When there is obvious UB involved in the process of re-associating
a series of IV increments to build up a CHREC, fail. This catches
a few degenerate cases where SCEV introduces UB with its inherent
re-associating of IV increments.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
PR tree-optimization/121370
* tree-scalar-evolution.cc (scev_dfs::add_to_evolution_1):
Avoid UB integer overflow in accumulating CHREC_RIGHT.
* gcc.dg/torture/pr121370.c: New testcase.
---
gcc/testsuite/gcc.dg/torture/pr121370.c | 25 +++++++++++++++++++++++++
gcc/tree-scalar-evolution.cc | 11 +++++++++++
2 files changed, 36 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr121370.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr121370.c
b/gcc/testsuite/gcc.dg/torture/pr121370.c
new file mode 100644
index 00000000000..d40f3b216ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121370.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+int a;
+int main()
+{
+ int c = -2147483647;
+ int d = -2147483647;
+ int e = 2147483647;
+ if (0)
+ f:
+ e = d + e - 2;
+g:
+ if (d - c - e > 0) {
+ a = -c;
+ if (a + d) {
+ d = 1;
+ goto g;
+ }
+ return 0;
+ }
+ if (e)
+ goto f;
+ return 0;
+}
diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index 413ca49cb92..3b3748aba67 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -670,6 +670,17 @@ scev_dfs::add_to_evolution_1 (tree chrec_before, tree
to_add, gimple *at_stmt)
to_add = chrec_convert (type, to_add, at_stmt);
right = chrec_convert_rhs (type, right, at_stmt);
right = chrec_fold_plus (chrec_type (right), right, to_add);
+ /* When we have an evolution in a non-wrapping type and
+ in the process of accumulating CHREC_RIGHT there was
+ overflow this indicates in the association that happened
+ in building the CHREC clearly involved UB. Avoid this.
+ In building a CHREC we basically turn (a + INCR1) + INCR2
+ into a + (INCR1 + INCR2) which is not always valid.
+ Note this check only catches few invalid cases. */
+ if ((INTEGRAL_TYPE_P (type) && ! TYPE_OVERFLOW_WRAPS (type))
+ && TREE_CODE (right) == INTEGER_CST
+ && TREE_OVERFLOW (right))
+ return chrec_dont_know;
return build_polynomial_chrec (var, left, right);
}
else
--
2.43.0