Hello!

split_double_mode tries to split TImode address:

(insn 10 2 11 2 (set (reg/i:TI 0 ax)
        (mem/u/c:TI (const:DI (unspec:DI [
                        (symbol_ref:DI ("_ZZ7tempDirvE5cache") [flags 0x2a])
                    ] UNSPEC_NTPOFF)) [1 cache+0 S16 A64 AS1]))
to:

(const:DI (unspec:DI [
                (symbol_ref:DI ("_ZZ7tempDirvE5cache") [flags 0x2a])
            ] UNSPEC_NTPOFF))

and

(const:DI (plus:DI (unspec:DI [
                (symbol_ref:DI ("_ZZ7tempDirvE5cache") [flags 0x2a])
            ] UNSPEC_NTPOFF)
        (const_int 8 [0x8])))

but the later RTX is not recognized as a valid address.

Attached patch allows offsetted UNSPEC_DTPOFF/UNSPEC_NTPOFF
relocations in legitimate_pic_address_disp_p. In fact, these are
already allowed in x86_64_immediate_operand, with the immediate
limited to SImode values.

2017-10-29  Uros Bizjak  <ubiz...@gmail.com>

    PR target/82725
    * config/i386/i386.c (legitimate_pic_address_disp_p): Allow
    UNSPEC_DTPOFF and UNSPEC_NTPOFF with SImode immediate offset.

testsuite/ChangeLog:

2017-10-29  Uros Bizjak  <ubiz...@gmail.com>

    PR target/82725
    * g++.dg/pr82725.C: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Jakub, HJ, do you have any comments on the patch?

Uros.
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c  (revision 254199)
+++ config/i386/i386.c  (working copy)
@@ -15079,10 +15079,16 @@ legitimate_pic_address_disp_p (rtx disp)
            break;
          op0 = XEXP (XEXP (disp, 0), 0);
          op1 = XEXP (XEXP (disp, 0), 1);
-         if (!CONST_INT_P (op1)
-             || INTVAL (op1) >= 16*1024*1024
+         if (!CONST_INT_P (op1))
+           break;
+         if (GET_CODE (op0) == UNSPEC
+             && (XINT (op0, 1) == UNSPEC_DTPOFF
+                 || XINT (op0, 1) == UNSPEC_NTPOFF)
+             && trunc_int_for_mode (INTVAL (op1), SImode) == INTVAL (op1))
+           return true;
+         if (INTVAL (op1) >= 16*1024*1024
              || INTVAL (op1) < -16*1024*1024)
-            break;
+           break;
          if (GET_CODE (op0) == LABEL_REF)
            return true;
          if (GET_CODE (op0) == CONST
Index: testsuite/g++.dg/pr82725.C
===================================================================
--- testsuite/g++.dg/pr82725.C  (nonexistent)
+++ testsuite/g++.dg/pr82725.C  (working copy)
@@ -0,0 +1,16 @@
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target pie }
+// { dg-options "-O2 -fpie -mtls-direct-seg-refs" }
+
+struct string
+{
+  __SIZE_TYPE__ length;
+  const char *ptr;
+};
+
+string
+tempDir ()
+{
+  thread_local string cache;
+  return cache;
+}

Reply via email to