re PR tree-optimization/72817 (wrong code at -O3 on x86_64-linux-gnu (in both 32-bit and 64-bit modes))
PR tree-optimization/72817 PR tree-optimization/73450 * tree-ssa-loop-niter.c (number_of_iterations_ne): Check multiple_of_p for adjusted IV.base. gcc/testsuite * gcc.dg/tree-ssa/pr72817.c: New test. * gcc.dg/tree-ssa/pr73450.c: New test. From-SVN: r239494
This commit is contained in:
parent
f6ba953d24
commit
8f21990a67
|
@ -1,3 +1,10 @@
|
|||
2016-08-16 Bin Cheng <bin.cheng@arm.com>
|
||||
|
||||
PR tree-optimization/72817
|
||||
PR tree-optimization/73450
|
||||
* tree-ssa-loop-niter.c (number_of_iterations_ne): Check
|
||||
multiple_of_p for adjusted IV.base.
|
||||
|
||||
2016-08-15 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR target/72867
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2016-08-16 Bin Cheng <bin.cheng@arm.com>
|
||||
|
||||
PR tree-optimization/72817
|
||||
PR tree-optimization/73450
|
||||
* gcc.dg/tree-ssa/pr72817.c: New test.
|
||||
* gcc.dg/tree-ssa/pr73450.c: New test.
|
||||
|
||||
2016-08-15 Fritz Reese <fritzoreese@gmail.com>
|
||||
|
||||
* gfortran.dg/init_flag_13.f90: New testcase.
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O3" } */
|
||||
|
||||
char a;
|
||||
short b;
|
||||
|
||||
int main ()
|
||||
{
|
||||
for (a = 3; a != -1; a -= 5)
|
||||
while (b)
|
||||
;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O3" } */
|
||||
|
||||
int a;
|
||||
char b;
|
||||
int main() {
|
||||
char c = 0;
|
||||
for (; c != 3; c = c + 7) {
|
||||
a = b & a;
|
||||
if (a)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -999,33 +999,36 @@ number_of_iterations_ne (struct loop *loop, tree type, affine_iv *iv,
|
|||
mpz_clear (max);
|
||||
|
||||
/* Compute no-overflow information for the control iv. This can be
|
||||
proven when below two conditions hold.
|
||||
|
||||
1) |FINAL - base| is an exact multiple of step.
|
||||
2) IV evaluates toward FINAL at beginning, i.e:
|
||||
proven when below two conditions are satisfied:
|
||||
|
||||
1) IV evaluates toward FINAL at beginning, i.e:
|
||||
base <= FINAL ; step > 0
|
||||
base >= FINAL ; step < 0
|
||||
|
||||
Note the first condition holds, the second can be then relaxed
|
||||
to below condition.
|
||||
2) |FINAL - base| is an exact multiple of step.
|
||||
|
||||
base - step < FINAL ; step > 0
|
||||
&& base - step doesn't underflow
|
||||
base - step > FINAL ; step < 0
|
||||
&& base - step doesn't overflow
|
||||
Unfortunately, it's hard to prove above conditions after pass loop-ch
|
||||
because loop with exit condition (IV != FINAL) usually will be guarded
|
||||
by initial-condition (IV.base - IV.step != FINAL). In this case, we
|
||||
can alternatively try to prove below conditions:
|
||||
|
||||
The relaxation is important because after pass loop-ch, loop
|
||||
with exit condition (IV != FINAL) will usually be guarded by
|
||||
pre-condition (IV.base - IV.step != FINAL). Please refer to
|
||||
PR34114 as an example.
|
||||
1') IV evaluates toward FINAL at beginning, i.e:
|
||||
new_base = base - step < FINAL ; step > 0
|
||||
&& base - step doesn't underflow
|
||||
new_base = base - step > FINAL ; step < 0
|
||||
&& base - step doesn't overflow
|
||||
|
||||
Also note, for NE_EXPR, base equals to FINAL is a special case, in
|
||||
2') |FINAL - new_base| is an exact multiple of step.
|
||||
|
||||
Please refer to PR34114 as an example of loop-ch's impact, also refer
|
||||
to PR72817 as an example why condition 2') is necessary.
|
||||
|
||||
Note, for NE_EXPR, base equals to FINAL is a special case, in
|
||||
which the loop exits immediately, and the iv does not overflow. */
|
||||
if (!niter->control.no_overflow
|
||||
&& (integer_onep (s) || multiple_of_p (type, c, s)))
|
||||
{
|
||||
tree t, cond, relaxed_cond = boolean_false_node;
|
||||
tree t, cond, new_c, relaxed_cond = boolean_false_node;
|
||||
|
||||
if (tree_int_cst_sign_bit (iv->step))
|
||||
{
|
||||
|
@ -1039,8 +1042,12 @@ number_of_iterations_ne (struct loop *loop, tree type, affine_iv *iv,
|
|||
if (integer_nonzerop (t))
|
||||
{
|
||||
t = fold_build2 (MINUS_EXPR, type, iv->base, iv->step);
|
||||
relaxed_cond = fold_build2 (GT_EXPR, boolean_type_node,
|
||||
t, final);
|
||||
new_c = fold_build2 (MINUS_EXPR, niter_type,
|
||||
fold_convert (niter_type, t),
|
||||
fold_convert (niter_type, final));
|
||||
if (multiple_of_p (type, new_c, s))
|
||||
relaxed_cond = fold_build2 (GT_EXPR, boolean_type_node,
|
||||
t, final);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1056,8 +1063,12 @@ number_of_iterations_ne (struct loop *loop, tree type, affine_iv *iv,
|
|||
if (integer_nonzerop (t))
|
||||
{
|
||||
t = fold_build2 (MINUS_EXPR, type, iv->base, iv->step);
|
||||
relaxed_cond = fold_build2 (LT_EXPR, boolean_type_node,
|
||||
t, final);
|
||||
new_c = fold_build2 (MINUS_EXPR, niter_type,
|
||||
fold_convert (niter_type, final),
|
||||
fold_convert (niter_type, t));
|
||||
if (multiple_of_p (type, new_c, s))
|
||||
relaxed_cond = fold_build2 (LT_EXPR, boolean_type_node,
|
||||
t, final);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue