https://gcc.gnu.org/g:f4b64250a70482fbb51d6bb97fae481f90aa9649

commit r17-5452-gf4b64250a70482fbb51d6bb97fae481f90aa9649
Author: Richard Biener <[email protected]>
Date:   Tue Oct 20 14:17:01 2026 +0200

    tree-optimization/127975 - mixed AVX512 / AVX2 style masks with loop masking
    
    loop masking with AVX512 assumes integer type masks throughout, but when
    only a limited subset of AVX512 is enabled we can end up with mixed
    style masks which we do not support.  Verify this doesn't happen
    and disable loop masking in that case instead of ICEing at transform
    time.
    
            PR tree-optimization/127975
            * tree-vect-loop.cc (vect_verify_full_masking_avx512):
            Require all loop masks to be integer mode masks.
    
            * gcc.dg/vect/vect-simd-22.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/vect/vect-simd-22.c | 14 ++++++++++++++
 gcc/tree-vect-loop.cc                    | 29 ++++++++++++++++++-----------
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-22.c 
b/gcc/testsuite/gcc.dg/vect/vect-simd-22.c
new file mode 100644
index 000000000000..bbeb23f9e0db
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-22.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx512vl -mno-avx512bw --param 
vect-partial-vector-usage=2" { target { avx512vl } } } */
+
+#pragma omp declare simd simdlen(2)
+float f(double);
+
+void g(float *d, double *a, int n)
+{
+#pragma omp simd
+  for (int i = 0; i < n; i++)
+    d[i] = f(a[i]);
+
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index cfd03a97368b..51a71f990637 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -1148,6 +1148,8 @@ vect_verify_full_masking_avx512 (loop_vec_info loop_vinfo)
   if (!iv_type)
     return false;
 
+  bool ok = true;
+
   /* Produce the rgroup controls.  */
   for (auto const &mask : LOOP_VINFO_MASKS (loop_vinfo).mask_set)
     {
@@ -1168,37 +1170,42 @@ vect_verify_full_masking_avx512 (loop_vec_info 
loop_vinfo)
        masks->rgc_vec.safe_grow_cleared (nscalars_per_iter, true);
       rgroup_controls *rgm = &(*masks).rgc_vec[nscalars_per_iter - 1];
 
+      /* For now vect_get_loop_mask only supports integer mode masks
+        when we need to split it.  */
+      tree mask_type = truth_type_for (vectype);
+      if (GET_MODE_CLASS (TYPE_MODE (mask_type)) != MODE_INT
+         || TYPE_PRECISION (TREE_TYPE (mask_type)) != 1)
+       {
+         ok = false;
+         break;
+       }
+
       if (!rgm->type || rgm->factor > nvectors)
        {
-         rgm->type = truth_type_for (vectype);
+         rgm->type = mask_type;
          rgm->compare_type = NULL_TREE;
          rgm->max_nscalars_per_iter = nscalars_per_iter;
          rgm->factor = nvectors;
          rgm->bias_adjusted_ctrl = NULL_TREE;
        }
     }
+  if (!ok)
+    {
+      release_vec_loop_controls (&LOOP_VINFO_MASKS (loop_vinfo).rgc_vec);
+      return false;
+    }
 
   /* There is no fixed compare type we are going to use but we have to
      be able to get at one for each mask group.  */
   unsigned int min_ni_width
     = wi::min_precision (vect_max_vf (loop_vinfo), UNSIGNED);
 
-  bool ok = true;
   for (auto &rgc : LOOP_VINFO_MASKS (loop_vinfo).rgc_vec)
     {
       tree mask_type = rgc.type;
       if (!mask_type)
        continue;
 
-      /* For now vect_get_loop_mask only supports integer mode masks
-        when we need to split it.  */
-      if (GET_MODE_CLASS (TYPE_MODE (mask_type)) != MODE_INT
-         || TYPE_PRECISION (TREE_TYPE (mask_type)) != 1)
-       {
-         ok = false;
-         break;
-       }
-
       /* If iv_type is usable as compare type use that - we can elide the
         saturation in that case.   */
       if (TYPE_PRECISION (iv_type) >= min_ni_width)

Reply via email to