From d8b6da8dd15240849e00d46f3aef40cb8eeb1dc5 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 15 Feb 2022 09:40:59 +0100 Subject: [PATCH] tree-optimization/104519 - adjust PR100499 niter fix The following adjusts the PR100499 niter fix to use the appropriate types when checking whether the difference between the final and base values of the IV are a multiple of the step. It also gets rid of an always false condition in multiple_of_p which lead me to a wrong solution first. 2022-02-15 Richard Biener PR tree-optimization/104519 * fold-const.cc (multiple_of_p): Remove never true condition. * tree-ssa-loop-niter.cc (number_of_iterations_ne): Use the appropriate types for determining whether the difference of final and base is a multiple of the step. * gcc.dg/torture/pr104519.c: New testcase. --- gcc/fold-const.cc | 6 +----- gcc/testsuite/gcc.dg/torture/pr104519.c | 10 ++++++++++ gcc/tree-ssa-loop-niter.cc | 16 +++++++++++----- 3 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr104519.c diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 386d573..9d99396 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -14208,11 +14208,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap) && multiple_of_p (type, TREE_OPERAND (top, 2), bottom, nowrap)); case INTEGER_CST: - if (TREE_CODE (bottom) != INTEGER_CST - || integer_zerop (bottom) - || (TYPE_UNSIGNED (type) - && (tree_int_cst_sgn (top) < 0 - || tree_int_cst_sgn (bottom) < 0))) + if (TREE_CODE (bottom) != INTEGER_CST || integer_zerop (bottom)) return 0; return wi::multiple_of_p (wi::to_widest (top), wi::to_widest (bottom), SIGNED); diff --git a/gcc/testsuite/gcc.dg/torture/pr104519.c b/gcc/testsuite/gcc.dg/torture/pr104519.c new file mode 100644 index 0000000..389c7bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr104519.c @@ -0,0 +1,10 @@ +/* { dg-do run } */ + +signed char a, b; +int main() +{ + for (b = -7; b; b += 3) + if (a) + __builtin_abort(); + return 0; +} diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 318d10c..9bb5097 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -1048,13 +1048,19 @@ number_of_iterations_ne (class loop *loop, tree type, affine_iv *iv, which the loop exits immediately, and the iv does not overflow. Also note, we prove condition 2) by checking base and final seperately - along with condition 1) or 1'). */ + along with condition 1) or 1'). Since we ensure the difference + computation of c does not wrap with cond below and the adjusted s + will fit a signed type as well as an unsigned we can safely do + this using the type of the IV if it is not pointer typed. */ + tree mtype = type; + if (POINTER_TYPE_P (type)) + mtype = niter_type; if (!niter->control.no_overflow && (integer_onep (s) - || (multiple_of_p (type, fold_convert (niter_type, iv->base), s, - false) - && multiple_of_p (type, fold_convert (niter_type, final), s, - false)))) + || (multiple_of_p (mtype, fold_convert (mtype, iv->base), + fold_convert (mtype, s), false) + && multiple_of_p (mtype, fold_convert (mtype, final), + fold_convert (mtype, s), false)))) { tree t, cond, relaxed_cond = boolean_false_node; -- 2.7.4