https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82725

Uroš Bizjak <ubizjak at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Target|i?86-*-*                    |x86_64-linux-gnu
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-10-28
                 CC|                            |hjl.tools at gmail dot com,
                   |                            |jakub at gcc dot gnu.org
            Summary|[8 Regression] [i386]       |[8 Regression] [x86_64]
                   |internal compiler error: in |internal compiler error: in
                   |change_address_1, at        |change_address_1, at
                   |emit-rtl.c:2162             |emit-rtl.c:2162
     Ever confirmed|0                           |1

--- Comment #3 from Uroš Bizjak <ubizjak at gmail dot com> ---
The testcase fails on x86_64 using following compile flags:

-O2 -fpie -mtls-direct-seg-refs

As mentioned in the Comment #2, 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])))

The later RTX is not recognized as a valid address.

There is a part of code in ix86_legitimate_address_p that tries to handle
similar situation:

        is_legitimate_pic:
          if (TARGET_64BIT && (index || base))
            {
              /* foo@dtpoff(%rX) is ok.  */
              if (GET_CODE (disp) != CONST
                  || GET_CODE (XEXP (disp, 0)) != PLUS
                  || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
                  || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
                  || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
                      && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF))
                /* Non-constant pic memory reference.  */
                return false;

but it doesn't apply when we have constant tp-relative address.

Enabling this part by removing "&& (index || base)"

returns correct address:

        movq    %fs:_ZZ7tempDirvE5cache@tpoff, %rax
        movq    %fs:8+_ZZ7tempDirvE5cache@tpoff, %rdx

Jakub, this code was added by you in:

 53812        rth       is_legitimate_pic:
 40708    hubicka         if (TARGET_64BIT && (index || base))
 40708    hubicka           {
 58383      jakub             /* foo@dtpoff(%rX) is ok.  */
 58383      jakub             if (GET_CODE (disp) != CONST
 58383      jakub                 || GET_CODE (XEXP (disp, 0)) != PLUS
 58383      jakub                 || GET_CODE (XEXP (XEXP (disp, 0), 0)) !=
UNSPEC
121079       uros                 || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
 58383      jakub                 || (XINT (XEXP (XEXP (disp, 0), 0), 1) !=
UNSPEC_DTPOFF
 58383      jakub                     && XINT (XEXP (XEXP (disp, 0), 0), 1) !=
UNSPEC_NTPOFF))
151854       uros               /* Non-constant pic memory reference.  */
151854       uros               return false;

Do you perhaps remember, why the above addresses should be rejected?

Reply via email to