http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52698

--- Comment #4 from Uros Bizjak <ubizjak at gmail dot com> 2012-03-25 19:00:10 
UTC ---
(In reply to comment #0)
> [hjl@gnu-mic-2 gcc]$ cat /tmp/x.c
> extern void abort (void);
> static __thread unsigned char foo [32]
>   __attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *))));
> void
> test2 (void)
> {
>   unsigned int s;
>   for (s = 0; s < sizeof (foo); ++s)
>     {
>       if (foo [s] != s)
>  abort ();
>       foo [s] = sizeof (foo) - s;
>     }
> }
> [hjl@gnu-mic-2 gcc]$ ./xgcc -B./ -mx32 -O2  -S /tmp/x.c  -maddress-mode=long
> /tmp/x.c: In function \u2018test2\u2019:
> /tmp/x.c:14:1: error: insn does not satisfy its constraints:
> (insn 52 78 53 5 (set (mem/j:QI (plus:DI (plus:DI (reg:DI 37 r8)
>                     (reg:DI 38 r9))
>                 (reg:DI 2 cx [orig:98 D.1709 ] [98])) [0 foo S1 A8])
>         (reg:QI 1 dx [100])) /tmp/x.c:12 66 {*movqi_internal}
>      (nil))
> /tmp/x.c:14:1: internal compiler error: in reload_cse_simplify_operands, at
> postreload.c:403
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <http://gcc.gnu.org/bugs.html> for instructions.
> [hjl@gnu-mic-2 gcc]$ ./xgcc -B./ -mx32 -O2  -S /tmp/x.c  -maddress-mode=short
> [hjl@gnu-mic-2 gcc]$

The problem is that reload generates invalid RTX address:

(plus:DI (plus:DI (zero_extend:DI (unspec:SI [
                    (const_int 0 [0])
                ] UNSPEC_TP))
        (reg:DI 97))
    (reg:DI 2 cx [orig:98 D.1709 ] [98]))

invalid in the sense, that we got pseudo in the strict mode. This is rejected
by ix86_legitimate_address_p, so reload uses bigger hammer and reloads all
components in registers:

Reloads for insn # 52
Reload 0: reload_in (DI) = (zero_extend:DI (unspec:SI [
                                                            (const_int 0 [0])
                                                        ] UNSPEC_TP))
        INDEX_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0)
        reload_in_reg: (zero_extend:DI (unspec:SI [
                                                            (const_int 0 [0])
                                                        ] UNSPEC_TP))
        reload_reg_rtx: (reg:DI 37 r8)
Reload 1: reload_in (DI) = (reg:DI 97)
        GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0)
        reload_in_reg: (reg:DI 97)
        reload_reg_rtx: (reg:DI 38 r9)

Unfortunately, this creates invalid address with three-register addressing.

BTW: -mx32 just uncovered this problem, it can happen also for plain x86_32 or
x86_64 where segment registers are involved.

Reply via email to