diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fold-const.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr104519.c | 10 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.cc | 16 |
3 files changed, 22 insertions, 10 deletions
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; |