OSDN Git Service

* tree-vrp.c (extract_range_from_unary_expr): Handle type
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Jun 2005 18:46:33 +0000 (18:46 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Jun 2005 18:46:33 +0000 (18:46 +0000)
        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
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/vrp15.c [new file with mode: 0644]
gcc/tree-vrp.c

index 0cc4cf9..591d59d 100644 (file)
@@ -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.
index a526fb1..b8c7927 100644 (file)
@@ -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 (file)
index 0000000..035d38f
--- /dev/null
@@ -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" } } */
+
index 217ecc3..81b0c0a 100644 (file)
@@ -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