diff options
author | Sergei Trofimovich <siarheit@google.com> | 2016-01-05 17:57:05 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2016-01-05 10:57:05 -0700 |
commit | face88a110a3c1970119ba5fea9679609242975c (patch) | |
tree | a68c987f368170593f89e4702fe5083696175be2 | |
parent | a0866effcd38476b14e96b069ac697e08f5f5b79 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 9 | ||||
-rw-r--r-- | gcc/config/ia64/predicates.md | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c | 27 |
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); +} |