re PR tree-optimization/26180 (wrong code due to VRP and unsigned multiplies with wraps)

PR 26180
	* tree-vrp.c (vrp_int_const_binop): Detect overflow when
	multiplying unsigned values.
	Tidy comments.

testsuite

	PR 26180
	* gcc.dg/tree-ssa/pr26180.c: New test.

From-SVN: r110794
This commit is contained in:
Diego Novillo 2006-02-09 12:38:35 +00:00 committed by Diego Novillo
parent e10fbf9639
commit 7dc32197a8
4 changed files with 63 additions and 6 deletions

View File

@ -1,3 +1,10 @@
2006-02-09 Diego Novillo <dnovillo@redhat.com>
PR 26180
* tree-vrp.c (vrp_int_const_binop): Detect overflow when
multiplying unsigned values.
Tidy comments.
2006-02-09 Eric Botcazou <ebotcazou@libertysurf.fr>
* config/sparc/sparc.c (tls_call_delay): Fix oversight.

View File

@ -1,3 +1,8 @@
2006-02-09 Diego Novillo <dnovillo@redhat.com>
PR 26180
* gcc.dg/tree-ssa/pr26180.c: New test.
2006-02-08 Jeff Law <law@redhat.com>
* gcc.dg/tree-ssa/pr21417.c: New test.

View File

@ -0,0 +1,43 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
void abort(void);
int bar(int x, int y)
{
int x1, y1;
int x2, y2;
unsigned int x3, y3, w;
int z = 1;
x1 = (x < (1 << 30));
y1 = (y < (1 << 30));
if (x1)
if (y1) {
x2 = ((x > 0)? (x): -(x));
y2 = ((y > 0)? (y): -(y));
x3 = x2;
y3 = y2;
w = x3 * y3;
if (w >= (1 << 30)) {
z = 1;
} else {
z = -1;
}
}
return z;
}
int main()
{
int x, y, z;
x = 536870912; /* 2^29 */
y = 2;
z = bar(x, y);
if (z != 1)
abort ();
return 0;
}

View File

@ -1191,22 +1191,24 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
{
int checkz = compare_values (res, val1);
/* Ensure that res = val1 + val2 >= val1
/* Ensure that res = val1 [+*] val2 >= val1
or that res = val1 - val2 <= val1. */
if ((code == PLUS_EXPR && !(checkz == 1 || checkz == 0))
|| (code == MINUS_EXPR && !(checkz == 0 || checkz == -1)))
if (((code == PLUS_EXPR || code == MULT_EXPR)
&& !(checkz == 1 || checkz == 0))
|| (code == MINUS_EXPR
&& !(checkz == 0 || checkz == -1)))
{
res = copy_node (res);
TREE_OVERFLOW (res) = 1;
}
}
/* If the operation overflowed but neither VAL1 nor VAL2 are
overflown, return -INF or +INF depending on the operation
and the combination of signs of the operands. */
else if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1)
&& !TREE_OVERFLOW (val2))
{
/* If the operation overflowed but neither VAL1 nor VAL2 are
overflown, return -INF or +INF depending on the operation
and the combination of signs of the operands. */
int sgn1 = tree_int_cst_sgn (val1);
int sgn2 = tree_int_cst_sgn (val2);