https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83304
--- Comment #6 from ktkachov at gcc dot gnu.org --- So I'm digging through the combine dumps... Before the r255384 we have: Trying 70 -> 19: 70: r131:SI={(cc:CC!=0)?r130:SI:0xffffffffffffffff} REG_DEAD r130:SI 19: {r134:SI=r131:SI!=0xffffffffffffffff;clobber cc:CC;} REG_UNUSED cc:CC REG_DEAD r131:SI Can't combine i2 into i3. But after we succeed: Trying 70 -> 19: 70: r131:SI={(cc:CC!=0)?r130:SI:0xffffffffffffffff} REG_DEAD r130:SI 19: {r134:SI=r131:SI!=0xffffffffffffffff;clobber cc:CC;} REG_UNUSED cc:CC REG_DEAD r131:SI Failed to match this instruction: (parallel [ (set (reg:SI 134) (ne:SI (reg:CC 100 cc) (const_int 0 [0]))) (clobber (reg:CC 100 cc)) ]) Successfully matched this instruction: (set (reg:SI 134) (ne:SI (reg:CC 100 cc) (const_int 0 [0]))) (ne:SI (reg:CC 100 cc) (const_int 0 [0])) Hot cost: 12 (final) allowing combination of insns 70 and 19 original costs 4 + 16 = 20 replacement cost 12 deferring deletion of insn with uid = 70. deferring deletion of insn with uid = 9. modifying insn i3 19: r134:SI=cc:CC!=0 REG_DEAD cc:CC deferring rescan insn with uid = 19. I think the transformation is *almost valid*, but it lost the "clobber cc" that was in parallel with insn 19. Note that this happens after propagating some comparisons into their uses. For example, this form of insn 19 is after munging together 14, 18 and 19: (insn 14 70 16 3 (set (reg/v:SI 132 [ a ]) (plus:SI (reg:SI 131) (const_int 1 [0x1]))) "bad.c":9 4 {*arm_addsi3} (expr_list:REG_DEAD (reg:SI 131) (nil))) (insn 18 16 19 3 (set (reg:CC 100 cc) (compare:CC (reg/v:SI 132 [ a ]) (const_int 0 [0]))) "bad.c":10 193 {*arm_cmpsi_insn} (expr_list:REG_DEAD (reg/v:SI 132 [ a ]) (nil))) (insn 19 18 21 3 (set (reg:SI 134) (ne:SI (reg:CC 100 cc) (const_int 0 [0]))) "bad.c":10 879 {*thumb2_mov_scc} (expr_list:REG_DEAD (reg:CC 100 cc) (nil))) Hope this helps