From: Sergei Trofimovich <[email protected]>
Tested on the following example:
void * a[77] __attribute((visibility("hidden")));
void f(long o, void * v) { a[0x6ffffeff - o + 66] = v; }
Before the patch generated code uses .GOT entry:
addl r14 = @ltoffx(a#), r1
ld8.mov r14 = [r14], a#
After the patch generated code uses static gprel relocation:
movl r14 = @gprel(a#)
add r14 = r1, r14
That way gcc will be able to compile glibc's ld: PR/60465
Bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60465
Signed-off-by: Sergei Trofimovich <[email protected]>
---
gcc/config/ia64/ia64.c | 2 ++
gcc/config/ia64/predicates.md | 26 ++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index f48cebc..6ea5072 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -1105,6 +1105,8 @@ 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))
+ 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 2aa7a78..9c6951d 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 large 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")
--
2.6.4