]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/122680 - avoid range query during vect transform
authorRichard Biener <rguenther@suse.de>
Fri, 14 Nov 2025 07:20:56 +0000 (08:20 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 14 Nov 2025 08:28:32 +0000 (09:28 +0100)
Range queries during analysis on the original loop might not yield
the same result as those on the epilog during transform.  Separate
analysis from transform here.

PR tree-optimization/122680
* tree-vect-stmts.cc (vectorizable_conversion): Avoid range
queries during transform.

* gcc.dg/vect/pr122680.c: New testcase.

gcc/testsuite/gcc.dg/vect/pr122680.c [new file with mode: 0644]
gcc/tree-vect-stmts.cc

diff --git a/gcc/testsuite/gcc.dg/vect/pr122680.c b/gcc/testsuite/gcc.dg/vect/pr122680.c
new file mode 100644 (file)
index 0000000..3e25a3f
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+/* { dg-additional-options "-mavx2" { target avx2 } } */
+
+void
+foo (float *buf)
+{
+  for (unsigned long i = 0, j = 100; i < 100; i++, j--)
+    buf[i] = j;
+}
index b0f15902c8195c2b7650a5a2b41de389fce7f342..d08f5f19fd4449def710b0fe94108b87118352c2 100644 (file)
@@ -5580,23 +5580,26 @@ vectorizable_conversion (vec_info *vinfo,
         truncate it to cvt_type and the do FLOAT_EXPR.  */
       else if (code == FLOAT_EXPR)
        {
-         wide_int op_min_value, op_max_value;
-         tree def;
-         /* ???  Merge ranges in case of more than one lane.  */
-         if (SLP_TREE_LANES (slp_op0) != 1
-             || !(def = vect_get_slp_scalar_def (slp_op0, 0))
-             || !vect_get_range_info (def, &op_min_value, &op_max_value))
-           goto unsupported;
+         if (cost_vec)
+           {
+             wide_int op_min_value, op_max_value;
+             tree def;
+
+             /* ???  Merge ranges in case of more than one lane.  */
+             if (SLP_TREE_LANES (slp_op0) != 1
+                 || !(def = vect_get_slp_scalar_def (slp_op0, 0))
+                 || !vect_get_range_info (def, &op_min_value, &op_max_value))
+               goto unsupported;
+
+             if ((wi::min_precision (op_max_value, SIGNED)
+                  > GET_MODE_BITSIZE (lhs_mode))
+                 || (wi::min_precision (op_min_value, SIGNED)
+                     > GET_MODE_BITSIZE (lhs_mode)))
+               goto unsupported;
+           }
 
          cvt_type
            = build_nonstandard_integer_type (GET_MODE_BITSIZE (lhs_mode), 0);
-         if (cvt_type == NULL_TREE
-             || (wi::min_precision (op_max_value, SIGNED)
-                 > TYPE_PRECISION (cvt_type))
-             || (wi::min_precision (op_min_value, SIGNED)
-                 > TYPE_PRECISION (cvt_type)))
-           goto unsupported;
-
          cvt_type = get_same_sized_vectype (cvt_type, vectype_out);
          if (cvt_type == NULL_TREE)
            goto unsupported;