https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101885
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Seems it goes wrong during combine, before combine we have: (insn 17 16 131 2 (parallel [ (set (reg:QI 124 [ _199 ]) (and:QI (reg:QI 143) (reg:QI 145))) (clobber (reg:CC 17 flags)) ]) "pr101885.c":17:5 534 {*andqi_1} (expr_list:REG_DEAD (reg:QI 145) (expr_list:REG_DEAD (reg:QI 143) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))))) (insn 131 17 130 2 (set (reg:QI 152) (const_int 0 [0])) "pr101885.c":17:5 83 {*movqi_internal} (nil)) (insn 130 131 132 2 (set (reg:CCZ 17 flags) (compare:CCZ (reg:QI 124 [ _199 ]) (const_int 0 [0]))) "pr101885.c":17:5 5 {*cmpqi_ccno_1} (nil)) (insn 132 130 134 2 (set (reg:QI 82 [ b_lsm_flag.26 ]) (if_then_else:QI (ne (reg:CCZ 17 flags) (const_int 0 [0])) (reg:QI 124 [ _199 ]) (reg:QI 152))) "pr101885.c":17:5 1204 {*movqicc_noc} (expr_list:REG_DEAD (reg:QI 152) (expr_list:REG_DEAD (reg:QI 124 [ _199 ]) (expr_list:REG_EQUAL (if_then_else:QI (ne (reg:CCZ 17 flags) (const_int 0 [0])) (reg:QI 124 [ _199 ]) (const_int 0 [0])) (nil))))) (insn 134 132 135 2 (set (reg:SI 153) (const_int 0 [0])) "pr101885.c":17:5 81 {*movsi_internal} (nil)) (insn 135 134 137 2 (set (reg:SI 90 [ a_lsm.27 ]) (if_then_else:SI (eq (reg:CCZ 17 flags) (const_int 0 [0])) (reg:SI 90 [ a_lsm.27 ]) (reg:SI 153))) "pr101885.c":17:5 1201 {*movsicc_noc} (expr_list:REG_EQUAL (if_then_else:SI (eq (reg:CCZ 17 flags) (const_int 0 [0])) (reg:SI 90 [ a_lsm.27 ]) (const_int 0 [0])) (nil))) and that is in RTL what the optimized dump had: _33 = _31 & _32; if (_33 != 0) goto <bb 7>; [13.50%] else goto <bb 6>; [86.50%] <bb 6> [local count: 12627325]: <bb 7> [local count: 14598063]: # b_lsm_flag.26_11 = PHI <_33(5), b_lsm_flag.26_202(6)> # a_lsm.27_45 = PHI <0(5), a_lsm.27_203(6)> i.e. both the conditional moves consume flags reg set from comparison of x & y result against 0. But combine makes: (note 17 16 131 2 NOTE_INSN_DELETED) (note 131 17 130 2 NOTE_INSN_DELETED) (insn 130 131 132 2 (set (reg:CCZ 17 flags) (compare:CCZ (and:QI (reg:QI 143) (reg:QI 145)) (const_int 0 [0]))) "pr101885.c":17:5 515 {*testqi_1_maybe_si} (nil)) (insn 132 130 134 2 (parallel [ (set (reg:QI 82 [ b_lsm_flag.26 ]) (and:QI (reg:QI 143) (reg:QI 145))) (clobber (reg:CC 17 flags)) ]) "pr101885.c":17:5 534 {*andqi_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_DEAD (reg:QI 145) (expr_list:REG_DEAD (reg:QI 143) (nil))))) out of this (followed by the conditional moves). That means it sets flags and then immediately clobbers them by another and. Ideally we want *andqi_2_maybe_si insn for both that (set (reg 17) (compare (and:QI (match_operand:QI 1 ("nonimmediate_operand") ("%0,0,0")) (match_operand:QI 2 ("general_operand") ("qn,m,n"))) (const_int 0 [0]))) (set (match_operand:QI 0 ("nonimmediate_operand") ("=qm,q,r")) (and:QI (match_dup 1) (match_dup 2))) but if that isn't used, at least the flag setting should be after 132 and not before it...