mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-17 01:04:11 +08:00
tree-vrp.c (extract_range_from_assert): Refine the result range if the variable referenced by the ASSERT_EXPR has a...
* tree-vrp.c (extract_range_from_assert): Refine the result range if the variable referenced by the ASSERT_EXPR has a range and either the tentative result range or the previous range is a VR_ANTI_RANGE. * gcc.dg/tree-ssa/vrp25.c: New test. From-SVN: r109968
This commit is contained in:
parent
2e6f91e35a
commit
307d19feb1
@ -1,3 +1,10 @@
|
||||
2006-01-19 Jeff Law <law@redhat.com>
|
||||
|
||||
* tree-vrp.c (extract_range_from_assert): Refine the result range
|
||||
if the variable referenced by the ASSERT_EXPR has a range and
|
||||
either the tentative result range or the previous range is a
|
||||
VR_ANTI_RANGE.
|
||||
|
||||
2006-01-19 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* c-decl.c (add_flexible_array_elts_to_size): Simplify vector accesses.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2006-01-18 Jeff Law <law@redhat.com>
|
||||
|
||||
* gcc.dg/tree-ssa/vrp25.c: New test.
|
||||
|
||||
2006-01-19 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* gcc.dg/pr25805.c: Fix misapplied patch.
|
||||
|
52
gcc/testsuite/gcc.dg/tree-ssa/vrp25.c
Normal file
52
gcc/testsuite/gcc.dg/tree-ssa/vrp25.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-vrp-details" } */
|
||||
|
||||
extern void abort ();
|
||||
int tree_code_length[100];
|
||||
|
||||
blah (int code1)
|
||||
{
|
||||
unsigned char D18670;
|
||||
|
||||
if (code1 != 53) goto L0; else goto L1;
|
||||
|
||||
L0:
|
||||
abort ();
|
||||
|
||||
L1:
|
||||
D18670 = tree_code_length[53];
|
||||
if (D18670 <= 1) goto L2; else goto L3;
|
||||
|
||||
L2:
|
||||
abort ();
|
||||
|
||||
L3:
|
||||
if (D18670 == 2) goto L4; else goto L5;
|
||||
|
||||
L4:
|
||||
abort ();
|
||||
|
||||
L5:
|
||||
arf ();
|
||||
if (code1 != 53) goto L6; else goto L7;
|
||||
|
||||
L6:
|
||||
abort ();
|
||||
|
||||
L7:
|
||||
if (D18670 <= 2) goto L8; else goto L9;
|
||||
|
||||
L8:
|
||||
abort ();
|
||||
|
||||
L9:
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* The second test of (code1 != 53) and the test (D18670 <= 2) are
|
||||
both totally subsumed by earlier tests and thus should be folded
|
||||
away using VRP. */
|
||||
/* { dg-final { scan-tree-dump-times "Folding predicate" 2 "vrp" } } */
|
||||
/* { dg-final { cleanup-tree-dump "vrp" } } */
|
||||
|
@ -1048,6 +1048,96 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
|
||||
if (compare_values (var_vr->min, vr_p->min) == 0
|
||||
&& compare_values (var_vr->max, vr_p->max) == 0)
|
||||
set_value_range_to_varying (vr_p);
|
||||
else
|
||||
{
|
||||
tree min, max, anti_min, anti_max, real_min, real_max;
|
||||
|
||||
/* We want to compute the logical AND of the two ranges;
|
||||
there are three cases to consider.
|
||||
|
||||
|
||||
1. The VR_ANTI_RANGE range is competely within the
|
||||
VR_RANGE and the endpoints of the ranges are
|
||||
different. In that case the resulting range
|
||||
should be the VR_ANTI_RANGE.
|
||||
|
||||
2. The VR_ANTI_RANGE is completely disjoint from
|
||||
the VR_RANGE. In this case the resulting range
|
||||
should be the VR_RANGE.
|
||||
|
||||
3. There is some overlap between the VR_ANTI_RANGE
|
||||
and the VR_RANGE.
|
||||
|
||||
3a. If the high limit of the VR_ANTI_RANGE resides
|
||||
within the VR_RANGE, then the result is a new
|
||||
VR_RANGE starting at the high limit of the
|
||||
the VR_ANTI_RANGE + 1 and extending to the
|
||||
high limit of the original VR_RANGE.
|
||||
|
||||
3b. If the low limit of the VR_ANTI_RANGE resides
|
||||
within the VR_RANGE, then the result is a new
|
||||
VR_RANGE starting at the low limit of the original
|
||||
VR_RANGE and extending to the low limit of the
|
||||
VR_ANTI_RANGE - 1. */
|
||||
if (vr_p->type == VR_ANTI_RANGE)
|
||||
{
|
||||
anti_min = vr_p->min;
|
||||
anti_max = vr_p->max;
|
||||
real_min = var_vr->min;
|
||||
real_max = var_vr->max;
|
||||
}
|
||||
else
|
||||
{
|
||||
anti_min = var_vr->min;
|
||||
anti_max = var_vr->max;
|
||||
real_min = vr_p->min;
|
||||
real_max = vr_p->max;
|
||||
}
|
||||
|
||||
|
||||
/* Case 1, VR_ANTI_RANGE completely within VR_RANGE,
|
||||
not including any endpoints. */
|
||||
if (compare_values (anti_max, real_max) == -1
|
||||
&& compare_values (anti_min, real_min) == 1)
|
||||
{
|
||||
set_value_range (vr_p, VR_ANTI_RANGE, anti_min,
|
||||
anti_max, vr_p->equiv);
|
||||
}
|
||||
/* Case 2, VR_ANTI_RANGE completely disjoint from
|
||||
VR_RANGE. */
|
||||
else if (compare_values (anti_min, real_max) == 1
|
||||
|| compare_values (anti_max, real_min) == -1)
|
||||
{
|
||||
set_value_range (vr_p, VR_RANGE, real_min,
|
||||
real_max, vr_p->equiv);
|
||||
}
|
||||
/* Case 3a, the anti-range extends into the low
|
||||
part of the real range. Thus creating a new
|
||||
low for the real reange. */
|
||||
else if ((compare_values (anti_max, real_min) == 1
|
||||
|| compare_values (anti_max, real_min) == 0)
|
||||
&& compare_values (anti_max, real_max) == -1)
|
||||
{
|
||||
min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
|
||||
anti_max,
|
||||
build_int_cst (TREE_TYPE (var_vr->min), 1));
|
||||
max = real_max;
|
||||
set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
|
||||
}
|
||||
/* Case 3b, the anti-range extends into the high
|
||||
part of the real range. Thus creating a new
|
||||
higher for the real reange. */
|
||||
else if (compare_values (anti_min, real_min) == 1
|
||||
&& (compare_values (anti_min, real_max) == -1
|
||||
|| compare_values (anti_min, real_max) == 0))
|
||||
{
|
||||
max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
|
||||
anti_min,
|
||||
build_int_cst (TREE_TYPE (var_vr->min), 1));
|
||||
min = real_min;
|
||||
set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove names from the equivalence set that have ranges
|
||||
|
Loading…
Reference in New Issue
Block a user