From: Richard Biener Date: Fri, 5 Jun 2026 07:56:09 +0000 (+0200) Subject: tree-optimization/125602 - avoid negating the most negative signed value X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=435ff0c5dff136eef427872991398ee09739fa3b;p=thirdparty%2Fgcc.git 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 --git a/gcc/testsuite/gcc.dg/torture/pr125602.c b/gcc/testsuite/gcc.dg/torture/pr125602.c new file mode 100644 index 00000000000..54db4421986 --- /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 391fcbfb2e1..13dd1e30fbb 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);