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.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
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 | 10 +++++++++
gcc/tree-vect-stmts.cc | 31 +++++++++++++++-------------
2 files changed, 27 insertions(+), 14 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/vect/pr122680.c
diff --git a/gcc/testsuite/gcc.dg/vect/pr122680.c
b/gcc/testsuite/gcc.dg/vect/pr122680.c
new file mode 100644
index 00000000000..3e25a3f2fed
--- /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 b0f15902c81..d08f5f19fd4 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;
--
2.51.0