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