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:
parent
b9bd6f7438
commit
7d5a0f1b4e
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
20
gcc/testsuite/gcc.dg/torture/pr50729.c
Normal file
20
gcc/testsuite/gcc.dg/torture/pr50729.c
Normal 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;
|
||||
}
|
@ -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)),
|
||||
|
Loading…
Reference in New Issue
Block a user