From e53d562a36ead2279b98bc7cde3abe9606b44ee2 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 24 Feb 2016 12:03:27 +0000 Subject: [PATCH] re PR tree-optimization/68963 (O3 vs. O2 discards part of loop and terminates early) 2016-02-24 Richard Biener PR middle-end/68963 * tree-ssa-loop-niter.c (derive_constant_upper_bound_ops): Fix bogus check. (record_nonwrapping_iv): Do not fall back to the low/high bound for non-constant IV bases if the stmt is not always executed. * gcc.dg/torture/pr68963.c: New testcase. From-SVN: r233660 --- gcc/ChangeLog | 8 +++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/torture/pr68963.c | 41 ++++++++++++++++++++++++++ gcc/tree-ssa-loop-niter.c | 14 +++++---- 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr68963.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05b04b911da1..9dab27af9aa8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-02-24 Richard Biener + + PR middle-end/68963 + * tree-ssa-loop-niter.c (derive_constant_upper_bound_ops): Fix + bogus check. + (record_nonwrapping_iv): Do not fall back to the low/high bound + for non-constant IV bases if the stmt is not always executed. + 2016-02-24 Kyrylo Tkachov * config/arm/arm-cores.def (cortex-a32): New entry. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f678fbaeb398..ad48962d7231 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-24 Richard Biener + + PR middle-end/68963 + * gcc.dg/torture/pr68963.c: New testcase. + 2016-02-24 Kyrylo Tkachov PR target/69875 diff --git a/gcc/testsuite/gcc.dg/torture/pr68963.c b/gcc/testsuite/gcc.dg/torture/pr68963.c new file mode 100644 index 000000000000..c83b543fa035 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr68963.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ + +static const float a[3] = { 1, 2, 3 }; +int b = 3; + +__attribute__((noinline, noclone)) void +bar (int x) +{ + if (x != b++) + __builtin_abort (); +} + +void +foo (float *x, int y) +{ + int i; + for (i = 0; i < 2 * y; ++i) + { + if (i < y) + x[i] = a[i]; + else + { + bar (i); + x[i] = a[i - y]; + } + } +} + +int +main () +{ + float x[10]; + unsigned int i; + for (i = 0; i < 10; ++i) + x[i] = 1337; + foo (x, 3); + for (i = 0; i < 10; ++i) + if (x[i] != (i < 6 ? (i % 3) + 1 : 1337)) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index fbeeb9d6b731..43632edfe5d7 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2757,7 +2757,7 @@ derive_constant_upper_bound_ops (tree type, tree op0, enum tree_code code, tree op1) { tree subtype, maxt; - widest_int bnd, max, mmax, cst; + widest_int bnd, max, cst; gimple *stmt; if (INTEGRAL_TYPE_P (type)) @@ -2823,8 +2823,8 @@ derive_constant_upper_bound_ops (tree type, tree op0, /* OP0 + CST. We need to check that BND <= MAX (type) - CST. */ - mmax -= cst; - if (wi::ltu_p (bnd, max)) + widest_int mmax = max - cst; + if (wi::leu_p (bnd, mmax)) return max; return bnd + cst; @@ -3065,7 +3065,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt, && get_range_info (orig_base, &min, &max) == VR_RANGE && wi::gts_p (high, max)) base = wide_int_to_tree (unsigned_type, max); - else if (TREE_CODE (base) != INTEGER_CST) + else if (TREE_CODE (base) != INTEGER_CST + && dominated_by_p (CDI_DOMINATORS, + loop->latch, gimple_bb (stmt))) base = fold_convert (unsigned_type, high); delta = fold_build2 (MINUS_EXPR, unsigned_type, base, extreme); step = fold_build1 (NEGATE_EXPR, unsigned_type, step); @@ -3080,7 +3082,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt, && get_range_info (orig_base, &min, &max) == VR_RANGE && wi::gts_p (min, low)) base = wide_int_to_tree (unsigned_type, min); - else if (TREE_CODE (base) != INTEGER_CST) + else if (TREE_CODE (base) != INTEGER_CST + && dominated_by_p (CDI_DOMINATORS, + loop->latch, gimple_bb (stmt))) base = fold_convert (unsigned_type, low); delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base); }