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

Reply via email to