https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111267
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Roger Sayle from comment #3) > This patch addresses the regression, but probably isn't the correct fix. Why? To me it looks like 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). How it could do anything else? It simplifies the computation of r137, but because r111 isn't dead but used later, it has to preserve the previous computation. And, combine only considers the 2-4 instructions being simplified together, so doesn't know that the other use only extracts the highpart subreg and can be therefore also simplified. Combine simply never tries to simplify folding say 10 -> 74 + 75. Does your patch help with the testcase?