OSDN Git Service

2010-03-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
[pf3gnuchains/gcc-fork.git] / gcc / fold-const.c
index cbdaf86..292b89f 100644 (file)
@@ -326,13 +326,17 @@ add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
   HOST_WIDE_INT h;
 
   l = l1 + l2;
-  h = h1 + h2 + (l < l1);
+  h = (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) h1
+                      + (unsigned HOST_WIDE_INT) h2
+                      + (l < l1));
 
   *lv = l;
   *hv = h;
 
   if (unsigned_p)
-    return (unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1;
+    return ((unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1
+           || (h == h1
+               && l < l1));
   else
     return OVERFLOW_SUM_SIGN (h1, h2, h);
 }
@@ -1125,10 +1129,14 @@ negate_expr_p (tree t)
              && TYPE_OVERFLOW_WRAPS (type));
 
     case FIXED_CST:
-    case REAL_CST:
     case NEGATE_EXPR:
       return true;
 
+    case REAL_CST:
+      /* We want to canonicalize to positive real constants.  Pretend
+         that only negative ones can be easily negated.  */
+      return REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
+
     case COMPLEX_CST:
       return negate_expr_p (TREE_REALPART (t))
             && negate_expr_p (TREE_IMAGPART (t));
@@ -1962,12 +1970,10 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
          break;
 
        case MULT_EXPR:
-#ifdef HAVE_mpc
          if (COMPLEX_FLOAT_TYPE_P (type))
            return do_mpc_arg2 (arg1, arg2, type,
                                /* do_nonfinite= */ folding_initializer,
                                mpc_mul);
-#endif
 
          real = const_binop (MINUS_EXPR,
                              const_binop (MULT_EXPR, r1, r2, notrunc),
@@ -1980,14 +1986,11 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
          break;
 
        case RDIV_EXPR:
-#ifdef HAVE_mpc
          if (COMPLEX_FLOAT_TYPE_P (type))
            return do_mpc_arg2 (arg1, arg2, type,
                                 /* do_nonfinite= */ folding_initializer,
                                mpc_div);
          /* Fallthru ... */
-#endif
-
        case TRUNC_DIV_EXPR:
        case CEIL_DIV_EXPR:
        case FLOOR_DIV_EXPR:
@@ -3162,7 +3165,9 @@ int
 operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 {
   /* If either is ERROR_MARK, they aren't equal.  */
-  if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
+  if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK
+      || TREE_TYPE (arg0) == error_mark_node
+      || TREE_TYPE (arg1) == error_mark_node)
     return 0;
 
   /* Check equality of integer constants before bailing out due to
@@ -8947,6 +8952,19 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
        }
       return NULL_TREE;
 
+    case INDIRECT_REF:
+      /* Fold *&X to X if X is an lvalue.  */
+      if (TREE_CODE (op0) == ADDR_EXPR)
+       {
+         tree op00 = TREE_OPERAND (op0, 0);
+         if ((TREE_CODE (op00) == VAR_DECL
+              || TREE_CODE (op00) == PARM_DECL
+              || TREE_CODE (op00) == RESULT_DECL)
+             && !TREE_READONLY (op00))
+           return op00;
+       }
+      return NULL_TREE;
+
     default:
       return NULL_TREE;
     } /* switch (code) */