re PR middle-end/30364 (Wrong variable ranges due to constant folding)
2007-02-28 Richard Guenther <rguenther@suse.de> PR middle-end/30364 * fold-const.c (fold_binary): Do not associate expressions with more than one variable for integer types that do not wrap. * gcc.dg/torture/pr30364-1.c: New testcase. * gcc.dg/torture/pr30364-2.c: Likewise. * gcc.dg/torture/pr30364-3.c: Likewise. From-SVN: r122414
This commit is contained in:
parent
cfac137674
commit
a6d5f37ceb
|
@ -1,3 +1,9 @@
|
||||||
|
2007-02-28 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR middle-end/30364
|
||||||
|
* fold-const.c (fold_binary): Do not associate expressions
|
||||||
|
with more than one variable for integer types that do not wrap.
|
||||||
|
|
||||||
2007-02-28 Sandra Loosemore <sandra@codesourcery.com>
|
2007-02-28 Sandra Loosemore <sandra@codesourcery.com>
|
||||||
|
|
||||||
* builtins.c (fold_builtin_call_list, fold_builtin_call_valist):
|
* builtins.c (fold_builtin_call_list, fold_builtin_call_valist):
|
||||||
|
|
|
@ -9424,6 +9424,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||||
{
|
{
|
||||||
tree var0, con0, lit0, minus_lit0;
|
tree var0, con0, lit0, minus_lit0;
|
||||||
tree var1, con1, lit1, minus_lit1;
|
tree var1, con1, lit1, minus_lit1;
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
/* Split both trees into variables, constants, and literals. Then
|
/* Split both trees into variables, constants, and literals. Then
|
||||||
associate each group together, the constants with literals,
|
associate each group together, the constants with literals,
|
||||||
|
@ -9434,12 +9435,32 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||||
var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1,
|
var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1,
|
||||||
code == MINUS_EXPR);
|
code == MINUS_EXPR);
|
||||||
|
|
||||||
|
/* With undefined overflow we can only associate constants
|
||||||
|
with one variable. */
|
||||||
|
if ((POINTER_TYPE_P (type)
|
||||||
|
|| (INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type)))
|
||||||
|
&& var0 && var1)
|
||||||
|
{
|
||||||
|
tree tmp0 = var0;
|
||||||
|
tree tmp1 = var1;
|
||||||
|
|
||||||
|
if (TREE_CODE (tmp0) == NEGATE_EXPR)
|
||||||
|
tmp0 = TREE_OPERAND (tmp0, 0);
|
||||||
|
if (TREE_CODE (tmp1) == NEGATE_EXPR)
|
||||||
|
tmp1 = TREE_OPERAND (tmp1, 0);
|
||||||
|
/* The only case we can still associate with two variables
|
||||||
|
is if they are the same, modulo negation. */
|
||||||
|
if (!operand_equal_p (tmp0, tmp1, 0))
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only do something if we found more than two objects. Otherwise,
|
/* Only do something if we found more than two objects. Otherwise,
|
||||||
nothing has changed and we risk infinite recursion. */
|
nothing has changed and we risk infinite recursion. */
|
||||||
if (2 < ((var0 != 0) + (var1 != 0)
|
if (ok
|
||||||
+ (con0 != 0) + (con1 != 0)
|
&& (2 < ((var0 != 0) + (var1 != 0)
|
||||||
+ (lit0 != 0) + (lit1 != 0)
|
+ (con0 != 0) + (con1 != 0)
|
||||||
+ (minus_lit0 != 0) + (minus_lit1 != 0)))
|
+ (lit0 != 0) + (lit1 != 0)
|
||||||
|
+ (minus_lit0 != 0) + (minus_lit1 != 0))))
|
||||||
{
|
{
|
||||||
/* Recombine MINUS_EXPR operands by using PLUS_EXPR. */
|
/* Recombine MINUS_EXPR operands by using PLUS_EXPR. */
|
||||||
if (code == MINUS_EXPR)
|
if (code == MINUS_EXPR)
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2007-02-28 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR middle-end/30364
|
||||||
|
* gcc.dg/torture/pr30364-1.c: New testcase.
|
||||||
|
* gcc.dg/torture/pr30364-2.c: Likewise.
|
||||||
|
* gcc.dg/torture/pr30364-3.c: Likewise.
|
||||||
|
|
||||||
2007-02-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
2007-02-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||||
|
|
||||||
* gcc.dg/torture/builtin-frexp-1.c: On mips*-*-irix6* and
|
* gcc.dg/torture/builtin-frexp-1.c: On mips*-*-irix6* and
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
|
||||||
|
extern void abort (void);
|
||||||
|
|
||||||
|
int f(int a, int b)
|
||||||
|
{
|
||||||
|
if (a > 0x7FFFFFF0) return 0;
|
||||||
|
if (b > 0x7FFFFFF0) return 0;
|
||||||
|
|
||||||
|
int c = (a - 20) + (b - 20);
|
||||||
|
return c > 0x7FFFFFF0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (f (0x7FFFFFF0, 41) != 1)
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
|
||||||
|
extern void abort (void);
|
||||||
|
|
||||||
|
int f(unsigned int a, unsigned int b)
|
||||||
|
{
|
||||||
|
if (a > 0x7FFFFFF0) return 0;
|
||||||
|
if (b > 0x7FFFFFF0) return 0;
|
||||||
|
|
||||||
|
int c = (a - 20) + (b - 20);
|
||||||
|
return c > 0x7FFFFFF0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (f (0x7FFFFFF0, 41) != 1)
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-fwrapv" } */
|
||||||
|
|
||||||
|
extern void abort (void);
|
||||||
|
|
||||||
|
int f(int a, int b)
|
||||||
|
{
|
||||||
|
if (a > 0x7FFFFFF0) return 0;
|
||||||
|
if (b > 0x7FFFFFF0) return 0;
|
||||||
|
|
||||||
|
int c = (a - 20) + (b - 20);
|
||||||
|
return c > 0x7FFFFFF0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (f (0x7FFFFFF0, 41) != 1)
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue