OSDN Git Service

* config/rs6000/rs6000.c (build_opaque_vector_type): Set
[pf3gnuchains/gcc-fork.git] / gcc / fold-const.c
index b4645ca..aaae9d6 100644 (file)
@@ -1,6 +1,6 @@
 /* Fold a constant sub-tree into a single node for C-compiler
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -3033,8 +3033,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 
   /* If both types don't have the same signedness, then we can't consider
      them equal.  We must check this before the STRIP_NOPS calls
-     because they may change the signedness of the arguments.  */
-  if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1)))
+     because they may change the signedness of the arguments.  As pointers
+     strictly don't have a signedness, require either two pointers or
+     two non-pointers as well.  */
+  if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1))
+      || POINTER_TYPE_P (TREE_TYPE (arg0)) != POINTER_TYPE_P (TREE_TYPE (arg1)))
     return 0;
 
   /* If both types don't have the same precision, then it is not safe
@@ -3165,8 +3168,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
       /* Two conversions are equal only if signedness and modes match.  */
       switch (TREE_CODE (arg0))
         {
-        case NOP_EXPR:
-        case CONVERT_EXPR:
+       CASE_CONVERT:
         case FIX_TRUNC_EXPR:
          if (TYPE_UNSIGNED (TREE_TYPE (arg0))
              != TYPE_UNSIGNED (TREE_TYPE (arg1)))
@@ -3256,6 +3258,9 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
                  && operand_equal_p (TREE_OPERAND (arg0, 1),
                                      TREE_OPERAND (arg1, 0), flags));
 
+       case COND_EXPR:
+         return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
+         
        default:
          return 0;
        }
@@ -3901,8 +3906,7 @@ decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize,
   /* We are interested in the bare arrangement of bits, so strip everything
      that doesn't affect the machine mode.  However, record the type of the
      outermost expression if it may matter below.  */
-  if (TREE_CODE (exp) == NOP_EXPR
-      || TREE_CODE (exp) == CONVERT_EXPR
+  if (CONVERT_EXPR_P (exp)
       || TREE_CODE (exp) == NON_LVALUE_EXPR)
     outer_type = TREE_TYPE (exp);
   STRIP_NOPS (exp);
@@ -4313,7 +4317,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
          exp = arg0;
          continue;
 
-       case NOP_EXPR:  case NON_LVALUE_EXPR:  case CONVERT_EXPR:
+       CASE_CONVERT: case NON_LVALUE_EXPR:
          if (TYPE_PRECISION (arg0_type) > TYPE_PRECISION (exp_type))
            break;
 
@@ -5725,24 +5729,24 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
                            fold_convert (ctype, c), 0);
       break;
 
-    case CONVERT_EXPR:  case NON_LVALUE_EXPR:  case NOP_EXPR:
+    CASE_CONVERT: case NON_LVALUE_EXPR:
       /* If op0 is an expression ...  */
       if ((COMPARISON_CLASS_P (op0)
           || UNARY_CLASS_P (op0)
           || BINARY_CLASS_P (op0)
           || VL_EXP_CLASS_P (op0)
           || EXPRESSION_CLASS_P (op0))
-         /* ... and is unsigned, and its type is smaller than ctype,
-            then we cannot pass through as widening.  */
-         && ((TYPE_UNSIGNED (TREE_TYPE (op0))
+         /* ... and has wrapping overflow, and its type is smaller
+            than ctype, then we cannot pass through as widening.  */
+         && ((TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0))
               && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
                     && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
-              && (GET_MODE_SIZE (TYPE_MODE (ctype))
-                  > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
+              && (TYPE_PRECISION (ctype)
+                  > TYPE_PRECISION (TREE_TYPE (op0))))
              /* ... or this is a truncation (t is narrower than op0),
                 then we cannot pass through this narrowing.  */
-             || (GET_MODE_SIZE (TYPE_MODE (type))
-                 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
+             || (TYPE_PRECISION (type)
+                 < TYPE_PRECISION (TREE_TYPE (op0)))
              /* ... or signedness changes for division or modulus,
                 then we cannot pass through this conversion.  */
              || (code != MULT_EXPR
@@ -6801,8 +6805,7 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
   tree arg0_inner;
   tree inner_type, outer_type;
 
-  if (TREE_CODE (arg0) != NOP_EXPR
-      && TREE_CODE (arg0) != CONVERT_EXPR)
+  if (!CONVERT_EXPR_P (arg0))
     return NULL_TREE;
 
   outer_type = TREE_TYPE (arg0);
@@ -6827,12 +6830,12 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
     return NULL_TREE;
 
   if (TREE_CODE (arg1) != INTEGER_CST
-      && !((TREE_CODE (arg1) == NOP_EXPR
-           || TREE_CODE (arg1) == CONVERT_EXPR)
+      && !(CONVERT_EXPR_P (arg1)
           && TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
     return NULL_TREE;
 
-  if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
+  if ((TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
+       || POINTER_TYPE_P (inner_type) != POINTER_TYPE_P (outer_type))
       && code != NE_EXPR
       && code != EQ_EXPR)
     return NULL_TREE;
@@ -7723,9 +7726,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
        return fold_convert (type, op0);
       return NULL_TREE;
 
-    case NOP_EXPR:
+    CASE_CONVERT:
     case FLOAT_EXPR:
-    case CONVERT_EXPR:
     case FIX_TRUNC_EXPR:
       if (TREE_TYPE (op0) == type)
        return op0;
@@ -7737,8 +7739,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
                            TREE_OPERAND (op0, 1));
 
       /* Handle cases of two conversions in a row.  */
-      if (TREE_CODE (op0) == NOP_EXPR
-         || TREE_CODE (op0) == CONVERT_EXPR)
+      if (CONVERT_EXPR_P (op0))
        {
          tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0));
          tree inter_type = TREE_TYPE (op0);
@@ -7865,9 +7866,11 @@ fold_unary (enum tree_code code, tree type, tree op0)
 
       /* Convert (T)(x & c) into (T)x & (T)c, if c is an integer
         constants (if x has signed type, the sign bit cannot be set
-        in c).  This folds extension into the BIT_AND_EXPR.  */
-      if (INTEGRAL_TYPE_P (type)
-         && TREE_CODE (type) != BOOLEAN_TYPE
+        in c).  This folds extension into the BIT_AND_EXPR.
+        ??? We don't do it for BOOLEAN_TYPE or ENUMERAL_TYPE because they
+        very likely don't have maximal range for their precision and this
+        transformation effectively doesn't preserve non-maximal ranges.  */
+      if (TREE_CODE (type) == INTEGER_TYPE
          && TREE_CODE (op0) == BIT_AND_EXPR
          && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
        {
@@ -7933,8 +7936,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
       if (INTEGRAL_TYPE_P (type)
          && TREE_CODE (op0) == BIT_NOT_EXPR
          && INTEGRAL_TYPE_P (TREE_TYPE (op0))
-         && (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
-             || TREE_CODE (TREE_OPERAND (op0, 0)) == CONVERT_EXPR)
+         && CONVERT_EXPR_P (TREE_OPERAND (op0, 0))
          && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0)))
        {
          tem = TREE_OPERAND (TREE_OPERAND (op0, 0), 0);
@@ -7990,8 +7992,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
        return fold_convert (type, op0);
 
       /* Strip inner integral conversions that do not change the precision.  */
-      if ((TREE_CODE (op0) == NOP_EXPR
-          || TREE_CODE (op0) == CONVERT_EXPR)
+      if (CONVERT_EXPR_P (op0)
          && (INTEGRAL_TYPE_P (TREE_TYPE (op0))
              || POINTER_TYPE_P (TREE_TYPE (op0)))
          && (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
@@ -8908,8 +8909,7 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
     }
 
   if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
-      && (TREE_CODE (arg0) == NOP_EXPR
-         || TREE_CODE (arg0) == CONVERT_EXPR))
+      && CONVERT_EXPR_P (arg0))
     {
       /* If we are widening one operand of an integer comparison,
         see if the other operand is similarly being widened.  Perhaps we
@@ -9261,7 +9261,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
      safe for every expression, except for a comparison expression
      because its signedness is derived from its operands.  So, in
      the latter case, only strip conversions that don't change the
-     signedness.
+     signedness.  MIN_EXPR/MAX_EXPR also need signedness of arguments
+     preserved.
 
      Note that this is done as an internal manipulation within the
      constant folder, in order to find the simplest representation
@@ -9269,7 +9270,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
      cases, the appropriate type conversions should be put back in
      the tree that will get out of the constant folder.  */
 
-  if (kind == tcc_comparison)
+  if (kind == tcc_comparison || code == MIN_EXPR || code == MAX_EXPR)
     {
       STRIP_SIGN_NOPS (arg0);
       STRIP_SIGN_NOPS (arg1);
@@ -11388,7 +11389,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
        {
          if (strict_overflow_p)
            fold_overflow_warning (("assuming signed overflow does not occur "
-                                   "when simplifying modulos"),
+                                   "when simplifying modulus"),
                                   WARN_STRICT_OVERFLOW_MISC);
          return fold_convert (type, tem);
        }
@@ -12662,8 +12663,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
 
       if ((code == LT_EXPR || code == GE_EXPR)
          && TYPE_UNSIGNED (TREE_TYPE (arg0))
-         && (TREE_CODE (arg1) == NOP_EXPR
-             || TREE_CODE (arg1) == CONVERT_EXPR)
+         && CONVERT_EXPR_P (arg1)
          && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
          && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
        return
@@ -14074,11 +14074,6 @@ tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
 
   switch (TREE_CODE (t))
     {
-    case SSA_NAME:
-      /* Query VRP to see if it has recorded any information about
-        the range of this object.  */
-      return ssa_name_nonnegative_p (t);
-
     case INTEGER_CST:
       return tree_int_cst_sgn (t) >= 0;
 
@@ -14563,11 +14558,6 @@ tree_single_nonzero_warnv_p (tree t, bool *strict_overflow_p)
   bool sub_strict_overflow_p;
   switch (TREE_CODE (t))
     {
-    case SSA_NAME:
-      /* Query VRP to see if it has recorded any information about
-        the range of this object.  */
-      return ssa_name_nonzero_p (t);
-
     case INTEGER_CST:
       return !integer_zerop (t);
 
@@ -14768,7 +14758,7 @@ fold_read_from_constant_string (tree exp)
             with constant folding.  (E.g. suppose the lower bound is 1,
             and its mode is QI.  Without the conversion,l (ARRAY
             +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
-            +INDEX), which becomes (ARRAY+255+INDEX).  Opps!)  */
+            +INDEX), which becomes (ARRAY+255+INDEX).  Oops!)  */
          if (! integer_zerop (low_bound))
            index = size_diffop (index, fold_convert (sizetype, low_bound));