Re: Question about compare rtl

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

 



>>>> 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. 
>>
>> It cannot combine the sub with a cbranch if the result is used (maybe
>> because of DFG consideration?). but in my case, the cbranch is expanded
>> into a compare insn and a branch<condition> insn which enables combining
>> the sub and the compare.
> 
> To be clear, combine does not generate the input to a define_expand.  It
> only generates patterns that are matched by a define_insn.  So what you
> are describing would only work if you implement a conditional branch via
> a define_insn, and then use a define_split to split it up into the
> actual instructions.

What I mean is I do not have any define_insn that matches a cbranch, but
the cbranch named pattern is expanded during expand pass using a
define_expand into:
(set (reg:CC CC_REGNO) (compare:CC op0 op1))
(set (pc) (if_then_else (match_operator 1 "xxx"
  [(reg:CC CC_REGNO)(const_int 0)]) (label_ref ()) (pc)))

Then the first insn can be combined with such a sub pattern:
[(set (reg:CC CC_REGNO) (compare:CC op1 op2))
 (set op0 (minus (match_dup 1) (match_dup 2))]

And my question was about the correctness of the previous pattern
compared with the following when an overflow occurs (and the comparison
operator is lt).
[(set (reg:CC CC_REGNO) (compare:CC (minus (op1 op2)) (const_int 0)))
 (set op0 (minus (match_dup 1) (match_dup 2))]

You helped me (thanks!) come to the conclusion that both are valid, and
that the N xor V test is enough for the two, right?


>> It doesn't seems to be the best practice according to
>> http://gcc.gnu.org/wiki/general_backend_cleanup (I'm not sure why), but
>> it enables better optimizations and/or many less peephole to write...
> 
> Are you talking about CC0?  Don't use CC0 in a new port.  It requires a
> lot of special case code in the backend.  That code is rarely tested
> because very few ports still use CC0.

I was talking about points 1&2:

"1- use compare-and-branch insns before reload (without
operate-and-compare);
2- split to separate compare-and-branch after reload;
3- use peephole2 patterns instead of NOTICE_CC for operate-and-compare."

I split cbranch during expand, not after reload. I have no idea why this
is important (expect to reduce the number of insns during reload?).


> 
>>> The second one can not.
>>
>> I did not test, but perhaps it can in my case?
> 
> How?

From
[(set (reg:CC CC_REGNO) (compare:CC op1 op2))
(set op0 (minus (match_dup 1) (match_dup 2))]
(set (reg:CC CC_REGNO) (compare:CC op0 op1))
(set (pc) (if_then_else (match_operator 1 "xxx"
  [(reg:CC CC_REGNO)(const_int 0)]) (label_ref ()) (pc)))]

To
[(set (reg:CC CC_REGNO) (compare:CC op1 op2))
(set op0 (minus (match_dup 1) (match_dup 2))]
(set (pc) (if_then_else (match_operator 1 "xxx"
  [(reg:CC CC_REGNO)(const_int 0)]) (label_ref ()) (pc)))]


Thanks,
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