[gcc r15-10352] tree-optimization/121370 - avoid UB in building a CHREC
Richard Biener
rguenth@gcc.gnu.org
Wed Sep 24 09:46:36 GMT 2025
https://gcc.gnu.org/g:6348c1c263b6b70d11cbe4f178463db7fba185b6
commit r15-10352-g6348c1c263b6b70d11cbe4f178463db7fba185b6
Author: Richard Biener <rguenther@suse.de>
Date: Tue Aug 5 08:59:18 2025 +0200
tree-optimization/121370 - avoid UB in building a CHREC
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.
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.
(cherry picked from commit afafae097232e700bb7a74a453a048b83ebefccd)
Diff:
---
gcc/testsuite/gcc.dg/torture/pr121370.c | 25 +++++++++++++++++++++++++
gcc/tree-scalar-evolution.cc | 11 +++++++++++
2 files changed, 36 insertions(+)
diff --git a/gcc/testsuite/gcc.dg/torture/pr121370.c b/gcc/testsuite/gcc.dg/torture/pr121370.c
new file mode 100644
index 000000000000..d40f3b216add
--- /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 4ca08751a0d3..7156cb426a7a 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
More information about the Gcc-cvs
mailing list