https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69305
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The patterns are just weird. (insn 10 7 11 2 (parallel [ (set (reg:CC_NZ 66 cc) (compare:CC_NZ (plus:DI (reg:DI 79) (reg:DI 85 [ x ])) (const_int 0 [0]))) (set (reg:DI 81) (plus:DI (reg:DI 79) (reg:DI 85 [ x ]))) ]) pr69305-1.c:5 100 {adddi3_compare0} (expr_list:REG_DEAD (reg:DI 85 [ x ]) (expr_list:REG_DEAD (reg:DI 79) (nil)))) (insn 11 10 25 2 (set (reg:DI 82) (plus:DI (geu:DI (reg:CC 66 cc) (const_int 0 [0])) (reg:DI 86 [ x+8 ]))) pr69305-1.c:5 452 {*csinc2di_insn} (expr_list:REG_DEAD (reg:DI 86 [ x+8 ]) (expr_list:REG_DEAD (reg:CC 66 cc) (nil)))) This suggests that that you compare (a + b) cmp 0 and add 1 in the second insn if (a + b) u>= 0, which is always, while what you are actually interested in is whether (a + b) u< a (or equivalently (a + b) u< b), i.e. if there is an overflow in the addition. E.g. on x86_64 (though, only after split2) it is represented that way: (insn 33 13 34 2 (parallel [ (set (reg:CCC 17 flags) (compare:CCC (plus:DI (reg:DI 0 ax [97]) (reg:DI 38 r9 [orig:90 x ] [90])) (reg:DI 0 ax [97]))) (set (reg:DI 0 ax [95]) (plus:DI (reg:DI 0 ax [97]) (reg:DI 38 r9 [orig:90 x ] [90]))) ]) pr69305-1.c:5 306 {*adddi3_cc_overflow_1} (nil)) (insn 34 33 20 2 (parallel [ (set (reg:DI 1 dx [+8 ]) (plus:DI (plus:DI (ltu:DI (reg:CC 17 flags) (const_int 0 [0])) (reg:DI 1 dx [+8 ])) (reg:DI 39 r10 [ x+8 ]))) (clobber (reg:CC 17 flags)) ]) pr69305-1.c:5 284 {adddi3_carry} (nil))