]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/125602 - avoid negating the most negative signed value
authorRichard Biener <rguenther@suse.de>
Fri, 5 Jun 2026 07:56:09 +0000 (09:56 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 5 Jun 2026 08:59:31 +0000 (10:59 +0200)
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.

gcc/testsuite/gcc.dg/torture/pr125602.c [new file with mode: 0644]
gcc/tree-ssa-loop-niter.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr125602.c b/gcc/testsuite/gcc.dg/torture/pr125602.c
new file mode 100644 (file)
index 0000000..54db442
--- /dev/null
@@ -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;
+}
index 391fcbfb2e16c5489d972050e3214bc6072cfc9b..13dd1e30fbbbd79c98b3cbc26edc931fe3fec045 100644 (file)
@@ -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);