We treat POLY_INT_CSTs as VARYING, but the check in irange::set for them
was occurring after we called irange::set_range. This patch merely
shuffles the orders of checks around such that we check for undefined,
and then varying/polyints before the other cases. Performance impact is
negligible.
bootstraps on 86_64-pc-linux-gnu with no regressions. Compilation
reproduced the PR and patch passes the test on a cross compiler for
aarch64. I have no access to bootstrap on aarch64. Hopefully the
testcase works as provided :)
pushed.
Andrew
commit 265cdd067afd56293137ecb3057c5ba28a7c9480
Author: Andrew MacLeod <amacl...@redhat.com>
Date: Mon Aug 15 10:16:23 2022 -0400
Check for undefined and varying first.
Rearrange order in irange:set to ensure all POLY_INTs map to varying.
PR tree-optimization/106621
gcc/
* value-range.cc (irange::set): Check for POLY_INT_CST early.
gcc/testsuite/
* gcc.dg/pr106621.c
diff --git a/gcc/testsuite/gcc.dg/pr106621.c b/gcc/testsuite/gcc.dg/pr106621.c
new file mode 100644
index 00000000000..0465de4f14f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr106621.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-mcpu=neoverse-v1 -O2 -fvect-cost-model=dynamic -fno-tree-scev-cprop" } */
+
+int m, n;
+
+void
+foo (unsigned int x, short int y)
+{
+ if (m)
+ for (;;)
+ {
+ ++m;
+ while (m < 1)
+ {
+ n += m + x;
+ ++m;
+ }
+ }
+
+ for (;;)
+ if (y)
+ {
+ ++x;
+ if (x)
+ for (y = 0; y < 75; y += 2)
+ {
+ }
+ }
+}
+
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index a2273f540e8..d056f7356e1 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -716,25 +716,6 @@ irange::irange_set_anti_range (tree min, tree max)
void
irange::set (tree min, tree max, value_range_kind kind)
{
- if (kind != VR_UNDEFINED)
- {
- if (TREE_OVERFLOW_P (min))
- min = drop_tree_overflow (min);
- if (TREE_OVERFLOW_P (max))
- max = drop_tree_overflow (max);
- }
-
- if (!legacy_mode_p ())
- {
- if (kind == VR_RANGE)
- irange_set (min, max);
- else
- {
- gcc_checking_assert (kind == VR_ANTI_RANGE);
- irange_set_anti_range (min, max);
- }
- return;
- }
if (kind == VR_UNDEFINED)
{
irange::set_undefined ();
@@ -749,6 +730,22 @@ irange::set (tree min, tree max, value_range_kind kind)
return;
}
+ if (TREE_OVERFLOW_P (min))
+ min = drop_tree_overflow (min);
+ if (TREE_OVERFLOW_P (max))
+ max = drop_tree_overflow (max);
+
+ if (!legacy_mode_p ())
+ {
+ if (kind == VR_RANGE)
+ irange_set (min, max);
+ else
+ {
+ gcc_checking_assert (kind == VR_ANTI_RANGE);
+ irange_set_anti_range (min, max);
+ }
+ return;
+ }
// Nothing to canonicalize for symbolic ranges.
if (TREE_CODE (min) != INTEGER_CST
|| TREE_CODE (max) != INTEGER_CST)