diff options
author | Jeff Law <law@redhat.com> | 2005-06-21 12:46:33 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2005-06-21 12:46:33 -0600 |
commit | 2735e93e53bb4cf96a8f245b40bf29fefe946163 (patch) | |
tree | 51811cb1fc3462dd074a020bad55da4671ab8357 /gcc | |
parent | a6b46ba2c84f81e70811e13581c99350cdc76400 (diff) | |
download | gcc-2735e93e53bb4cf96a8f245b40bf29fefe946163.zip gcc-2735e93e53bb4cf96a8f245b40bf29fefe946163.tar.gz gcc-2735e93e53bb4cf96a8f245b40bf29fefe946163.tar.bz2 |
tree-vrp.c (extract_range_from_unary_expr): Handle type conversions better.
* tree-vrp.c (extract_range_from_unary_expr): Handle type
conversions better.
* gcc.dg/tree-ssa/vrp15.c: New test.
From-SVN: r101232
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp15.c | 34 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 29 |
4 files changed, 72 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0cc4cf9..591d59d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-06-21 Jeff Law <law@redhat.com> + + * tree-vrp.c (extract_range_from_unary_expr): Handle type + conversions better. + 2005-06-21 Dorit Nuzman <dorit@il.ibm.com> * genopinit.c (vec_shl_optab, vec_shr_optab): Initialize new optabs. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a526fb1..b8c7927 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-06-21 Jeff Law <law@redhat.com> + + * gcc.dg/tree-ssa/vrp15.c: New test. + 2005-06-21 Dorit Nuzman <dorit@il.ibm.com> * lib/target-supports.exp (check_effective_target_vect_reduction): diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp15.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp15.c new file mode 100644 index 0000000..035d38f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp15.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp" } */ + + +extern void abort (void) __attribute__ ((__noreturn__)); +union tree_node; +typedef union tree_node *tree; +enum tree_code +{ + ERROR_MARK, + COND_EXPR = 42, +}; +extern const unsigned char tree_code_length[]; +struct tree_common +{ + enum tree_code code:8; +}; +union tree_node +{ + struct tree_common common; +}; +void +blah (tree t) +{ + if (t->common.code != COND_EXPR) + abort (); + if (1 >= tree_code_length[t->common.code]) + abort (); + +} + +/* { dg-final { scan-tree-dump-times "tree_code_length.42." 1 "vrp" } } */ +/* { dg-final { cleanup-tree-dump "vrp" } } */ + diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 217ecc3..81b0c0a 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1286,6 +1286,35 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) tree inner_type = TREE_TYPE (op0); tree outer_type = TREE_TYPE (expr); + /* If VR0 represents a simple range, then try to convert + the min and max values for the range to the same type + as OUTER_TYPE. If the results compare equal to VR0's + min and max values and the new min is still less than + or equal to the new max, then we can safely use the newly + computed range for EXPR. This allows us to compute + accurate ranges through many casts. */ + if (vr0.type == VR_RANGE) + { + tree new_min, new_max; + + /* Convert VR0's min/max to OUTER_TYPE. */ + new_min = fold_convert (outer_type, vr0.min); + new_max = fold_convert (outer_type, vr0.max); + + /* Verify the new min/max values are gimple values and + that they compare equal to VR0's min/max values. */ + if (is_gimple_val (new_min) + && is_gimple_val (new_max) + && tree_int_cst_equal (new_min, vr0.min) + && tree_int_cst_equal (new_max, vr0.max) + && compare_values (new_min, new_max) <= 0 + && compare_values (new_min, new_max) >= -2) + { + set_value_range (vr, VR_RANGE, new_min, new_max, vr->equiv); + return; + } + } + /* When converting types of different sizes, set the result to VARYING. Things like sign extensions and precision loss may change the range. For instance, if x_3 is of type 'long long |