When vectorizable_simd_clone_call uses an inbranch SIMD clone for a call
site that is not masked, it synthesizes an all-true mask.  For clones
whose mask argument is a vector of the argument type (mask_mode ==
VOIDmode) it built an all-ones mask of that type and then converted it
to the clone's 1/0 encoding with

  VEC_COND_EXPR <mask, { 1, ... }, { 0, ... }>

A VEC_COND_EXPR condition must be a boolean vector, but
vect_build_all_ones_mask returns one only when the mask type is
boolean; for a floating-point mask type it is a vector of NaNs, and the
statement is invalid GIMPLE.  On x86_64 the SSE clone takes its mask as
vector(2) double; since r17-2654 two calls of an "omp declare simd
inbranch" function can be SLP-vectorized as one unmasked call of that
clone, so this ICEs at -O2 -fopenmp-simd.

All lanes are active, so pass the value the VEC_COND_EXPR would select,
a vector of 1s, directly.

        PR tree-optimization/127784

gcc/ChangeLog:

        * tree-vect-stmts.cc (vectorizable_simd_clone_call): Pass a vector
        of 1s as an all-true mask for a VOIDmode mask_mode.

gcc/testsuite/ChangeLog:

        * gcc.dg/vect/vect-simd-clone-allones-mask.c: New test.

Signed-off-by: Igor Shevlyakov <[email protected]>
---
Bootstrapped and regtested on x86_64-pc-linux-gnu (-m32/-m64), no new 
regressions.

 .../vect/vect-simd-clone-allones-mask.c       | 43 +++++++++++++++++++
 gcc/tree-vect-stmts.cc                        |  8 ++++
 2 files changed, 51 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-simd-clone-allones-mask.c

diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-allones-mask.c 
b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-allones-mask.c
new file mode 100644
index 00000000000..d74e9246168
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-allones-mask.c
@@ -0,0 +1,43 @@
+/* Unmasked call of an inbranch SIMD clone whose mask argument is a
+   floating-point vector.  */
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd --param vect-partial-vector-usage=0" 
} */
+/* { dg-additional-options "-mavx512f" { target avx512f_runtime } } */
+
+#include "tree-vect.h"
+
+#define N 64
+
+#pragma omp declare simd inbranch
+__attribute__((noinline)) double
+foo (double x, double y)
+{
+  return x * 10.0 + y;
+}
+
+double r[N], t[N];
+
+__attribute__((noipa)) void
+f (double *rp, double *tp, long n)
+{
+  for (long i = 0; i < n; i++)
+    rp[i] = rp[i] * (foo (tp[0] + 1.0, tp[0] + 2.0)
+                    + foo (tp[0] + 3.0, tp[0] + 4.0));
+}
+
+int
+main ()
+{
+  check_vect ();
+  for (int i = 0; i < N; i++)
+    {
+      r[i] = i;
+      t[i] = 0.5;
+    }
+  f (r, t, N);
+  /* foo (1.5, 2.5) + foo (3.5, 4.5) = 17.5 + 39.5.  */
+  for (int i = 0; i < N; i++)
+    if (r[i] != i * 57.0)
+      __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 18d0dd8ff3a..fd87bdab684 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -4903,6 +4903,14 @@ vectorizable_simd_clone_call (vec_info *vinfo, 
stmt_vec_info stmt_info,
                  mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks,
                                             ncopies * o, mask_vectype, m);
                }
+             else if (bestn->simdclone->mask_mode == VOIDmode)
+               {
+                 /* All lanes are active: pass what the VEC_COND_EXPR below
+                    would select.  An all-ones floating-point MASK_ARGTYPE
+                    is not a valid condition.  */
+                 vargs.safe_push (build_one_cst (mask_argtype));
+                 continue;
+               }
              else
                mask = vect_build_all_ones_mask (vinfo, stmt_info,
                                                 mask_argtype);
-- 
2.55.0


Reply via email to