tree-vrp.c (extract_range_from_unary_expr_1): New function, split out from ...
authorRichard Guenther <rguenther@suse.de>
Mon, 8 Aug 2011 11:40:08 +0000 (11:40 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 8 Aug 2011 11:40:08 +0000 (11:40 +0000)
2011-08-08  Richard Guenther  <rguenther@suse.de>

* tree-vrp.c (extract_range_from_unary_expr_1): New function,
split out from ...
(extract_range_from_unary_expr): ... here.  Handle BIT_NOT_EXPR
by composition.

From-SVN: r177558

gcc/ChangeLog
gcc/tree-vrp.c

index 227202ce36428456b14628626a2efb17cac12bef..3e0391e26b3cb6af0bede05156c2d9b3a3207a9b 100644 (file)
@@ -1,3 +1,10 @@
+2011-08-08  Richard Guenther  <rguenther@suse.de>
+
+       * tree-vrp.c (extract_range_from_unary_expr_1): New function,
+       split out from ...
+       (extract_range_from_unary_expr): ... here.  Handle BIT_NOT_EXPR
+       by composition.
+
 2011-08-08  Mikael Pettersson  <mikpe@it.uu.se>
 
        PR tree-optimization/50005
index eb6fc9dcc8c9a09402d7fcff1a33cc2ed984f54d..2eeb3790984ea39e498b624c275cdcd5daa20d23 100644 (file)
@@ -2805,60 +2805,40 @@ extract_range_from_binary_expr (value_range_t *vr,
   extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1);
 }
 
-/* Extract range information from a unary expression EXPR based on
-   the range of its operand and the expression code.  */
+/* Extract range information from a unary operation CODE based on
+   the range of its operand *VR0 with type OP0_TYPE with resulting type TYPE.
+   The The resulting range is stored in *VR.  */
 
 static void
-extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
-                              tree type, tree op0)
+extract_range_from_unary_expr_1 (value_range_t *vr,
+                                enum tree_code code, tree type,
+                                value_range_t *vr0_, tree op0_type)
 {
+  value_range_t vr0 = *vr0_;
   tree min, max;
   int cmp;
-  value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+
+  /* If VR0 is UNDEFINED, so is the result.  */
+  if (vr0.type == VR_UNDEFINED)
+    {
+      set_value_range_to_undefined (vr);
+      return;
+    }
 
   /* Refuse to operate on certain unary expressions for which we
      cannot easily determine a resulting range.  */
   if (code == FIX_TRUNC_EXPR
       || code == FLOAT_EXPR
-      || code == BIT_NOT_EXPR
       || code == CONJ_EXPR)
     {
-      /* We can still do constant propagation here.  */
-      if ((op0 = op_with_constant_singleton_value_range (op0)) != NULL_TREE)
-       {
-         tree tem = fold_unary (code, type, op0);
-         if (tem
-             && is_gimple_min_invariant (tem)
-             && !is_overflow_infinity (tem))
-           {
-             set_value_range (vr, VR_RANGE, tem, tem, NULL);
-             return;
-           }
-       }
       set_value_range_to_varying (vr);
       return;
     }
 
-  /* Get value ranges for the operand.  For constant operands, create
-     a new value range with the operand to simplify processing.  */
-  if (TREE_CODE (op0) == SSA_NAME)
-    vr0 = *(get_value_range (op0));
-  else if (is_gimple_min_invariant (op0))
-    set_value_range_to_value (&vr0, op0, NULL);
-  else
-    set_value_range_to_varying (&vr0);
-
-  /* If VR0 is UNDEFINED, so is the result.  */
-  if (vr0.type == VR_UNDEFINED)
-    {
-      set_value_range_to_undefined (vr);
-      return;
-    }
-
   /* Refuse to operate on symbolic ranges, or if neither operand is
      a pointer or integral type.  */
-  if ((!INTEGRAL_TYPE_P (TREE_TYPE (op0))
-       && !POINTER_TYPE_P (TREE_TYPE (op0)))
+  if ((!INTEGRAL_TYPE_P (op0_type)
+       && !POINTER_TYPE_P (op0_type))
       || (vr0.type != VR_VARYING
          && symbolic_range_p (&vr0)))
     {
@@ -2868,29 +2848,23 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
 
   /* If the expression involves pointers, we are only interested in
      determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]).  */
-  if (POINTER_TYPE_P (type) || POINTER_TYPE_P (TREE_TYPE (op0)))
+  if (POINTER_TYPE_P (type) || POINTER_TYPE_P (op0_type))
     {
-      bool sop;
-
-      sop = false;
-      if (range_is_nonnull (&vr0)
-         || (tree_unary_nonzero_warnv_p (code, type, op0, &sop)
-             && !sop))
+      if (range_is_nonnull (&vr0))
        set_value_range_to_nonnull (vr, type);
       else if (range_is_null (&vr0))
        set_value_range_to_null (vr, type);
       else
        set_value_range_to_varying (vr);
-
       return;
     }
 
   /* Handle unary expressions on integer ranges.  */
   if (CONVERT_EXPR_CODE_P (code)
       && INTEGRAL_TYPE_P (type)
-      && INTEGRAL_TYPE_P (TREE_TYPE (op0)))
+      && INTEGRAL_TYPE_P (op0_type))
     {
-      tree inner_type = TREE_TYPE (op0);
+      tree inner_type = op0_type;
       tree outer_type = type;
 
       /* If VR0 is varying and we increase the type precision, assume
@@ -3146,6 +3120,16 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
            }
        }
     }
+  else if (code == BIT_NOT_EXPR)
+    {
+      /* ~X is simply -1 - X, so re-use existing code that also handles
+         anti-ranges fine.  */
+      value_range_t minusone = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+      set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL);
+      extract_range_from_binary_expr_1 (vr, MINUS_EXPR,
+                                       type, &minusone, &vr0);
+      return;
+    }
   else
     {
       /* Otherwise, operate on each end of the range.  */
@@ -3212,6 +3196,29 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
 }
 
 
+/* Extract range information from a unary expression CODE OP0 based on
+   the range of its operand with resulting type TYPE.
+   The resulting range is stored in *VR.  */
+
+static void
+extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
+                              tree type, tree op0)
+{
+  value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+
+  /* Get value ranges for the operand.  For constant operands, create
+     a new value range with the operand to simplify processing.  */
+  if (TREE_CODE (op0) == SSA_NAME)
+    vr0 = *(get_value_range (op0));
+  else if (is_gimple_min_invariant (op0))
+    set_value_range_to_value (&vr0, op0, NULL);
+  else
+    set_value_range_to_varying (&vr0);
+
+  extract_range_from_unary_expr_1 (vr, code, type, &vr0, TREE_TYPE (op0));
+}
+
+
 /* Extract range information from a conditional expression EXPR based on
    the ranges of each of its operands and the expression code.  */