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.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to trunk.
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 | 10 ++++++++++
gcc/tree-ssa-loop-niter.cc | 12 ++++++------
2 files changed, 16 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr125602.c
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);
--
2.51.0