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.