Re: Question about compare rtl

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

 



21/06/2012 02:05, Ian Lance Taylor:
> Aurelien Buhrig <aurelien.buhrig.gcc@xxxxxxxxx> writes:
> 
>> I have a question about combining compare with arithmetic operations.
>> The doc says about (compare:m x y):
>>
>> "Represents the result of subtracting y from x for purposes of
>> comparison. The result is computed without overflow, as if with infinite
>> precision.
>> Of course, machines can’t really subtract with infinite precision.
>> However, they can pretend to do so when only the sign of the result will
>> be used, which is the case when the result is stored in the condition
>> code. And that is the only way this kind of expression may validly be
>> used: as a value to be stored in the condition codes, either (cc0) or a
>> register."
>>
>> So is it valid to combine a subm pattern (which sets the flags as a
>> compare does) and a cbranchm with a signed comparison operator?
>>
>> If it is, what is the expected behavior when an overflow occurs?
>> Should we branch if (compare x y) is true, or if (compare result 0) is true?
> 
> I'm finding it hard to answer this question in the abstract.  Can you
> show us the RTL?
> 
> Perhaps you are asking whether you may generate
> 
> (set (pc) (if_then_else (sub r0 r1) (label_ref) (pc)))
> 
> That is not valid RTL; the first operand of if_then_else must be a
> comparison operation.  This would be valid:
> 
> (set (pc) (if_then_else (eq (sub r0 r1) (const_int 0)) (label_ref) (pc)))
> 
> And I think that answers your question about overflow.
> 
> Ian
> 

Sorry, it was not very clear.

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

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.

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.


Cheers,
Aurélien




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

  Powered by Linux