Commit e53d562a by Richard Biener Committed by Richard Biener

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
parent debc68ed
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> 2016-02-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm-cores.def (cortex-a32): New entry. * config/arm/arm-cores.def (cortex-a32): New entry.
......
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> 2016-02-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/69875 PR target/69875
......
/* { 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;
}
...@@ -2757,7 +2757,7 @@ derive_constant_upper_bound_ops (tree type, tree op0, ...@@ -2757,7 +2757,7 @@ derive_constant_upper_bound_ops (tree type, tree op0,
enum tree_code code, tree op1) enum tree_code code, tree op1)
{ {
tree subtype, maxt; tree subtype, maxt;
widest_int bnd, max, mmax, cst; widest_int bnd, max, cst;
gimple *stmt; gimple *stmt;
if (INTEGRAL_TYPE_P (type)) if (INTEGRAL_TYPE_P (type))
...@@ -2823,8 +2823,8 @@ derive_constant_upper_bound_ops (tree type, tree op0, ...@@ -2823,8 +2823,8 @@ derive_constant_upper_bound_ops (tree type, tree op0,
/* OP0 + CST. We need to check that /* OP0 + CST. We need to check that
BND <= MAX (type) - CST. */ BND <= MAX (type) - CST. */
mmax -= cst; widest_int mmax = max - cst;
if (wi::ltu_p (bnd, max)) if (wi::leu_p (bnd, mmax))
return max; return max;
return bnd + cst; return bnd + cst;
...@@ -3065,7 +3065,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt, ...@@ -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 && get_range_info (orig_base, &min, &max) == VR_RANGE
&& wi::gts_p (high, max)) && wi::gts_p (high, max))
base = wide_int_to_tree (unsigned_type, 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); base = fold_convert (unsigned_type, high);
delta = fold_build2 (MINUS_EXPR, unsigned_type, base, extreme); delta = fold_build2 (MINUS_EXPR, unsigned_type, base, extreme);
step = fold_build1 (NEGATE_EXPR, unsigned_type, step); step = fold_build1 (NEGATE_EXPR, unsigned_type, step);
...@@ -3080,7 +3082,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt, ...@@ -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 && get_range_info (orig_base, &min, &max) == VR_RANGE
&& wi::gts_p (min, low)) && wi::gts_p (min, low))
base = wide_int_to_tree (unsigned_type, min); 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); base = fold_convert (unsigned_type, low);
delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base); delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment