https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106594
--- Comment #15 from Roger Sayle <roger at nextmovesoftware dot com> --- An example of combine's temporary lapses of sanity can be seen on powerpc: Trying 14 -> 15: 14: %3:SI=sign_extend(r128:SI#2)*sign_extend(r127:SI#2) REG_DEAD r128:SI REG_DEAD r127:SI 15: use %3:SI Failed to match this instruction: (parallel [ (use (mult:SI (ashiftrt:SI (ashift:SI (reg:SI 128) (const_int 16 [0x10])) (const_int 16 [0x10])) (ashiftrt:SI (ashift:SI (reg:SI 127) (const_int 16 [0x10])) (const_int 16 [0x10])))) (set (reg/i:SI 3 3) (mult:SI (sign_extend:SI (subreg:HI (reg:SI 128) 2)) (sign_extend:SI (subreg:HI (reg:SI 127) 2)))) ]) with the proposed patch, we now see: Trying 14 -> 15: 14: %3:SI=sign_extend(r128:SI#2)*sign_extend(r127:SI#2) REG_DEAD r128:SI REG_DEAD r127:SI 15: use %3:SI Failed to match this instruction: (parallel [ (use (mult:SI (sign_extend:SI (subreg:HI (reg:SI 128) 2)) (sign_extend:SI (subreg:HI (reg:SI 127) 2)))) (set (reg/i:SI 3 3) (mult:SI (sign_extend:SI (subreg:HI (reg:SI 128) 2)) (sign_extend:SI (subreg:HI (reg:SI 127) 2)))) ]) i.e. the "canonical" form of the expression actually matches the RTL pattern used/expected by the rs6000 backend.