More i386 comparison fixes

Jakub Jelinek jakub@redhat.com
Thu Oct 19 06:44:00 GMT 2000


On Tue, Oct 17, 2000 at 10:03:52AM -0700, Richard Henderson wrote:
> On Tue, Oct 17, 2000 at 11:23:17AM +0200, Jan Hubicka wrote:
> > Not exactly - it reverses only carry, not overflow.
> 
> Right.

Wrong.

(compare (X) (neg (Y))

and

(plus (X) (Y))

reverse carry in most cases, there are exceptions though (if
either of X, Y or X+Y is equal to 0 or (1 << (bitsize-1))), likewise
overflow is usually the same with some exceptions in the above boundary
cases. Zero flag is always the same and sign flag for these two is the same
as well (but (compare (neg (X)) (Y)) has the sign flag mostly reverse of
SF for plus with exceptions).
So, IMHO the patch should go away (Jan agreed on it) and we need to find out
how to model adddi3 and other DImode ops on i386 then.
I proposed using the same thing as on SPARC, ie. split
(insn 12 11 14 (parallel[
            (set (reg:DI 44)
                (plus:DI (reg:DI 42)
                    (reg:DI 43)))
            (clobber (reg:CC 17 flags))
        ] ) -1 (nil)
    (nil))

into
(insn 30 15 31 (parallel[
            (set (reg:CCNO 17 flags)
                (compare:CCNO (plus:SI (reg:SI x)
                        (reg:SI y))
                    (const_int 0 [0x0])))
            (set (reg:SI x)
                (plus:SI (reg:SI x)
                    (reg:SI x)))
        ] ) -1 (nil)
    (nil))

(insn 31 30 21 (set (reg:SI a)
        (plus:SI (plus:SI (reg:SI a)
                (reg:SI b))
            (ltu:SI (reg:CCNO 17 flags)
                (const_int 0 [0x0])))) -1 (nil)
    (nil))

after combine.
Jan reaction to this was if ever somebody starts playing with condition
codes after reload, we could loose that (ltu (flags) (const_int 0)), but I
think doing so would break many ports unless e.g. simplify_rtx would be
tought to handle it specially.
I'm posting it here so that others can comment on how to deal with this.

	Jakub


More information about the Gcc-patches mailing list