From: Sergei Trofimovich <siarh...@google.com> 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 <siarh...@google.com> --- 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