From: Andrei Nichita Tirziu <[email protected]>

The optabs introduced for the new MATCH Pattern need an implementation
in the backend so that the vectorizer can complete the transformation.

The non-conditional optab is expanded to its conditional counterpart,
using an all-true predicate as a mask.
The conditional optab emits an SVE `match` or `nmatch` instructions.

The SVE backend doesn't make use of the `len` or `bias` arguments that
the conditional-len optab has, so there is no need to implement
such a version.

gcc/ChangeLog:

        * config/aarch64/aarch64-sve2.md: New patterns for match,
                                          nmatch optabs.
        * config/aarch64/iterators.md: New iterator for MATCH,
                                       NMATCH modes.
---
 gcc/config/aarch64/aarch64-sve2.md | 70 ++++++++++++++++++++++++++++++
 gcc/config/aarch64/iterators.md    |  3 ++
 2 files changed, 73 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-sve2.md 
b/gcc/config/aarch64/aarch64-sve2.md
index 4a2d2c1cb8ce..089216533625 100644
--- a/gcc/config/aarch64/aarch64-sve2.md
+++ b/gcc/config/aarch64/aarch64-sve2.md
@@ -4333,6 +4333,76 @@
 ;; - NMATCH
 ;; -------------------------------------------------------------------------
 
+;; SVE MATCH instruction. This is used by the `vec_match_any_from_optab`.
+;;
+;; The initial operands are (result, variants_vector, invariants_vector).
+;; A full-true mask is generated to transform it into a valid instruction.
+(define_expand "@vec_match_any_from_<mode>"
+  [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
+       (unspec:<VPRED>
+         [(match_operand:SVE_MATCH_AND_NMATCH 1 "register_operand" "w")
+          (match_operand:SVE_MATCH_AND_NMATCH 2 "register_operand" "w")]
+         UNSPEC_MATCH))]
+  "TARGET_SVE2 && TARGET_NON_STREAMING"
+  {
+    rtx true_pred = aarch64_ptrue_reg (<VPRED>mode);
+    emit_insn (gen_vec_match_any_from_cond_<mode>
+             (operands[0], operands[1], operands[2], true_pred, operands[1]));
+    DONE;
+  }
+)
+
+;; SVE MATCH instruction. This is used by the `cond_vec_match_any_from_optab`.
+;;
+;; The operands are
+;; (result, variants_vector, invariants_vector, mask, ignored_vector).
+(define_insn "@vec_match_any_from_cond_<mode>"
+  [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
+       (unspec:<VPRED>
+         [(match_operand:SVE_MATCH_AND_NMATCH 1 "register_operand" "w")
+          (match_operand:SVE_MATCH_AND_NMATCH 2 "register_operand" "w")
+          (match_operand:<VPRED> 3 "register_operand" "Upa")
+          (match_operand:SVE_MATCH_AND_NMATCH 4 "register_operand" "w")]
+         UNSPEC_MATCH))]
+  "TARGET_SVE2 && TARGET_NON_STREAMING"
+  "match\t%0.<Vetype>, %3/z, %1.<Vetype>, %2.<Vetype>"
+)
+
+;; SVE NMATCH instruction. This is used by the `vec_match_none_from_optab`.
+;;
+;; The initial operands are (result, variants_vector, invariants_vector).
+;; A full-true mask is generated to transform it into a valid instruction.
+(define_expand "@vec_match_none_from_<mode>"
+  [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
+       (unspec:<VPRED>
+         [(match_operand:SVE_MATCH_AND_NMATCH 1 "register_operand" "w")
+          (match_operand:SVE_MATCH_AND_NMATCH 2 "register_operand" "w")]
+         UNSPEC_NMATCH))]
+  "TARGET_SVE2 && TARGET_NON_STREAMING"
+  {
+    rtx true_pred = aarch64_ptrue_reg (<VPRED>mode);
+    emit_insn (gen_vec_match_none_from_cond_<mode>
+             (operands[0], operands[1], operands[2], true_pred, operands[1]));
+    DONE;
+  }
+)
+
+;; SVE NMATCH instruction. This is used by the 
`cond_vec_match_none_from_optab`.
+;;
+;; The operands are
+;; (result, variants_vector, invariants_vector, mask, ignored_vector).
+(define_insn "@vec_match_none_from_cond_<mode>"
+  [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
+       (unspec:<VPRED>
+         [(match_operand:SVE_MATCH_AND_NMATCH 1 "register_operand" "w")
+          (match_operand:SVE_MATCH_AND_NMATCH 2 "register_operand" "w")
+          (match_operand:<VPRED> 3 "register_operand" "Upa")
+          (match_operand:SVE_MATCH_AND_NMATCH 4 "register_operand" "w")]
+         UNSPEC_NMATCH))]
+  "TARGET_SVE2 && TARGET_NON_STREAMING"
+  "nmatch\t%0.<Vetype>, %3/z, %1.<Vetype>, %2.<Vetype>"
+)
+
 ;; Predicated string matching.
 (define_insn "@aarch64_pred_<sve_int_op><mode>"
   [(set (match_operand:<VPRED> 0 "register_operand")
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index b425b0ed2ca3..d5c3073f153c 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -723,6 +723,9 @@
 ;; Used for narrowing SVE floating point operations.
 (define_mode_iterator VNx16F_NARROW [SVE_FULL_HFx2 VNx16SF])
 
+;; SVE modes supported by MATCH and NMATCH instructions.
+(define_mode_iterator SVE_MATCH_AND_NMATCH [VNx16QI VNx8HI])
+
 ;; All SVE predicate modes.
 (define_mode_iterator PRED_ALL [VNx16BI VNx8BI VNx4BI VNx2BI])
 
-- 
2.52.0

Reply via email to