]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH v2] ia64: don't use dynamic relocations for local symbols PR other/60465
authorSergei Trofimovich <siarheit@google.com>
Tue, 5 Jan 2016 17:57:05 +0000 (17:57 +0000)
committerJeff Law <law@gcc.gnu.org>
Tue, 5 Jan 2016 17:57:05 +0000 (10:57 -0700)
[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

gcc/ChangeLog
gcc/config/ia64/ia64.c
gcc/config/ia64/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c [new file with mode: 0644]
gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c [new file with mode: 0644]

index 98d6fefe93d2d434e80a3308015568dc73f833f2..d54d604efced5e9fcf0f121e4c9ec94af1288fdf 100644 (file)
@@ -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
index e0059f8b30630ef7a1b615866719a6ca4f3bac16..33ec7a74beec3f630af23326cabe6efb6f7692a4 100644 (file)
@@ -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;
index ddc31b125d1e99d84460a3bfe2d4620e3e8963cb..02347f7823c68930420c07e639fd3a78ad2939bb 100644 (file)
     }
 })
 
+;; 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")
index 4ab864ef371f7b73b7d08eed2b07b261a8c25ead..2075964cab1513b08a72df5a29ea50a0e62cf393 100644 (file)
@@ -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 (file)
index 0000000..a7e6809
--- /dev/null
@@ -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 (file)
index 0000000..c00ecc9
--- /dev/null
@@ -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);
+}