https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77729
Segher Boessenkool <segher at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |segher at gcc dot gnu.org --- Comment #11 from Segher Boessenkool <segher at gcc dot gnu.org> --- > Basically combine is going funny. Hey, don't blame combine, it's all simplify-rtx's doing. If in simplify_binary_operation_1 you disable the blocks after /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2. */ and after /* If we have (ior (and (X C1) C2)), simplify this by making C1 as small as possible if C1 actually changes. */ all works as you want (this is on rs6000, pretty much the same thing): === Trying 10, 11 -> 12: Failed to match this instruction: (set (reg:SI 131) (ior:SI (zero_extend:SI (mem:QI (reg/v/f:DI 128 [ string ]) [0 *string_9(D)+0 S1 A8])) (const_int 96 [0x60]))) Successfully matched this instruction: (set (reg:SI 130) (zero_extend:SI (mem:QI (reg/v/f:DI 128 [ string ]) [0 *string_9(D)+0 S1 A8]))) Successfully matched this instruction: (set (reg:SI 131) (ior:SI (reg:SI 130) (const_int 96 [0x60]))) allowing combination of insns 10, 11 and 12 original costs 8 + 4 + 4 = 16 replacement costs 8 + 4 = 12 deferring deletion of insn with uid = 10. modifying insn i2 11: r130:SI=zero_extend([r128:DI]) deferring rescan insn with uid = 11. modifying insn i3 12: r131:SI=r130:SI|0x60 REG_DEAD r130:SI deferring rescan insn with uid = 12. === giving lbz 9,0(3) ori 9,9,0x60 cmpwi 7,9,116 bne 7,.L5 etc.