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

--- Comment #3 from Roger Sayle <roger at nextmovesoftware dot com> ---
This patch addresses the regression, but probably isn't the correct fix.

The issue is that the backend now has a way of representing the concatenation
of two registers (for example, TI is constructed for two DI mode registers):

(set (reg:TI 111 [ bD.2764 ])
    (ior:TI (ashift:TI (zero_extend:TI (reg:DI 142))
            (const_int 64 [0x40]))
        (zero_extend:TI (reg:DI 141))))

But combine is unable to cleanly extract the (original) DI mode components back
out of this using SUBREGs.  Currently combine gets confused and attempts to
match things like:

Trying 10 -> 74:
   10: r111:TI=zero_extend(r142:DI)<<0x40|zero_extend(r141:DI)
      REG_DEAD r141:DI
      REG_DEAD r142:DI
   74: r137:DI=r111:TI#0
Failed to match this instruction:
(parallel [
        (set (reg:DI 137 [ bD.2764 ])
            (reg:DI 141))
        (set (reg:TI 111 [ bD.2764 ])
            (ior:TI (ashift:TI (zero_extend:TI (reg:DI 142))
                    (const_int 64 [0x40]))
                (zero_extend:TI (reg:DI 141))))
    ])

which contains the simplification we want, "reg:DI 137 := reg:DI 141", but
along with stuff that combine should really take care off (strip/duplicate). 
I'll work on a more acceptable middle-end fix, but this patch demonstrates
progress, and can be used if a more general solution can't be found.

Reply via email to