https://gcc.gnu.org/g:55a77666c9126fe8c189aff82059003ad513b22f

commit r16-5273-g55a77666c9126fe8c189aff82059003ad513b22f
Author: Richard Biener <[email protected]>
Date:   Fri Nov 14 08:20:56 2025 +0100

    tree-optimization/122680 - avoid range query during vect transform
    
    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.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr122680.c | 10 ++++++++++
 gcc/tree-vect-stmts.cc               | 31 +++++++++++++++++--------------
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr122680.c 
b/gcc/testsuite/gcc.dg/vect/pr122680.c
new file mode 100644
index 000000000000..3e25a3f2feda
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr122680.c
@@ -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;
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index b0f15902c819..d08f5f19fd44 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -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;

Reply via email to