When trying to change a IV from IV0 < IV1 to IV0' != IV1' we apply
fancy adjustments to the may_be_zero condition we compute rather
than using the obvious IV0->base >= IV1->base expression (to be
able to use > instead of >=?). This doesn't seem to go well.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Can anybody think of what the adjustment by mod is about?
Thanks,
Richard.
PR tree-optimization/117574
* tree-ssa-loop-niter.cc (number_of_iterations_lt_to_ne):
Use the obvious may_be_zero condition.
* gcc.dg/torture/pr117574-1.c: New testcase.
---
gcc/testsuite/gcc.dg/torture/pr117574-1.c | 20 +++++++++++++++
gcc/tree-ssa-loop-niter.cc | 31 +++++------------------
2 files changed, 27 insertions(+), 24 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr117574-1.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr117574-1.c
b/gcc/testsuite/gcc.dg/torture/pr117574-1.c
new file mode 100644
index 00000000000..2e99cec13b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr117574-1.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+
+void abort (void);
+int a, c;
+long b;
+short d;
+static long e(long f, long h, long i) {
+ for (long g = f; g <= h; g += i)
+ b += g;
+ return b;
+}
+int main() {
+ c = 1;
+ for (; c >= 0; c--)
+ ;
+ for (; e(d + 40, d + 76, c + 51) < 4;)
+ ;
+ if (a != 0)
+ abort ();
+}
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 9518bf969cd..1be4b552206 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -1200,17 +1200,6 @@ number_of_iterations_lt_to_ne (tree type, affine_iv
*iv0, affine_iv *iv1,
if (integer_zerop (assumption))
return false;
}
- if (mpz_cmp (mmod, bnds->below) < 0)
- noloop = boolean_false_node;
- else if (POINTER_TYPE_P (type))
- noloop = fold_build2 (GT_EXPR, boolean_type_node,
- iv0->base,
- fold_build_pointer_plus (iv1->base, tmod));
- else
- noloop = fold_build2 (GT_EXPR, boolean_type_node,
- iv0->base,
- fold_build2 (PLUS_EXPR, type1,
- iv1->base, tmod));
}
else
{
@@ -1226,21 +1215,15 @@ number_of_iterations_lt_to_ne (tree type, affine_iv
*iv0, affine_iv *iv1,
if (integer_zerop (assumption))
return false;
}
- if (mpz_cmp (mmod, bnds->below) < 0)
- noloop = boolean_false_node;
- else if (POINTER_TYPE_P (type))
- noloop = fold_build2 (GT_EXPR, boolean_type_node,
- fold_build_pointer_plus (iv0->base,
- fold_build1 (NEGATE_EXPR,
- type1,
tmod)),
- iv1->base);
- else
- noloop = fold_build2 (GT_EXPR, boolean_type_node,
- fold_build2 (MINUS_EXPR, type1,
- iv0->base, tmod),
- iv1->base);
}
+ /* IV0 < IV1 does not loop if IV0->base >= IV1->base. */
+ if (mpz_cmp (mmod, bnds->below) < 0)
+ noloop = boolean_false_node;
+ else
+ noloop = fold_build2 (GE_EXPR, boolean_type_node,
+ iv0->base, iv1->base);
+
if (!integer_nonzerop (assumption))
niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
niter->assumptions,
--
2.43.0