re PR middle-end/31115 (libstdc++ 22_locale/num_get/get/char/2.cc 27_io/basic_ostream/inserters_arithmetic/char/6.cc)

2007-03-11  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/31115
	* tree-vrp.c (extract_range_from_binary_expr): Make sure
	the shift count is positive and non-anti-range for RSHIFT_EXPR.
	A shift count of zero is not special as with *_DIV_EXPR.
	(vrp_int_const_binop): Handle RSHIFT_EXPR for determining overflow
	direction.

	* gcc.dg/torture/pr31115.c: New testcase.

From-SVN: r122821
This commit is contained in:
Richard Guenther 2007-03-11 16:08:35 +00:00 committed by Richard Biener
parent d7419dec45
commit 13338552e2
4 changed files with 55 additions and 1 deletions

View File

@ -1,3 +1,12 @@
2007-03-11 Richard Guenther <rguenther@suse.de>
PR tree-optimization/31115
* tree-vrp.c (extract_range_from_binary_expr): Make sure
the shift count is positive and non-anti-range for RSHIFT_EXPR.
A shift count of zero is not special as with *_DIV_EXPR.
(vrp_int_const_binop): Handle RSHIFT_EXPR for determining overflow
direction.
2007-03-11 Ian Lance Taylor <iant@google.com>
* tree-vrp.c (vrp_int_const_binop): Handle PLUS_EXPR and

View File

@ -1,3 +1,8 @@
2007-03-11 Richard Guenther <rguenther@suse.de>
PR tree-optimization/31115
* gcc.dg/torture/pr31115.c: New testcase.
2007-03-11 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/29925

View File

@ -0,0 +1,22 @@
/* { dg-do run } */
extern void exit(int);
extern void abort();
void foo (int e1)
{
if (e1 < 0)
{
e1 = -e1;
if (e1 >>= 4)
{
if (e1 >= 1 << 5)
exit(0);
}
}
}
int main()
{
foo(-(1<<9));
abort();
}

View File

@ -1569,6 +1569,12 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
&& (sgn1 >= 0
? !is_positive_overflow_infinity (val2)
: is_negative_overflow_infinity (val2)))
/* We only get in here with positive shift count, so the
overflow direction is the same as the sign of val1.
Actually rshift does not overflow at all, but we only
handle the case of shifting overflowed -INF and +INF. */
|| (code == RSHIFT_EXPR
&& sgn1 >= 0)
/* For division, the only case is -INF / -1 = +INF. */
|| code == TRUNC_DIV_EXPR
|| code == FLOOR_DIV_EXPR
@ -1802,6 +1808,17 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
return;
}
/* If we have a RSHIFT_EXPR with a possibly negative shift
count or an anti-range shift count drop to VR_VARYING.
We currently cannot handle the overflow cases correctly. */
if (code == RSHIFT_EXPR
&& (vr1.type == VR_ANTI_RANGE
|| !vrp_expr_computes_nonnegative (op1, &sop)))
{
set_value_range_to_varying (vr);
return;
}
/* Multiplications and divisions are a bit tricky to handle,
depending on the mix of signs we have in the two ranges, we
need to operate on different values to get the minimum and
@ -1816,7 +1833,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
the new range. */
/* Divisions by zero result in a VARYING value. */
if (code != MULT_EXPR
if ((code != MULT_EXPR
&& code != RSHIFT_EXPR)
&& (vr0.type == VR_ANTI_RANGE || range_includes_zero_p (&vr1)))
{
set_value_range_to_varying (vr);