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

Reply via email to