diff options
author | Richard Biener <rguenther@suse.de> | 2016-02-24 12:03:27 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-02-24 12:03:27 +0000 |
commit | e53d562a36ead2279b98bc7cde3abe9606b44ee2 (patch) | |
tree | 5cd461c7bd1554cfa9a6aa0662f753d76e4bb68a /gcc | |
parent | debc68edb4df2357589427fe90ea894467c7b2e2 (diff) | |
download | gcc-e53d562a36ead2279b98bc7cde3abe9606b44ee2.zip gcc-e53d562a36ead2279b98bc7cde3abe9606b44ee2.tar.gz gcc-e53d562a36ead2279b98bc7cde3abe9606b44ee2.tar.bz2 |
re PR tree-optimization/68963 (O3 vs. O2 discards part of loop and terminates early)
2016-02-24 Richard Biener <rguenther@suse.de>
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr68963.c | 41 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.c | 14 |
4 files changed, 63 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05b04b9..9dab27a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-02-24 Richard Biener <rguenther@suse.de> + + 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 <kyrylo.tkachov@arm.com> * config/arm/arm-cores.def (cortex-a32): New entry. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f678fba..ad48962 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-24 Richard Biener <rguenther@suse.de> + + PR middle-end/68963 + * gcc.dg/torture/pr68963.c: New testcase. + 2016-02-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 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 0000000..c83b543 --- /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 fbeeb9d..43632ed 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); } |