This is a patch for PR target/83466, an ILP32 aarch64 bug.  I verified
that it did not cause any regressions in the GCC testsuite and Andreas
verified that it fixed the original failure that he reported.  The
basic idea is to do the addition in ptr_mode (SImode in ILP32) instead
of Pmode (DImode in both LP64 and ILP32 modes).

OK to checkin?

Steve Ellcey
sell...@cavium.com


2018-01-04  Steve Ellcey  <sell...@cavium.com>

        PR target/83466
        * config/aarch64/aarch64.c (aarch64_load_symref_appropriately):
        Do address calculation in ptr_mode instead of Pmode.


diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index a189605..e60fd1c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1540,7 +1540,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
     case SYMBOL_SMALL_TLSDESC:
       {
        machine_mode mode = GET_MODE (dest);
-       rtx x0 = gen_rtx_REG (mode, R0_REGNUM);
+       rtx x0 = gen_rtx_REG (ptr_mode, R0_REGNUM);
        rtx tp;
 
        gcc_assert (mode == Pmode || mode == ptr_mode);
@@ -1553,10 +1553,13 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
          emit_insn (gen_tlsdesc_small_di (imm));
        tp = aarch64_load_tp (NULL);
 
-       if (mode != Pmode)
-         tp = gen_lowpart (mode, tp);
+       if (GET_MODE (tp) != ptr_mode)
+         tp = gen_lowpart (ptr_mode, tp);
+       tp = gen_rtx_PLUS (ptr_mode, tp, x0);
+       if (mode != ptr_mode)
+         tp = gen_rtx_ZERO_EXTEND (mode, tp);
+       emit_insn (gen_rtx_SET (dest, tp));
 
-       emit_insn (gen_rtx_SET (dest, gen_rtx_PLUS (mode, tp, x0)));
        if (REG_P (dest))
          set_unique_reg_note (get_last_insn (), REG_EQUIV, imm);
        return;

Reply via email to