]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/121370 - avoid UB in building a CHREC
authorRichard Biener <rguenther@suse.de>
Tue, 5 Aug 2025 06:59:18 +0000 (08:59 +0200)
committerRichard Biener <rguenther@suse.de>
Tue, 14 Oct 2025 11:53:03 +0000 (13:53 +0200)
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)

gcc/testsuite/gcc.dg/torture/pr121370.c [new file with mode: 0644]
gcc/tree-scalar-evolution.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr121370.c b/gcc/testsuite/gcc.dg/torture/pr121370.c
new file mode 100644 (file)
index 0000000..d40f3b2
--- /dev/null
@@ -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;
+}
index b0a5e09a77c106c6f1ceb7e0a1e7f7b904db92d4..a3511c55c7052fad87ff6141bc096b0c7c621214 100644 (file)
@@ -669,6 +669,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