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.
This commit is contained in:
Richard Biener
2025-08-05 08:59:18 +02:00
committed by Richard Biener
parent bc97874bec
commit afafae0972
2 changed files with 36 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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