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