Commit 567fb660 by Kazu Hirata Committed by Kazu Hirata

re PR tree-optimization/22026 (ACATS FAIL C45331A fixed point wrong code (VRP related))

gcc/
	PR tree-optimization/22026
	* tree-vrp.c (extract_range_from_binary_expr): Drop to
	VR_VARYING if a binary expression involving VR_ANTI_RANGE is
	PLUS_EXPR, MINUS_EXPR, or unsigned MULT_EXPR.

testsuite/
	PR tree-optimization/22026
	* gcc.dg/tree-ssa/pr22026.c: New.

From-SVN: r101328
parent e4ca1c95
2005-06-25 Kazu Hirata <kazu@codesourcery.com> 2005-06-26 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/22026
* tree-vrp.c (extract_range_from_binary_expr): Drop to
VR_VARYING if a binary expression involving VR_ANTI_RANGE is
PLUS_EXPR, MINUS_EXPR, or unsigned MULT_EXPR.
2005-06-26 Kazu Hirata <kazu@codesourcery.com>
* Makefile.in (OBJS-common): Remove duplicate object file * Makefile.in (OBJS-common): Remove duplicate object file
names. names.
......
2005-06-26 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/22026
* gcc.dg/tree-ssa/pr22026.c: New.
2005-06-25 Thomas Koenig <Thomas.Koenig@online.de> 2005-06-25 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/21144 PR libfortran/21144
......
/* PR tree-optimization/22026
VRP used think that ~[0,0] + ~[0,0] = ~[0,0], which is wrong. The
same applies to subtraction and unsigned multiplication. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vrp" } */
int
plus (int x, int y)
{
if (x != 0)
if (y != 0)
{
int z = x + y;
if (z != 0)
return 1;
}
return 0;
}
int
minus (int x, int y)
{
if (x != 0)
if (y != 0)
{
int z = x - y;
if (z != 0)
return 1;
}
return 0;
}
int
mult (unsigned x, unsigned y)
{
if (x != 0)
if (y != 0)
{
unsigned z = x * y;
if (z != 0)
return 1;
}
return 0;
}
/* None of the predicates can be folded in these functions. */
/* { dg-final { scan-tree-dump-times "Folding predicate" 0 "vrp" } } */
/* { dg-final { cleanup-tree-dump "vrp" } } */
...@@ -1107,6 +1107,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) ...@@ -1107,6 +1107,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
|| code == MIN_EXPR || code == MIN_EXPR
|| code == MAX_EXPR) || code == MAX_EXPR)
{ {
/* If we have a PLUS_EXPR with two VR_ANTI_RANGEs, drop to
VR_VARYING. It would take more effort to compute a precise
range for such a case. For example, if we have op0 == 1 and
op1 == -1 with their ranges both being ~[0,0], we would have
op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
Note that we are guaranteed to have vr0.type == vr1.type at
this point. */
if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
{
set_value_range_to_varying (vr);
return;
}
/* For operations that make the resulting range directly /* For operations that make the resulting range directly
proportional to the original ranges, apply the operation to proportional to the original ranges, apply the operation to
the same end of each range. */ the same end of each range. */
...@@ -1123,6 +1136,22 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) ...@@ -1123,6 +1136,22 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
tree val[4]; tree val[4];
size_t i; size_t i;
/* If we have an unsigned MULT_EXPR with two VR_ANTI_RANGEs,
drop to VR_VARYING. It would take more effort to compute a
precise range for such a case. For example, if we have
op0 == 65536 and op1 == 65536 with their ranges both being
~[0,0] on a 32-bit machine, we would have op0 * op1 == 0, so
we cannot claim that the product is in ~[0,0]. Note that we
are guaranteed to have vr0.type == vr1.type at this
point. */
if (code == MULT_EXPR
&& vr0.type == VR_ANTI_RANGE
&& (flag_wrapv || TYPE_UNSIGNED (TREE_TYPE (op0))))
{
set_value_range_to_varying (vr);
return;
}
/* Multiplications and divisions are a bit tricky to handle, /* Multiplications and divisions are a bit tricky to handle,
depending on the mix of signs we have in the two ranges, we depending on the mix of signs we have in the two ranges, we
need to operate on different values to get the minimum and need to operate on different values to get the minimum and
...@@ -1188,6 +1217,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) ...@@ -1188,6 +1217,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
} }
else if (code == MINUS_EXPR) else if (code == MINUS_EXPR)
{ {
/* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to
VR_VARYING. It would take more effort to compute a precise
range for such a case. For example, if we have op0 == 1 and
op1 == 1 with their ranges both being ~[0,0], we would have
op0 - op1 == 0, so we cannot claim that the difference is in
~[0,0]. Note that we are guaranteed to have
vr0.type == vr1.type at this point. */
if (vr0.type == VR_ANTI_RANGE)
{
set_value_range_to_varying (vr);
return;
}
/* For MINUS_EXPR, apply the operation to the opposite ends of /* For MINUS_EXPR, apply the operation to the opposite ends of
each range. */ each range. */
min = vrp_int_const_binop (code, vr0.min, vr1.max); min = vrp_int_const_binop (code, vr0.min, vr1.max);
......
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