From: Andrei Nichita Tirziu <[email protected]>

The MATCH Pattern is a new addition to the vectorizer.
After the pattern is identified, a replacement node
is created for the initial expression.

This requires several new Internal Functions:
  - `IFN_MATCH_ANY_FROM`, `IFN_MATCH_NONE_FROM`: the basic IFNs for
     unpredicated `match / nmatch` instructions.
     These are used when building the new node, but are expected to
     get transformed into the conditional versions.
  - `IFN_COND_MATCH_ANY_FROM`, `IFN_COND_MATCH_NONE_FROM`: conditional versions.
  - `IFN_COND_LEN_MATCH_ANY_FROM`, `IFN_COND_LEN_MATCH_NONE_FROM`: conditional
     with length versions.

The arguments of these functions are:
  - `IFN_MATCH_ANY_FROM (variants, invariants)`
  - `IFN_MATCH_NONE_FROM (variants, invariants)`
  - `IFN_COND_MATCH_ANY_FROM (variants, invariants, mask, else)`
  - `IFN_COND_MATCH_NONE_FROM (variants, invariants, mask, else)`
  - `IFN_COND_LEN_MATCH_ANY_FROM (variants, invariants, mask, else, len, bias)`
  - `IFN_COND_LEN_MATCH_NONE_FROM (variants, invariants, mask, else, len, bias)`

These IFNs have corresponding optabs. It is up to the backends to support
them further. All the optabs are declared as "direct" optabs,
since only a mode is being used. It is expected that the mode
corresponds to the input vectors (the variants / invariants).

gcc/ChangeLog:

        * internal-fn.def: New IFNs for MATCH ANY FROM and MATCH
                           NONE FROM (including conditional versions).
        * internal-fn.cc: Define paramater positions for new IFNs.
        * optabs.def: New optabs for MATCH ANY FROM and MATCH
                      NONE FROM (including conditional versions).
---
 gcc/doc/md.texi     | 18 ++++++++++++++++++
 gcc/internal-fn.cc  | 18 +++++++++++++++++-
 gcc/internal-fn.def | 11 +++++++++++
 gcc/optabs.def      |  6 ++++++
 4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index edbdb1d50f1a..992fb3edfc49 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -6144,6 +6144,24 @@ with mode @var{m}.
 
 These instructions are not allowed to @code{FAIL}.
 
+@cindex @code{vec_match_any_from_@var{m}} instruction pattern
+@cindex @code{vec_match_none_from_@var{m}} instruction pattern
+@cindex @code{cond_vec_match_any_from_@var{m}} instruction pattern
+@cindex @code{cond_vec_match_none_from_@var{m}} instruction pattern
+@cindex @code{cond_len_vec_match_any_from_@var{m}} instruction pattern
+@cindex @code{cond_len_vec_match_none_from_@var{m}} instruction pattern
+@item @samp{vec_match_any_from_@var{m}}, 
@samp{cond_vec_match_any_from_@var{m}}, 
@samp{cond_len_vec_match_any_from_@var{m}}
+@itemx @samp{vec_match_none_from_@var{m}}, 
@samp{cond_vec_match_none_from_@var{m}}, 
@samp{cond_len_vec_match_none_from_@var{m}}
+Used for Match ANY FROM and Match NONE FROM patterns, which handle
+disjunctions of equality comparisons and conjunctions of inequality 
comparisons.
+
+@smallexample
+short int a[1000], x, y, z, sum = 0;
+for (int i = 0; i < 1000; i++)
+  if (a[i] == x || a[i] == y || a[i] == z)
+    sum++;
+@end smallexample
+
 @cindex @code{mulhisi3} instruction pattern
 @item @samp{mulhisi3}
 Multiply operands 1 and 2, which have mode @code{HImode}, and store
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index d879568c6e3e..f81d147c3830 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -4834,7 +4834,9 @@ get_conditional_len_internal_fn (tree_code code)
   T (ROUND) \
   T (FLOOR) \
   T (RINT) \
-  T (CEIL)
+  T (CEIL) \
+  T (MATCH_ANY_FROM) \
+  T (MATCH_NONE_FROM)
 
 /* Return a function that only performs internal function FN when a
    certain condition is met and that uses a given fallback value otherwise.
@@ -4890,6 +4892,10 @@ get_len_internal_fn (internal_fn fn)
       return IFN_MASK_LEN_LOAD_LANES;
     case IFN_MASK_GATHER_LOAD:
       return IFN_MASK_LEN_GATHER_LOAD;
+    case IFN_MATCH_ANY_FROM:
+      return IFN_COND_LEN_MATCH_ANY_FROM;
+    case IFN_MATCH_NONE_FROM:
+      return IFN_COND_LEN_MATCH_NONE_FROM;
     default:
       return IFN_LAST;
     }
@@ -5106,6 +5112,8 @@ internal_fn_len_index (internal_fn fn)
     case IFN_COND_LEN_XOR:
     case IFN_COND_LEN_SHL:
     case IFN_COND_LEN_SHR:
+    case IFN_COND_LEN_MATCH_ANY_FROM:
+    case IFN_COND_LEN_MATCH_NONE_FROM:
     case IFN_MASK_LEN_STRIDED_STORE:
       return 4;
 
@@ -5179,6 +5187,10 @@ internal_fn_else_index (internal_fn fn)
     case IFN_COND_LEN_XOR:
     case IFN_COND_LEN_SHL:
     case IFN_COND_LEN_SHR:
+    case IFN_COND_MATCH_ANY_FROM:
+    case IFN_COND_MATCH_NONE_FROM:
+    case IFN_COND_LEN_MATCH_ANY_FROM:
+    case IFN_COND_LEN_MATCH_NONE_FROM:
       return 3;
 
     case IFN_MASK_LOAD:
@@ -5225,6 +5237,10 @@ internal_fn_mask_index (internal_fn fn)
     case IFN_MASK_LEN_STORE_LANES:
     case IFN_MASK_LEN_LOAD:
     case IFN_MASK_LEN_STORE:
+    case IFN_COND_MATCH_ANY_FROM:
+    case IFN_COND_MATCH_NONE_FROM:
+    case IFN_COND_LEN_MATCH_ANY_FROM:
+    case IFN_COND_LEN_MATCH_NONE_FROM:
       return 2;
 
     case IFN_MASK_LEN_STRIDED_LOAD:
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 084a92716312..131328d29c1a 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -246,6 +246,17 @@ DEF_INTERNAL_OPTAB_FN (VEC_SET, ECF_CONST | ECF_NOTHROW, 
vec_set, vec_set)
 DEF_INTERNAL_OPTAB_FN (VEC_EXTRACT, ECF_CONST | ECF_NOTHROW,
                       vec_extract, vec_extract)
 
+// Internal functions for Match ANY FROM and Match NONE FROM patterns
+// (conjuction of inequalities or disjunction of equalities)
+DEF_INTERNAL_OPTAB_FN (MATCH_ANY_FROM, ECF_PURE | ECF_NOTHROW,
+                      vec_match_any_from, binary)
+DEF_INTERNAL_OPTAB_FN (MATCH_NONE_FROM, ECF_PURE | ECF_NOTHROW,
+                      vec_match_none_from, binary)
+DEF_INTERNAL_COND_FN (MATCH_ANY_FROM, ECF_PURE | ECF_NOTHROW,
+                     vec_match_any_from, binary)
+DEF_INTERNAL_COND_FN (MATCH_NONE_FROM, ECF_PURE | ECF_NOTHROW,
+                     vec_match_none_from, binary)
+
 DEF_INTERNAL_OPTAB_FN (LEN_STORE, 0, len_store, len_store)
 DEF_INTERNAL_OPTAB_FN (MASK_LEN_STORE, 0, mask_len_store, mask_len_store)
 
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 193f42a728a2..41932fc54ecd 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -517,6 +517,12 @@ OPTAB_D (vec_trunc_add_high_optab, "vec_trunc_add_high$a")
 OPTAB_D (vec_addsub_optab, "vec_addsub$a3")
 OPTAB_D (vec_fmaddsub_optab, "vec_fmaddsub$a4")
 OPTAB_D (vec_fmsubadd_optab, "vec_fmsubadd$a4")
+OPTAB_D (vec_match_any_from_optab, "vec_match_any_from_$a")
+OPTAB_D (vec_match_none_from_optab, "vec_match_none_from_$a")
+OPTAB_D (cond_vec_match_any_from_optab, "vec_match_any_from_cond_$a")
+OPTAB_D (cond_vec_match_none_from_optab, "vec_match_none_from_cond_$a")
+OPTAB_D (cond_len_vec_match_any_from_optab, "vec_match_any_from_cond_len_$a")
+OPTAB_D (cond_len_vec_match_none_from_optab, "vec_match_none_from_cond_len_$a")
 
 OPTAB_D (sync_add_optab, "sync_add$I$a")
 OPTAB_D (sync_and_optab, "sync_and$I$a")
-- 
2.52.0

Reply via email to