aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2005-06-21 12:46:33 -0600
committerJeff Law <law@gcc.gnu.org>2005-06-21 12:46:33 -0600
commit2735e93e53bb4cf96a8f245b40bf29fefe946163 (patch)
tree51811cb1fc3462dd074a020bad55da4671ab8357 /gcc
parenta6b46ba2c84f81e70811e13581c99350cdc76400 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp15.c34
-rw-r--r--gcc/tree-vrp.c29
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