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 /gcc/config | |
parent | a0866effcd38476b14e96b069ac697e08f5f5b79 (diff) | |
download | gcc-face88a110a3c1970119ba5fea9679609242975c.tar.gz |
[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
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/ia64/ia64.c | 9 | ||||
-rw-r--r-- | gcc/config/ia64/predicates.md | 26 |
2 files changed, 35 insertions, 0 deletions
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index e0059f8b306..33ec7a74bee 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 ddc31b125d1..02347f7823c 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") |