From 395dd6595cabebb7fd3e71a5fbfe84544d598608 Mon Sep 17 00:00:00 2001 Author: Bin Cheng Date: Fri, 28 May 2021 16:49:54 +0800 Subject: [PATCH] Simplify exit cond comparing two IVs only if they converge. We should also check that iv1.step >= iv2.step so that the two IVs converge to each other under comparison condition LE_EXPR/LT_EXPR. gcc: PR tree-optimization/100740 * tree-ssa-loop-niter.c (number_of_iterations_cond): Check IVs converge or not. gcc/testsuite: * gcc.c-torture/execute/pr100740.c --- .../gcc.c-torture/execute/pr100740.c | 11 ++++++++++ gcc/tree-ssa-loop-niter.c | 20 +++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr100740.c diff --git a/gcc/testsuite/gcc.c-torture/execute/pr100740.c b/gcc/testsuite/gcc.c-torture/execute/pr100740.c new file mode 100644 index 00000000000..8fcdaffef3b --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr100740.c @@ -0,0 +1,11 @@ +/* PR tree-optimization/100740 */ + +unsigned a, b; +int main() { + unsigned c = 0; + for (a = 0; a < 2; a++) + for (b = 0; b < 2; b++) + if (++c < a) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 325bd978609..6240084782a 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -1782,7 +1782,9 @@ number_of_iterations_cond (class loop *loop, provided that either below condition is satisfied: a) the test is NE_EXPR; - b) iv0.step - iv1.step is integer and iv0/iv1 don't overflow. + b) iv0.step and iv1.step are integers and: + - iv0 and iv1 don't overflow. + - iv0 and iv1 converge to each other, under cond LE_EXPR/LT_EXPR. This rarely occurs in practice, but it is simple enough to manage. */ if (!integer_zerop (iv0->step) && !integer_zerop (iv1->step)) @@ -1790,14 +1792,20 @@ number_of_iterations_cond (class loop *loop, tree step_type = POINTER_TYPE_P (type) ? sizetype : type; tree step = fold_binary_to_constant (MINUS_EXPR, step_type, iv0->step, iv1->step); + if (code != NE_EXPR) + { + if (TREE_CODE (step) != INTEGER_CST) + return false; + + if (!iv0->no_overflow || !iv1->no_overflow) + return false; + + if (tree_int_cst_lt (iv0->step, iv1->step)) + return false; + } /* No need to check sign of the new step since below code takes care of this well. */ - if (code != NE_EXPR - && (TREE_CODE (step) != INTEGER_CST - || !iv0->no_overflow || !iv1->no_overflow)) - return false; - iv0->step = step; if (!POINTER_TYPE_P (type)) iv0->no_overflow = false; -- 2.19.1.6.gb485710b