[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
This commit is contained in:
Sergei Trofimovich 2016-01-05 17:57:05 +00:00 committed by Jeff Law
parent a0866effcd
commit face88a110
6 changed files with 86 additions and 0 deletions

View File

@ -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

View File

@ -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;

View File

@ -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")

View File

@ -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

View File

@ -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; }

View File

@ -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);
}