Re: Question about compare rtl

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Aurelien Buhrig <aurelien.buhrig.gcc@xxxxxxxxx> writes:

> Lets consider the lt comparison.
> My target has V and N hardware flags which are respectively set when an
> overflow occurs and when the result is negative.
> It can branch when N xor V == 1, but can also branch when N == 1. The
> difference is that the first test really compares (lt r0 r1) (taking
> into account the overflow) whereas the latter compares the "truncated"
> result of the sub with 0, which are different when an overflow occurs.
> So, from the hardware point of view, one comparison, two different lt
> meanings...
>
> So the question is more about the RTL difference there would be between
> (set (pc) (if_then_else (lt (sub r0 r1) (const_int 0)) (label_ref) (pc)))
> and
> (set (pc) (if_then_else (lt r0 r1) (label_ref) (pc)))
> and the ability / correctness to merge both insn (if different) with a
> (sub r0 r1) (in combine or cse pass).

The first one (lt (sub r0 r1) (const_int 0)) can be combined with a sub
insn, if the result of the sub insn is not used.  The second one can
not.

> And the main question is: can the N==1 test be useful for the backend?
> For instance, in C, I think an overflow has undefined behavior, so
> testing for an overflowed result seems meaningless.

Signed overflow is undefined, but unsigned overflow wraps.  So it is
possible to write valid code that could use an overflow flag using
unsigned types.  But it's uncommon.

> If it is useless, perhaps I should change the hardware behavior (yes, I
> can) so that to replace the branch negative to something more useful
> such as a branch GT. For now, a cbranch GT is implemented by changing
> the comparison operands and emitting a cbranch GE or LT, but it is not
> possible to combine a sub with (gt result 0) cbranch. So perhaps I could
> save some comparison insns.

I think that from the compiler's perspective the most useful sorts of
conditional branches are the ones that say "if Rn COND Rm then jump",
where COND is any of EQ, NE, LE, LT, GT, GE, ULE, ULT, UGT, UGE (of
course symmetry lets you drop GT, GE, UGT, UGE for integers, and of
course you don't need the U variants for floating point).  Anything
involving condition flags is harder to generate code for, although I
understand that it permits additional pipelining in the processor.  If
the processor has to have condition flags then I suspect that the best
results will come from instructions that store the results of the
condition in a general register, and conditional branches that can test
any general register against zero.

Ian


[Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

Add to Google