summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorSergei Trofimovich <siarheit@google.com>2016-01-05 17:57:05 +0000
committerJeff Law <law@gcc.gnu.org>2016-01-05 10:57:05 -0700
commitface88a110a3c1970119ba5fea9679609242975c (patch)
treea68c987f368170593f89e4702fe5083696175be2 /gcc/config
parenta0866effcd38476b14e96b069ac697e08f5f5b79 (diff)
downloadgcc-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.c9
-rw-r--r--gcc/config/ia64/predicates.md26
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")