The following adds named patterns for reducing of vector masks with
AND, IOR and XOR to be used by the vectorizer. A slight complication
will be targets using scalar integer modes as mask modes, as those
do not reliably know the actual number of mask bits. A zero-extended
mask for IOR and a sign extended mask for AND works (and either for
XOR), but then I'm unsure who'd be supposed to ensure this. I guess
the vectorizer?
* doc/md.texi (reduc_mask_{and,ior,xor}_scal_<mode>): Document.
* optabs.def (reduc_mask_and_scal_optab,
reduc_mask_ior_scal_optab, reduc_mask_xor_scal_optab): New.
* internal-fn.def (MASK_REDUC_AND, MASK_REDUC_IOR,
MASK_REDUC_XOR): Likewise.
---
gcc/doc/md.texi | 11 +++++++++++
gcc/internal-fn.def | 7 +++++++
gcc/optabs.def | 3 +++
3 files changed, 21 insertions(+)
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 44e1149bea8..77e44b24c7b 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -5736,6 +5736,17 @@ of a vector of mode @var{m}. Operand 1 is the vector
input and operand 0
is the scalar result. The mode of the scalar result is the same as one
element of @var{m}.
+@cindex @code{reduc_mask_and_scal_@var{m}} instruction pattern
+@cindex @code{reduc_mask_ior_scal_@var{m}} instruction pattern
+@cindex @code{reduc_mask_xor_scal_@var{m}} instruction pattern
+@item @samp{reduc_mask_and_scal_@var{m}}
+@itemx @samp{reduc_mask_ior_scal_@var{m}}
+@itemx @samp{reduc_mask_xor_scal_@var{m}}
+Compute the bitwise @code{AND}/@code{IOR}/@code{XOR} reduction of the elements
+of a vector mask of mode @var{m}. Operand 1 is the vector input and operand 0
+is the scalar result. The mode of the scalar result is @var{QImode} with
+its value either zero or one.
+
@cindex @code{extract_last_@var{m}} instruction pattern
@item @code{extract_last_@var{m}}
Find the last set bit in mask operand 1 and extract the associated element
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 8434a805e28..97b518e56a8 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -330,6 +330,13 @@ DEF_INTERNAL_OPTAB_FN (REDUC_IOR, ECF_CONST | ECF_NOTHROW,
reduc_ior_scal, unary)
DEF_INTERNAL_OPTAB_FN (REDUC_XOR, ECF_CONST | ECF_NOTHROW,
reduc_xor_scal, unary)
+DEF_INTERNAL_OPTAB_FN (MASK_REDUC_AND, ECF_CONST | ECF_NOTHROW,
+ reduc_mask_and_scal, unary)
+DEF_INTERNAL_OPTAB_FN (MASK_REDUC_IOR, ECF_CONST | ECF_NOTHROW,
+ reduc_mask_ior_scal, unary)
+DEF_INTERNAL_OPTAB_FN (MASK_REDUC_XOR, ECF_CONST | ECF_NOTHROW,
+ reduc_mask_xor_scal, unary)
+
/* Extract the last active element from a vector. */
DEF_INTERNAL_OPTAB_FN (EXTRACT_LAST, ECF_CONST | ECF_NOTHROW,
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 790e43f08f4..22284f775ac 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -401,6 +401,9 @@ OPTAB_D (reduc_umin_scal_optab, "reduc_umin_scal_$a")
OPTAB_D (reduc_and_scal_optab, "reduc_and_scal_$a")
OPTAB_D (reduc_ior_scal_optab, "reduc_ior_scal_$a")
OPTAB_D (reduc_xor_scal_optab, "reduc_xor_scal_$a")
+OPTAB_D (reduc_mask_and_scal_optab, "reduc_mask_and_scal_$a")
+OPTAB_D (reduc_mask_ior_scal_optab, "reduc_mask_ior_scal_$a")
+OPTAB_D (reduc_mask_xor_scal_optab, "reduc_mask_xor_scal_$a")
OPTAB_D (fold_left_plus_optab, "fold_left_plus_$a")
OPTAB_D (mask_fold_left_plus_optab, "mask_fold_left_plus_$a")
OPTAB_D (mask_len_fold_left_plus_optab, "mask_len_fold_left_plus_$a")
--
2.51.0