From b8f8bd676fdaad83fc346061846bc381acc8fde4 Mon Sep 17 00:00:00 2001 From: law Date: Tue, 21 Jun 2005 18:46:33 +0000 Subject: [PATCH] * tree-vrp.c (extract_range_from_unary_expr): Handle type conversions better. * gcc.dg/tree-ssa/vrp15.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101232 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/tree-ssa/vrp15.c | 34 ++++++++++++++++++++++++++++++++++ gcc/tree-vrp.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp15.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0cc4cf9170e..591d59d884d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-06-21 Jeff Law + + * tree-vrp.c (extract_range_from_unary_expr): Handle type + conversions better. + 2005-06-21 Dorit Nuzman * genopinit.c (vec_shl_optab, vec_shr_optab): Initialize new optabs. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a526fb121b4..b8c7927dae0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-06-21 Jeff Law + + * gcc.dg/tree-ssa/vrp15.c: New test. + 2005-06-21 Dorit Nuzman * 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 00000000000..035d38f9f22 --- /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 217ecc30ae2..81b0c0a471e 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 -- 2.11.0