https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87763
--- Comment #21 from Steve Ellcey <sje at gcc dot gnu.org> --- If I look at this specific example: int f2 (int x, int y) { return (x & ~0x0ff000) | ((y & 0x0ff) << 12); } Before the combine change, I see in x.c.260r.combine: Trying 8, 9 -> 15: 8: r98:SI=x1:SI<<0xc&0xff000 REG_DEAD x1:SI 9: r99:SI=x0:SI&0xfffffffffff00fff REG_DEAD x0:SI 15: x0:SI=r98:SI|r99:SI REG_DEAD r98:SI REG_DEAD r99:SI Successfully matched this instruction: (set (zero_extract:SI (reg/i:SI 0 x0) (const_int 8 [0x8]) (const_int 12 [0xc])) (zero_extend:SI (reg:QI 1 x1 [ y ]))) allowing combination of insns 8, 9 and 15 original costs 4 + 4 + 4 = 12 replacement cost 4 deferring deletion of insn with uid = 9. Immediately after the combine change, I get: Trying 8, 9 -> 15: 8: r98:SI=r101:SI<<0xc&0xff000 REG_DEAD r101:SI 9: r99:SI=r100:SI&0xfffffffffff00fff REG_DEAD r100:SI 15: x0:SI=r98:SI|r99:SI REG_DEAD r98:SI REG_DEAD r99:SI Failed to match this instruction: (set (reg/i:SI 0 x0) (ior:SI (and:SI (reg:SI 100) (const_int -1044481 [0xfffffffffff00fff])) (and:SI (ashift:SI (reg:SI 101) (const_int 12 [0xc])) (const_int 1044480 [0xff000])))) Successfully matched this instruction: (set (reg:SI 99) (ashift:SI (reg:SI 101) (const_int 12 [0xc]))) Failed to match this instruction: (set (reg/i:SI 0 x0) (ior:SI (and:SI (reg:SI 100) (const_int -1044481 [0xfffffffffff00fff])) (and:SI (reg:SI 99) (const_int 1044480 [0xff000])))) Is this because of x0 (a hard register) at the destination in insn 15?