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