From face88a110a3c1970119ba5fea9679609242975c Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Tue, 5 Jan 2016 17:57:05 +0000 Subject: [PATCH] [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 --- gcc/ChangeLog | 8 +++++++ gcc/config/ia64/ia64.c | 9 ++++++++ gcc/config/ia64/predicates.md | 26 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 6 +++++ .../gcc.target/ia64/pr60465-gprel64-c37.c | 10 ++++++++ gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c | 27 ++++++++++++++++++++++ 6 files changed, 86 insertions(+) create mode 100644 gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c create mode 100644 gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c 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 + + 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 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 + + 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 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); +} -- 2.7.4