Hi,

Indu Bhagat <indu.bha...@oracle.com> writes:
> subg (Subtract with Tag) is an Armv8.5-A memory tagging (MTE)
> instruction.  It can be used to subtract an immediate value scaled by
> the tag granule from the address in the source register.
>
> gcc/ChangeLog:
>
>       * config/aarch64/aarch64.md (subg): New definition.

In my previous comment about this patch:

  https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668669.html

I hadn't realised that the pattern follows the existing "addg" pattern.
But...

> ---
>  gcc/config/aarch64/aarch64.md | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 031e621c98a1..0c7aebb838cd 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -8416,6 +8416,23 @@
>    [(set_attr "type" "memtag")]
>  )
>  
> +(define_insn "subg"
> +  [(set (match_operand:DI 0 "register_operand" "=rk")
> +     (ior:DI
> +      (and:DI (minus:DI (match_operand:DI 1 "register_operand" "rk")
> +                       (match_operand:DI 2 "aarch64_granule16_uimm6" "i"))
> +              (const_int -1080863910568919041)) ;; 0xf0ff...
> +      (ashift:DI
> +       (unspec:QI
> +        [(and:QI (lshiftrt:DI (match_dup 1) (const_int 56)) (const_int 15))
> +         (match_operand:QI 3 "aarch64_memtag_tag_offset" "i")]
> +        UNSPEC_GEN_TAG)
> +       (const_int 56))))]
> +  "TARGET_MEMTAG"
> +  "subg\\t%0, %1, #%2, #%3"
> +  [(set_attr "type" "memtag")]
> +)
> +
>  (define_insn "subp"
>    [(set (match_operand:DI 0 "register_operand" "=r")
>       (minus:DI

...subtractions of constants are canonically expressed using (plus ...)
of a negative number, rather than (minus ...) of a positive number.
So I think we should instead add subg to the existing addg pattern.
That is, in:

(define_insn "addg"
  [(set (match_operand:DI 0 "register_operand" "=rk")
        (ior:DI
         (and:DI (plus:DI (match_operand:DI 1 "register_operand" "rk")
                          (match_operand:DI 2 "aarch64_granule16_uimm6" "i"))
                 (const_int -1080863910568919041)) ;; 0xf0ff...
         (ashift:DI
          (unspec:QI
           [(and:QI (lshiftrt:DI (match_dup 1) (const_int 56)) (const_int 15))
            (match_operand:QI 3 "aarch64_memtag_tag_offset" "i")]
           UNSPEC_GEN_TAG)
          (const_int 56))))]
  "TARGET_MEMTAG"
  "addg\\t%0, %1, #%2, #%3"
  [(set_attr "type" "memtag")]
)

the aarch64_granule16_uimm6 would be replaced with a predicate that
accepts all multiples of 16 in the range [-1008, 1008].  Then the
output pattern would generate an addg or subg instruction based on
whether operand 2 is negative.

Thanks,
Richard

Reply via email to