Richard Henderson <richard.hender...@linaro.org> writes: > Duplicate all usub_*_carryinC, but use xzr for the output when we > only require the flags output. The signed versions use sign_extend > instead of zero_extend for combine's benefit. > > These will be used shortly for TImode comparisons. > > * config/aarch64/aarch64.md (<su>cmp<GPI>3_carryinC): New. > (*<su>cmp<GPI>3_carryinC_z1): New. > (*<su>cmp<GPI>3_carryinC_z2): New. > (*<su>cmp<GPI>3_carryinC): New. > --- > gcc/config/aarch64/aarch64.md | 50 +++++++++++++++++++++++++++++++++++ > 1 file changed, 50 insertions(+) > > diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md > index a996a5f1c39..9b1c3f797f9 100644 > --- a/gcc/config/aarch64/aarch64.md > +++ b/gcc/config/aarch64/aarch64.md > @@ -3440,6 +3440,18 @@ > "" > ) > > +(define_expand "<ANY_EXTEND:su>cmp<GPI:mode>3_carryinC" > + [(set (reg:CC CC_REGNUM) > + (compare:CC > + (ANY_EXTEND:<DWI> > + (match_operand:GPI 0 "register_operand")) > + (plus:<DWI> > + (ANY_EXTEND:<DWI> > + (match_operand:GPI 1 "register_operand")) > + (ltu:<DWI> (reg:CC CC_REGNUM) (const_int 0)))))] > + "" > +) > (define_insn "*usub<GPI:mode>3_carryinC_z1" > [(set (reg:CC CC_REGNUM) > (compare:CC > @@ -3457,6 +3469,19 @@ > [(set_attr "type" "adc_reg")] > ) > > +(define_insn "*<ANY_EXTEND:su>cmp<GPI:mode>3_carryinC_z1" > + [(set (reg:CC CC_REGNUM) > + (compare:CC > + (const_int 0) > + (plus:<DWI> > + (ANY_EXTEND:<DWI> > + (match_operand:GPI 0 "register_operand" "r")) > + (match_operand:<DWI> 1 "aarch64_borrow_operation" ""))))] > + "" > + "sbcs\\t<w>zr, <w>zr, %<w>0" > + [(set_attr "type" "adc_reg")] > +) > + > (define_insn "*usub<GPI:mode>3_carryinC_z2" > [(set (reg:CC CC_REGNUM) > (compare:CC > @@ -3472,6 +3497,17 @@ > [(set_attr "type" "adc_reg")] > ) > > +(define_insn "*<ANY_EXTEND:su>cmp<GPI:mode>3_carryinC_z2" > + [(set (reg:CC CC_REGNUM) > + (compare:CC > + (ANY_EXTEND:<DWI> > + (match_operand:GPI 0 "register_operand" "r")) > + (match_operand:<DWI> 1 "aarch64_borrow_operation" "")))] > + "" > + "sbcs\\t<w>zr, %<w>0, <w>zr" > + [(set_attr "type" "adc_reg")] > +) > + > (define_insn "*usub<GPI:mode>3_carryinC" > [(set (reg:CC CC_REGNUM) > (compare:CC > @@ -3490,6 +3526,20 @@ > [(set_attr "type" "adc_reg")] > ) > > +(define_insn "*<ANY_EXTEND:su>cmp<GPI:mode>3_carryinC" > + [(set (reg:CC CC_REGNUM) > + (compare:CC > + (ANY_EXTEND:<DWI> > + (match_operand:GPI 0 "register_operand" "r")) > + (plus:<DWI> > + (ANY_EXTEND:<DWI> > + (match_operand:GPI 1 "register_operand" "r")) > + (match_operand:<DWI> 2 "aarch64_borrow_operation" ""))))] > + "" > + "sbcs\\t<w>zr, %<w>0, %<w>1" > + [(set_attr "type" "adc_reg")] > +)
I guess this feeds into your reply to Segher's comment for 7/9, but I think: (compare:CC X Y) is always supposed to be the NZCV flags result of X - Y, as computed in the mode of X and Y. If so, it seems like the type of extension should matter. E.g. the N flag ought to be set for: (compare:CC (sign_extend 0xf...) (plus (sign_extend 0x7...) (ltu ...))) but ought to be clear for: (compare:CC (zero_extend 0xf...) (plus (zero_extend 0x7...) (ltu ...))) If so, I guess this is a bug in the existing code... Thanks, Richard