]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ia64: don't use dynamic relocations for local symbols
authorSergei Trofimovich <siarheit@google.com>
Tue, 19 Jan 2016 23:15:12 +0000 (23:15 +0000)
committerMike Frysinger <vapier@gcc.gnu.org>
Tue, 19 Jan 2016 23:15:12 +0000 (23:15 +0000)
Backported from trunk for PR other/60465.

From-SVN: r232595

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 4d76bbc99435fa2c06e231ec30c27c120b374c68..f540110267c2cb71e762f8baaee8b78a45545f4e 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-19  Sergei Trofimovich <siarheit@google.com>
+
+       Backport from mainline
+       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-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        Backport from mainline:
index 229a0f386b4cb0f04f78307338185bab153f9fa0..82d9644569e897c7593c0853d58529b02d8c8a12 100644 (file)
@@ -1100,6 +1100,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 989c550e7a723743216a12f2500f17a28dd54f33..6bd5d0cac98961e70740722cdad511b6bfc68e91 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 940e485fcc9cddd4280373300ec07684f9a92670..a41384ced61d66ea9cb36e2492dc2c2ea4b9f3c8 100644 (file)
@@ -1,3 +1,10 @@
+2016-01-19  Sergei Trofimovich <siarheit@google.com>
+
+       Backport from mainline
+       PR other/60465
+       * gcc.target/ia64/pr60465-gprel64.c: New test.
+       * gcc.target/ia64/pr60465-gprel64-c37.c: New test.
+
 2016-01-19  Uros Bizjak  <ubizjak@gmail.com>
 
        PR testsuite/68820
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);
+}