https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119071
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- cse1 optimizes insn optimizes insn 15 away in: (insn 10 9 11 2 (parallel [ (set (reg:SI 84 [ _3 ]) (plus:SI (reg:SI 96) (reg:SI 92 [ _18 ]))) (clobber (reg:CC 17 flags)) ]) 185 {*addsi_1} (nil)) (insn 11 10 12 2 (set (reg:CCZ 17 flags) (compare:CCZ (reg:SI 84 [ _3 ]) (const_int 1 [0x1]))) 11 {*cmpsi_1} (nil)) (insn 12 11 13 2 (set (reg:QI 98) (ne:QI (reg:CCZ 17 flags) (const_int 0 [0]))) 732 {*setcc_qi} (nil)) (insn 13 12 14 2 (set (reg:SI 97) (zero_extend:SI (reg:QI 98))) 119 {*zero_extendqisi2} (nil)) (insn 14 13 15 2 (set (reg:SI 89 [ _15 ]) (reg:SI 97)) 67 {*movsi_internal} (nil)) (insn 15 14 16 2 (set (reg:CCZ 17 flags) (compare:CCZ (reg:SI 84 [ _3 ]) (const_int 1 [0x1]))) 11 {*cmpsi_1} (nil)) (insn 16 15 17 2 (set (reg:QI 100) (eq:QI (reg:CCZ 17 flags) (const_int 0 [0]))) 732 {*setcc_qi} (nil)) which looks reasonable, nothing clobbers flags in between and insn 11 sets it to the same value. I think things go wrong during combine. Before that revision we have (insn 5 2 6 2 (set (reg:CCZ 17 flags) (compare:CCZ (mem/c:SI (symbol_ref:DI ("a") [flags 0x2] <var_decl 0x7fc3d8edfb40 a>) [1 a+0 S4 A32]) (const_int -2 [0xfffffffffffffffe]))) 11 {*cmpsi_1} (nil)) ... (insn 18 17 19 2 (set (reg:SI 97) (eq:SI (reg:CCZ 17 flags) (const_int 0 [0]))) 731 {*setcc_si_1_movzbl} (expr_list:REG_DEAD (reg:CC 17 flags) (nil))) (insn 19 18 20 2 (set (reg:SI 102) (ne:SI (reg:CCZ 17 flags) (const_int 0 [0]))) 731 {*setcc_si_1_movzbl} (expr_list:REG_DEAD (reg:CC 17 flags) (nil))) (insn 20 19 21 2 (parallel [ (set (reg:SI 93 [ <retval> ]) (minus:SI (reg:SI 102) (reg:SI 97))) (clobber (reg:CC 17 flags)) ]) 254 {*subsi_1} (expr_list:REG_DEAD (reg:SI 102) (expr_list:REG_DEAD (reg:SI 97) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))))) (insn 21 20 25 2 (set (mem/c:SI (symbol_ref:DI ("b") [flags 0x2] <var_decl 0x7fc3d8edfbd0 b>) [1 b+0 S4 A32]) (reg:SI 93 [ <retval> ])) 67 {*movsi_internal} (nil)) which feels reasonable. The testcase has UB when a == -2 (left shift by -1) and otherwise sets b to 1. But starting with r10-7268 combiner combines this into (insn 5 2 6 2 (set (reg:CCZ 17 flags) (compare:CCZ (mem/c:SI (symbol_ref:DI ("a") [flags 0x2] <var_decl 0x7f2bc69b4b40 a>) [1 a+0 S4 A32]) (const_int -2 [0xfffffffffffffffe]))) 11 {*cmpsi_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) ... (insn 20 19 21 2 (set (reg:SI 93 [ <retval> ]) (const_int 0 [0])) 67 {*movsi_internal} (nil)) (insn 21 20 25 2 (set (mem/c:SI (symbol_ref:DI ("b") [flags 0x2] <var_decl 0x7f2bc69b4bd0 b>) [1 b+0 S4 A32]) (reg:SI 93 [ <retval> ])) 67 {*movsi_internal} (nil)) which is wrong for the non-UB case of a not being -2.