https://gcc.gnu.org/g:afafae097232e700bb7a74a453a048b83ebefccd

commit r16-2781-gafafae097232e700bb7a74a453a048b83ebefccd
Author: Richard Biener <rguent...@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.

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 413ca49cb926..3b3748aba67f 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

Reply via email to