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
This commit is contained in:
Richard Biener 2016-02-24 12:03:27 +00:00 committed by Richard Biener
parent debc68edb4
commit e53d562a36
4 changed files with 63 additions and 5 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}