aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr68963.c41
-rw-r--r--gcc/tree-ssa-loop-niter.c14
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);
}