re PR tree-optimization/68911 (wrong code with -O1 -ftree-vrp)

PR tree-optimization/68911
	* tree-vrp.c (adjust_range_with_scev): Check overflow in range
	information computed for expression "init + nit * step".

	gcc/testsuite/ChangeLog
	PR tree-optimization/68911
	* gcc.c-torture/execute/pr68911.c: New test.

From-SVN: r232286
This commit is contained in:
Bin Cheng 2016-01-12 17:49:51 +00:00 committed by Bin Cheng
parent ee30410c37
commit c446cf07e9
4 changed files with 59 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2016-01-12 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/68911
* tree-vrp.c (adjust_range_with_scev): Check overflow in range
information computed for expression "init + nit * step".
2016-01-12 Sandra Loosemore <sandra@codesourcery.com>
* doc/invoke.texi (Invoking GCC): Copy-edit. Incorporate information

View File

@ -1,3 +1,8 @@
2016-01-12 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/68911
* gcc.c-torture/execute/pr68911.c: New test.
2016-01-12 Marek Polacek <polacek@redhat.com>
PR c++/68979

View File

@ -0,0 +1,27 @@
extern void abort (void);
char a;
int b, c;
short d;
int main ()
{
unsigned e = 2;
unsigned timeout = 0;
for (; c < 2; c++)
{
int f = ~e / 7;
if (f)
a = e = ~(b && d);
while (e < 94)
{
e++;
if (++timeout > 100)
goto die;
}
}
return 0;
die:
abort ();
}

View File

@ -4259,6 +4259,27 @@ adjust_range_with_scev (value_range *vr, struct loop *loop,
/* Likewise if the addition did. */
if (maxvr.type == VR_RANGE)
{
value_range initvr = VR_INITIALIZER;
if (TREE_CODE (init) == SSA_NAME)
initvr = *(get_value_range (init));
else if (is_gimple_min_invariant (init))
set_value_range_to_value (&initvr, init, NULL);
else
return;
/* Check if init + nit * step overflows. Though we checked
scev {init, step}_loop doesn't wrap, it is not enough
because the loop may exit immediately. Overflow could
happen in the plus expression in this case. */
if ((dir == EV_DIR_DECREASES
&& (is_negative_overflow_infinity (maxvr.min)
|| compare_values (maxvr.min, initvr.min) != -1))
|| (dir == EV_DIR_GROWS
&& (is_positive_overflow_infinity (maxvr.max)
|| compare_values (maxvr.max, initvr.max) != 1)))
return;
tmin = maxvr.min;
tmax = maxvr.max;
}