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))