https://gcc.gnu.org/g:435ff0c5dff136eef427872991398ee09739fa3b
commit r17-1369-g435ff0c5dff136eef427872991398ee09739fa3b Author: Richard Biener <[email protected]> Date: Fri Jun 5 09:56:09 2026 +0200 tree-optimization/125602 - avoid negating the most negative signed value The following rewrites another case in niter analysis where we might end up using fold to negate the most negative signed value and expect that to be an INTEGER_CST. Like elsewhere we should swap negation and conversion to niter_type with the speciality that the affected path creates an assumption check in the original type. But for its construction we can avoid the negation. PR tree-optimization/125602 * tree-ssa-loop-niter.cc (number_of_iterations_until_wrap): Avoid double negation for assumption condition. Compute negated step in niter_type. * gcc.dg/torture/pr125602.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/torture/pr125602.c | 10 ++++++++++ gcc/tree-ssa-loop-niter.cc | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr125602.c b/gcc/testsuite/gcc.dg/torture/pr125602.c new file mode 100644 index 000000000000..54db4421986e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr125602.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fsanitize=undefined" } */ + +void f7() +{ + signed char v10; +lbl_b1: + v10 = -86 - 42 + v10; + if (0 > v10) goto lbl_b1; +} diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 391fcbfb2e16..13dd1e30fbbb 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -1453,13 +1453,13 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0, /* n < {base, C}. */ if (integer_zerop (iv0->step) && !tree_int_cst_sign_bit (iv1->step)) { - step = iv1->step; /* MIN + C - 1 <= n. */ - tree last = wide_int_to_tree (type, min + wi::to_wide (step) - 1); + tree last = wide_int_to_tree (type, min + wi::to_wide (iv1->step) - 1); assumptions = fold_build2 (LE_EXPR, boolean_type_node, last, iv0->base); if (integer_zerop (assumptions)) return false; + step = fold_convert (niter_type, iv1->step); num = fold_build2 (MINUS_EXPR, niter_type, wide_int_to_tree (niter_type, max), fold_convert (niter_type, iv1->base)); @@ -1491,13 +1491,14 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0, /* {base, -C} < n. */ else if (tree_int_cst_sign_bit (iv0->step) && integer_zerop (iv1->step)) { - step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv0->step), iv0->step); - /* MAX - C + 1 >= n. */ - tree last = wide_int_to_tree (type, max - wi::to_wide (step) + 1); + /* MAX + (-C) + 1 >= n. */ + tree last = wide_int_to_tree (type, max + wi::to_wide (iv0->step) + 1); assumptions = fold_build2 (GE_EXPR, boolean_type_node, last, iv1->base); if (integer_zerop (assumptions)) return false; + step = fold_build1 (NEGATE_EXPR, niter_type, + fold_convert (niter_type, iv0->step)); num = fold_build2 (MINUS_EXPR, niter_type, fold_convert (niter_type, iv0->base), wide_int_to_tree (niter_type, min)); @@ -1513,7 +1514,6 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0, return false; /* (delta + step - 1) / step */ - step = fold_convert (niter_type, step); num = fold_build2 (PLUS_EXPR, niter_type, num, step); niter->niter = fold_build2 (FLOOR_DIV_EXPR, niter_type, num, step);
