aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Trofimovich <siarheit@google.com>2016-01-05 17:57:05 +0000
committerJeff Law <law@gcc.gnu.org>2016-01-05 10:57:05 -0700
commitface88a110a3c1970119ba5fea9679609242975c (patch)
treea68c987f368170593f89e4702fe5083696175be2
parenta0866effcd38476b14e96b069ac697e08f5f5b79 (diff)
downloadgcc-face88a110a3c1970119ba5fea9679609242975c.zip
gcc-face88a110a3c1970119ba5fea9679609242975c.tar.gz
gcc-face88a110a3c1970119ba5fea9679609242975c.tar.bz2
[PATCH v2] ia64: don't use dynamic relocations for local symbols PR other/60465
[PATCH v2] ia64: don't use dynamic relocations for local symbols PR other/60465 * config/ia64/ia64.c (ia64_expand_load_address): Use gprel64 for local symbolic operands. * config/ia64/predicates.md (local_symbolic_operand64): New predicate. PR other/60465 * gcc.target/ia64/pr60465-gprel64.c: New test. * gcc.target/ia64/pr60465-gprel64-c37.c: New test. From-SVN: r232080
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/ia64/ia64.c9
-rw-r--r--gcc/config/ia64/predicates.md26
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c10
-rw-r--r--gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c27
6 files changed, 86 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 98d6fefe..d54d604 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2016-01-05 Sergei Trofimovich <siarheit@google.com>
+
+ PR other/60465
+ * config/ia64/ia64.c (ia64_expand_load_address): Use gprel64
+ for local symbolic operands.
+ * config/ia64/predicates.md (local_symbolic_operand64): New
+ predicate.
+
2016-01-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/68651
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index e0059f8..33ec7a7 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -1105,6 +1105,15 @@ ia64_expand_load_address (rtx dest, rtx src)
emit_insn (gen_load_fptr (dest, src));
else if (sdata_symbolic_operand (src, VOIDmode))
emit_insn (gen_load_gprel (dest, src));
+ else if (local_symbolic_operand64 (src, VOIDmode))
+ {
+ /* We want to use @gprel rather than @ltoff relocations for local
+ symbols:
+ - @gprel does not require dynamic linker
+ - and does not use .sdata section
+ https://gcc.gnu.org/bugzilla/60465 */
+ emit_insn (gen_load_gprel64 (dest, src));
+ }
else
{
HOST_WIDE_INT addend = 0;
diff --git a/gcc/config/ia64/predicates.md b/gcc/config/ia64/predicates.md
index ddc31b1..02347f7 100644
--- a/gcc/config/ia64/predicates.md
+++ b/gcc/config/ia64/predicates.md
@@ -97,6 +97,32 @@
}
})
+;; True if OP refers to a local symbol [+any offset].
+;; To be encoded as:
+;; movl % = @gprel(symbol+offset)
+;; add % = %, gp
+(define_predicate "local_symbolic_operand64"
+ (match_code "symbol_ref,const")
+{
+ switch (GET_CODE (op))
+ {
+ case CONST:
+ op = XEXP (op, 0);
+ if (GET_CODE (op) != PLUS
+ || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
+ || GET_CODE (XEXP (op, 1)) != CONST_INT)
+ return false;
+ op = XEXP (op, 0);
+ /* FALLTHRU */
+
+ case SYMBOL_REF:
+ return SYMBOL_REF_LOCAL_P (op);
+
+ default:
+ gcc_unreachable ();
+ }
+})
+
;; True if OP refers to a symbol in the small address area.
(define_predicate "small_addr_symbolic_operand"
(match_code "symbol_ref,const")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4ab864e..2075964 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-01-05 Sergei Trofimovich <siarheit@google.com>
+
+ PR other/60465
+ * gcc.target/ia64/pr60465-gprel64.c: New test.
+ * gcc.target/ia64/pr60465-gprel64-c37.c: New test.
+
2016-01-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/68651
diff --git a/gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c b/gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c
new file mode 100644
index 0000000..a7e6809
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target ia64-*-* } } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-final { scan-assembler-not "@ltoffx" } } */
+
+/* A bit of https://bugzilla.redhat.com/show_bug.cgi?id=33354
+ where many stores to static variables overflow .sdata */
+
+static const char *s90;
+void f() { s90 = "string 90"; }
+const char * g() { return s90; }
diff --git a/gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c b/gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c
new file mode 100644
index 0000000..c00ecc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target ia64-*-* } } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-final { scan-assembler-not "@ltoffx" } } */
+
+/* Test imitates early ld.so setup in glibc
+ where no dynamic relocations must be present. */
+
+struct rtld_global
+{
+ long *p[77];
+};
+
+struct rtld_global _rtld_local __attribute__ ((visibility ("hidden"), section (".sdata")));
+
+static void __attribute__ ((unused, noinline))
+elf_get_dynamic_info (struct rtld_global * g, long * dyn)
+{
+ long **info = g->p;
+
+ info[(0x6ffffeff - *dyn) + 66] = dyn;
+}
+
+void __attribute__ ((unused, noinline))
+_dl_start (long * dyn)
+{
+ elf_get_dynamic_info(&_rtld_local, dyn);
+}