re PR tree-optimization/50729 (Silent code gen fault: Value range propagation seems to propagate values across narrowing/widening)

2011-10-17  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/50729
	* tree-vrp.c (extract_range_from_unary_expr_1): Remove
	redundant test.
	(simplify_conversion_using_ranges): Properly test the
	intermediate result.

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

From-SVN: r180087
This commit is contained in:
Richard Guenther 2011-10-17 12:22:54 +00:00 committed by Richard Biener
parent b9bd6f7438
commit 7d5a0f1b4e
4 changed files with 47 additions and 12 deletions

View File

@ -1,3 +1,11 @@
2011-10-17 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50729
* tree-vrp.c (extract_range_from_unary_expr_1): Remove
redundant test.
(simplify_conversion_using_ranges): Properly test the
intermediate result.
2011-10-15 Tom Tromey <tromey@redhat.com>
Dodji Seketeli <dodji@redhat.com>

View File

@ -1,3 +1,8 @@
2011-10-17 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50729
* gcc.dg/torture/pr50729.c: New testcase.
2011-10-15 Tom Tromey <tromey@redhat.com>
Dodji Seketeli <dodji@redhat.com>

View File

@ -0,0 +1,20 @@
/* { dg-do run } */
/* { dg-require-effective-target int32plus } */
extern void abort (void);
unsigned short __attribute__((noinline))
foo (int i)
{
if (i >= 0
&& i <= 0x400000)
return (unsigned short)(signed char)i;
return i;
}
int main()
{
int i;
for (i = 0; i < 0xffff; ++i)
if (foo(i) != (unsigned short)(signed char) i)
abort ();
return 0;
}

View File

@ -2913,15 +2913,10 @@ extract_range_from_unary_expr_1 (value_range_t *vr,
determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]). */
if (POINTER_TYPE_P (type))
{
if (CONVERT_EXPR_CODE_P (code))
{
if (range_is_nonnull (&vr0))
set_value_range_to_nonnull (vr, type);
else if (range_is_null (&vr0))
set_value_range_to_null (vr, type);
else
set_value_range_to_varying (vr);
}
if (range_is_nonnull (&vr0))
set_value_range_to_nonnull (vr, type);
else if (range_is_null (&vr0))
set_value_range_to_null (vr, type);
else
set_value_range_to_varying (vr);
return;
@ -7288,10 +7283,17 @@ simplify_conversion_using_ranges (gimple stmt)
TYPE_UNSIGNED (TREE_TYPE (middleop)));
middlemax = double_int_ext (innermax, TYPE_PRECISION (TREE_TYPE (middleop)),
TYPE_UNSIGNED (TREE_TYPE (middleop)));
/* If the middle values do not represent a proper range fail. */
if (double_int_cmp (middlemin, middlemax,
TYPE_UNSIGNED (TREE_TYPE (middleop))) > 0)
/* If the middle values are not equal to the original values fail.
But only if the inner cast truncates (thus we ignore differences
in extension to handle the case going from a range to an anti-range
and back). */
if ((TYPE_PRECISION (TREE_TYPE (innerop))
> TYPE_PRECISION (TREE_TYPE (middleop)))
&& (!double_int_equal_p (innermin, middlemin)
|| !double_int_equal_p (innermax, middlemax)))
return false;
/* Require that the final conversion applied to both the original
and the intermediate range produces the same result. */
if (!double_int_equal_p (double_int_ext (middlemin,
TYPE_PRECISION (finaltype),
TYPE_UNSIGNED (finaltype)),