OSDN Git Service

Add new test - do not warn about (non-)redundant friend declaration.
[pf3gnuchains/gcc-fork.git] / gcc / fold-const.c
index 25fd496..3bedea1 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 Free Software Foundation, Inc.
+   1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "tree.h"
 #include "rtl.h"
+#include "expr.h"
 #include "tm_p.h"
 #include "toplev.h"
 #include "ggc.h"
@@ -100,7 +101,9 @@ static tree strip_compound_expr PARAMS ((tree, tree));
 static int multiple_of_p       PARAMS ((tree, tree, tree));
 static tree constant_boolean_node PARAMS ((int, tree));
 static int count_cond          PARAMS ((tree, int));
-
+static tree fold_binary_op_with_conditional_arg 
+  PARAMS ((enum tree_code, tree, tree, tree, int));
+                                                        
 #ifndef BRANCH_COST
 #define BRANCH_COST 1
 #endif
@@ -324,7 +327,7 @@ mul_double (l1, h1, l2, h2, lv, hv)
   encode (arg1, l1, h1);
   encode (arg2, l2, h2);
 
-  bzero ((char *) prod, sizeof prod);
+  memset ((char *) prod, 0, sizeof prod);
 
   for (i = 0; i < 4; i++)
     {
@@ -576,10 +579,10 @@ div_and_round_double (code, uns,
       goto finish_up;
     }
 
-  bzero ((char *) quo, sizeof quo);
+  memset ((char *) quo, 0, sizeof quo);
 
-  bzero ((char *) num, sizeof num);    /* to zero 9th element */
-  bzero ((char *) den, sizeof den);
+  memset ((char *) num, 0, sizeof num);        /* to zero 9th element */
+  memset ((char *) den, 0, sizeof den);
 
   encode (num, lnum, hnum);
   encode (den, lden, hden);
@@ -994,7 +997,7 @@ exact_real_inverse (mode, r)
     {
       /* Don't do the optimization if there was an arithmetic error.  */
 fail:
-      set_float_handler (NULL_PTR);
+      set_float_handler (NULL);
       return 0;
     }
   set_float_handler (float_error);
@@ -1037,7 +1040,7 @@ fail:
 #endif
 
   /* Output the reciprocal and return success flag.  */
-  set_float_handler (NULL_PTR);
+  set_float_handler (NULL);
   *r = y.d;
   return 1;
 }
@@ -1308,7 +1311,7 @@ negate_expr (t)
 
     case MINUS_EXPR:
       /* - (A - B) -> B - A  */
-      if (! FLOAT_TYPE_P (type) || flag_fast_math)
+      if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
        return convert (type,
                        fold (build (MINUS_EXPR, TREE_TYPE (t),
                                     TREE_OPERAND (t, 1),
@@ -1356,9 +1359,6 @@ split_tree (in, code, conp, litp, negate_p)
 
   if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST)
     *litp = in;
-  else if (TREE_CONSTANT (in))
-    *conp = in;
-
   else if (TREE_CODE (in) == code
           || (! FLOAT_TYPE_P (TREE_TYPE (in))
               /* We can associate addition and subtraction together (even
@@ -1398,6 +1398,8 @@ split_tree (in, code, conp, litp, negate_p)
       if (neg_conp_p) *conp = negate_expr (*conp);
       if (neg_var_p) var = negate_expr (var);
     }
+  else if (TREE_CONSTANT (in))
+    *conp = in;
   else
     var = in;
 
@@ -2019,7 +2021,8 @@ fold_convert (t, arg1)
 
          /* If we are trying to make a sizetype for a small integer, use
             size_int to pick up cached types to reduce duplicate nodes.  */
-         if (TREE_CODE (type) == INTEGER_CST && TYPE_IS_SIZETYPE (type)
+         if (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
+             && !TREE_CONSTANT_OVERFLOW (arg1)
              && compare_tree_int (arg1, 10000) < 0)
            return size_int_type_wide (TREE_INT_CST_LOW (arg1), type);
 
@@ -2716,7 +2719,9 @@ invert_truthvalue (arg)
   if (TREE_CODE_CLASS (code) == '<')
     {
       if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
-         && !flag_fast_math && code != NE_EXPR && code != EQ_EXPR)
+         && !flag_unsafe_math_optimizations
+         && code != NE_EXPR 
+         && code != EQ_EXPR)
        return build1 (TRUTH_NOT_EXPR, type, arg);
       else
        return build (invert_tree_comparison (code), type,
@@ -3779,6 +3784,7 @@ fold_range_test (exp)
      short-circuited branch and the underlying object on both sides
      is the same, make a non-short-circuit operation.  */
   else if (BRANCH_COST >= 2
+          && lhs != 0 && rhs != 0
           && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
               || TREE_CODE (exp) == TRUTH_ORIF_EXPR)
           && operand_equal_p (lhs, rhs, 0))
@@ -4448,7 +4454,14 @@ extract_muldiv (t, c, code, wide_type)
       if (SAVE_EXPR_RTL (t) == 0 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0))
          && 0 != (t1 = extract_muldiv (TREE_OPERAND (t, 0), c, code,
                                        wide_type)))
-       return save_expr (t1);
+       {
+         t1 = save_expr (t1);
+         if (SAVE_EXPR_PERSISTENT_P (t) && TREE_CODE (t1) == SAVE_EXPR)
+           SAVE_EXPR_PERSISTENT_P (t1) = 1;
+         if (is_pending_size (t))
+           put_pending_size (t1);
+         return t1;
+       }
       break;
 
     case LSHIFT_EXPR:  case RSHIFT_EXPR:
@@ -4477,7 +4490,12 @@ extract_muldiv (t, c, code, wide_type)
         constant.  */
       t1 = extract_muldiv (op0, c, code, wide_type);
       t2 = extract_muldiv (op1, c, code, wide_type);
-      if (t1 != 0 && t2 != 0)
+      if (t1 != 0 && t2 != 0
+         && (code == MULT_EXPR
+             /* If not multiplication, we can only do this if either operand
+                is divisible by c.  */
+             || multiple_of_p (ctype, op0, c)
+             || multiple_of_p (ctype, op1, c)))
        return fold (build (tcode, ctype, convert (ctype, t1),
                            convert (ctype, t2)));
 
@@ -4679,17 +4697,146 @@ count_cond (expr, lim)
      tree expr;
      int lim;
 {
-  int true, false;
+  int ctrue, cfalse;
 
   if (TREE_CODE (expr) != COND_EXPR)
     return 0;
   else if (lim <= 0)
     return 0;
 
-  true = count_cond (TREE_OPERAND (expr, 1), lim - 1);
-  false = count_cond (TREE_OPERAND (expr, 2), lim - 1 - true);
-  return MIN (lim, 1 + true + false);
+  ctrue = count_cond (TREE_OPERAND (expr, 1), lim - 1);
+  cfalse = count_cond (TREE_OPERAND (expr, 2), lim - 1 - ctrue);
+  return MIN (lim, 1 + ctrue + cfalse);
+}
+
+/* Transform `a + (b ? x : y)' into `x ? (a + b) : (a + y)'.
+   Transform, `a + (x < y)' into `(x < y) ? (a + 1) : (a + 0)'.  Here
+   CODE corresponds to the `+', COND to the `(b ? x : y)' or `(x < y)'
+   expression, and ARG to `a'.  If COND_FIRST_P is non-zero, then the
+   COND is the first argument to CODE; otherwise (as in the example
+   given here), it is the second argument.  TYPE is the type of the
+   original expression.  */
+
+static tree
+fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
+     enum tree_code code;
+     tree type;
+     tree cond;
+     tree arg;
+     int cond_first_p;
+{
+  tree test, true_value, false_value;
+  tree lhs = NULL_TREE;
+  tree rhs = NULL_TREE;
+  /* In the end, we'll produce a COND_EXPR.  Both arms of the
+     conditional expression will be binary operations.  The left-hand
+     side of the expression to be executed if the condition is true
+     will be pointed to by TRUE_LHS.  Similarly, the right-hand side
+     of the expression to be executed if the condition is true will be
+     pointed to by TRUE_RHS.  FALSE_LHS and FALSE_RHS are analagous --
+     but apply to the expression to be executed if the conditional is
+     false.  */
+  tree *true_lhs;
+  tree *true_rhs;
+  tree *false_lhs;
+  tree *false_rhs;
+  /* These are the codes to use for the left-hand side and right-hand
+     side of the COND_EXPR.  Normally, they are the same as CODE.  */
+  enum tree_code lhs_code = code;
+  enum tree_code rhs_code = code;
+  /* And these are the types of the expressions.  */
+  tree lhs_type = type;
+  tree rhs_type = type;
+
+  if (cond_first_p)
+    {
+      true_rhs = false_rhs = &arg;
+      true_lhs = &true_value;
+      false_lhs = &false_value;
+    }
+  else
+    {
+      true_lhs = false_lhs = &arg;
+      true_rhs = &true_value;
+      false_rhs = &false_value;
+    }
+
+  if (TREE_CODE (cond) == COND_EXPR)
+    {
+      test = TREE_OPERAND (cond, 0);
+      true_value = TREE_OPERAND (cond, 1);
+      false_value = TREE_OPERAND (cond, 2);
+      /* If this operand throws an expression, then it does not make
+        sense to try to perform a logical or arithmetic operation
+        involving it.  Instead of building `a + throw 3' for example,
+        we simply build `a, throw 3'.  */
+      if (VOID_TYPE_P (TREE_TYPE (true_value)))
+       {
+         lhs_code = COMPOUND_EXPR;
+         if (!cond_first_p)
+           lhs_type = void_type_node;
+       }
+      if (VOID_TYPE_P (TREE_TYPE (false_value)))
+       {
+         rhs_code = COMPOUND_EXPR;
+         if (!cond_first_p)
+           rhs_type = void_type_node;
+       }
+    }
+  else
+    {
+      tree testtype = TREE_TYPE (cond);
+      test = cond;
+      true_value = convert (testtype, integer_one_node);
+      false_value = convert (testtype, integer_zero_node);
+    }
+  
+  /* If ARG is complex we want to make sure we only evaluate
+     it once.  Though this is only required if it is volatile, it
+     might be more efficient even if it is not.  However, if we
+     succeed in folding one part to a constant, we do not need
+     to make this SAVE_EXPR.  Since we do this optimization
+     primarily to see if we do end up with constant and this
+     SAVE_EXPR interferes with later optimizations, suppressing
+     it when we can is important.
+     
+     If we are not in a function, we can't make a SAVE_EXPR, so don't
+     try to do so.  Don't try to see if the result is a constant
+     if an arm is a COND_EXPR since we get exponential behavior
+     in that case.  */
+  
+  if (TREE_CODE (arg) != SAVE_EXPR && ! TREE_CONSTANT (arg)
+      && global_bindings_p () == 0
+      && ((TREE_CODE (arg) != VAR_DECL
+          && TREE_CODE (arg) != PARM_DECL)
+         || TREE_SIDE_EFFECTS (arg)))
+    {
+      if (TREE_CODE (true_value) != COND_EXPR)
+       lhs = fold (build (lhs_code, lhs_type, *true_lhs, *true_rhs));
+      
+      if (TREE_CODE (false_value) != COND_EXPR)
+       rhs = fold (build (rhs_code, rhs_type, *false_lhs, *false_rhs));
+      
+      if ((lhs == 0 || ! TREE_CONSTANT (lhs))
+         && (rhs == 0 || !TREE_CONSTANT (rhs)))
+       arg = save_expr (arg), lhs = rhs = 0;
+    }
+  
+  if (lhs == 0)
+    lhs = fold (build (lhs_code, lhs_type, *true_lhs, *true_rhs));
+  if (rhs == 0)
+    rhs = fold (build (rhs_code, rhs_type, *false_lhs, *false_rhs));
+  
+  test = fold (build (COND_EXPR, type, test, lhs, rhs));
+  
+  if (TREE_CODE (arg) == SAVE_EXPR)
+    return build (COMPOUND_EXPR, type,
+                 convert (void_type_node, arg),
+                 strip_compound_expr (test, arg));
+  else
+    return convert (type, test);
 }
+
 \f
 /* Perform constant folding and related simplification of EXPR.
    The related simplifications include x*1 => x, x*0 => 0, etc.,
@@ -4709,7 +4856,7 @@ fold (expr)
   tree type = TREE_TYPE (expr);
   register tree arg0 = NULL_TREE, arg1 = NULL_TREE;
   register enum tree_code code = TREE_CODE (t);
-  register int kind;
+  register int kind = TREE_CODE_CLASS (code);
   int invert;
   /* WINS will be nonzero when the switch is done
      if all operands are constant.  */
@@ -4717,22 +4864,17 @@ fold (expr)
 
   /* Don't try to process an RTL_EXPR since its operands aren't trees.
      Likewise for a SAVE_EXPR that's already been evaluated.  */
-  if (code == RTL_EXPR || (code == SAVE_EXPR && SAVE_EXPR_RTL (t)) != 0)
+  if (code == RTL_EXPR || (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0))
     return t;
 
-  /* Return right away if already constant.  */
-  if (TREE_CONSTANT (t))
-    {
-      if (code == CONST_DECL)
-       return DECL_INITIAL (t);
-      return t;
-    }
+  /* Return right away if a constant.  */
+  if (kind == 'c')
+    return t;
 
 #ifdef MAX_INTEGER_COMPUTATION_MODE
   check_max_integer_computation_mode (expr);
 #endif
 
-  kind = TREE_CODE_CLASS (code);
   if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
     {
       tree subop;
@@ -4761,7 +4903,7 @@ fold (expr)
     }
   else if (IS_EXPR_CODE_CLASS (kind) || kind == 'r')
     {
-      register int len = TREE_CODE_LENGTH (code);
+      register int len = first_rtl_op (code);
       register int i;
       for (i = 0; i < len; i++)
        {
@@ -4916,70 +5058,9 @@ fold (expr)
               && (! TREE_SIDE_EFFECTS (arg0)
                   || (global_bindings_p () == 0
                       && ! contains_placeholder_p (arg0))))
-       {
-         tree test, true_value, false_value;
-         tree lhs = 0, rhs = 0;
-
-         if (TREE_CODE (arg1) == COND_EXPR)
-           {
-             test = TREE_OPERAND (arg1, 0);
-             true_value = TREE_OPERAND (arg1, 1);
-             false_value = TREE_OPERAND (arg1, 2);
-           }
-         else
-           {
-             tree testtype = TREE_TYPE (arg1);
-             test = arg1;
-             true_value = convert (testtype, integer_one_node);
-             false_value = convert (testtype, integer_zero_node);
-           }
-
-         /* If ARG0 is complex we want to make sure we only evaluate
-            it once.  Though this is only required if it is volatile, it
-            might be more efficient even if it is not.  However, if we
-            succeed in folding one part to a constant, we do not need
-            to make this SAVE_EXPR.  Since we do this optimization
-            primarily to see if we do end up with constant and this
-            SAVE_EXPR interferes with later optimizations, suppressing
-            it when we can is important.
-
-            If we are not in a function, we can't make a SAVE_EXPR, so don't
-            try to do so.  Don't try to see if the result is a constant
-            if an arm is a COND_EXPR since we get exponential behavior
-            in that case.  */
-
-         if (TREE_CODE (arg0) != SAVE_EXPR && ! TREE_CONSTANT (arg0)
-             && global_bindings_p () == 0
-             && ((TREE_CODE (arg0) != VAR_DECL
-                  && TREE_CODE (arg0) != PARM_DECL)
-                 || TREE_SIDE_EFFECTS (arg0)))
-           {
-             if (TREE_CODE (true_value) != COND_EXPR)
-               lhs = fold (build (code, type, arg0, true_value));
-
-             if (TREE_CODE (false_value) != COND_EXPR)
-               rhs = fold (build (code, type, arg0, false_value));
-
-             if ((lhs == 0 || ! TREE_CONSTANT (lhs))
-                 && (rhs == 0 || !TREE_CONSTANT (rhs)))
-               arg0 = save_expr (arg0), lhs = rhs = 0;
-           }
-
-         if (lhs == 0)
-           lhs = fold (build (code, type, arg0, true_value));
-         if (rhs == 0)
-           rhs = fold (build (code, type, arg0, false_value));
-
-         test = fold (build (COND_EXPR, type, test, lhs, rhs));
-
-         if (TREE_CODE (arg0) == SAVE_EXPR)
-           return build (COMPOUND_EXPR, type,
-                         convert (void_type_node, arg0),
-                         strip_compound_expr (test, arg0));
-         else
-           return convert (type, test);
-       }
-
+       return 
+         fold_binary_op_with_conditional_arg (code, type, arg1, arg0,
+                                              /*cond_first_p=*/0);
       else if (TREE_CODE (arg0) == COMPOUND_EXPR)
        return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
                      fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
@@ -4991,55 +5072,9 @@ fold (expr)
               && (! TREE_SIDE_EFFECTS (arg1)
                   || (global_bindings_p () == 0
                       && ! contains_placeholder_p (arg1))))
-       {
-         tree test, true_value, false_value;
-         tree lhs = 0, rhs = 0;
-
-         if (TREE_CODE (arg0) == COND_EXPR)
-           {
-             test = TREE_OPERAND (arg0, 0);
-             true_value = TREE_OPERAND (arg0, 1);
-             false_value = TREE_OPERAND (arg0, 2);
-           }
-         else
-           {
-             tree testtype = TREE_TYPE (arg0);
-             test = arg0;
-             true_value = convert (testtype, integer_one_node);
-             false_value = convert (testtype, integer_zero_node);
-           }
-
-         if (TREE_CODE (arg1) != SAVE_EXPR && ! TREE_CONSTANT (arg0)
-             && global_bindings_p () == 0
-             && ((TREE_CODE (arg1) != VAR_DECL
-                  && TREE_CODE (arg1) != PARM_DECL)
-                 || TREE_SIDE_EFFECTS (arg1)))
-           {
-             if (TREE_CODE (true_value) != COND_EXPR)
-               lhs = fold (build (code, type, true_value, arg1));
-
-             if (TREE_CODE (false_value) != COND_EXPR)
-               rhs = fold (build (code, type, false_value, arg1));
-
-             if ((lhs == 0 || ! TREE_CONSTANT (lhs))
-                 && (rhs == 0 || !TREE_CONSTANT (rhs)))
-               arg1 = save_expr (arg1), lhs = rhs = 0;
-           }
-
-         if (lhs == 0)
-           lhs = fold (build (code, type, true_value, arg1));
-
-         if (rhs == 0)
-           rhs = fold (build (code, type, false_value, arg1));
-
-         test = fold (build (COND_EXPR, type, test, lhs, rhs));
-         if (TREE_CODE (arg1) == SAVE_EXPR)
-           return build (COMPOUND_EXPR, type,
-                         convert (void_type_node, arg1),
-                         strip_compound_expr (test, arg1));
-         else
-           return convert (type, test);
-       }
+       return 
+         fold_binary_op_with_conditional_arg (code, type, arg0, arg1,
+                                              /*cond_first_p=*/1);
     }
   else if (TREE_CODE_CLASS (code) == '<'
           && TREE_CODE (arg0) == COMPOUND_EXPR)
@@ -5098,10 +5133,10 @@ fold (expr)
             handled below, if we are converting something to its own
             type via an object of identical or wider precision, neither
             conversion is needed.  */
-         if (inside_type == final_type
+         if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (final_type)
              && ((inter_int && final_int) || (inter_float && final_float))
              && inter_prec >= final_prec)
-           return TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+           return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
 
          /* Likewise, if the intermediate and final types are either both
             float or both integer, we don't need the middle conversion if
@@ -5229,7 +5264,7 @@ fold (expr)
 
       /* Convert - (a - b) to (b - a) for non-floating-point.  */
       else if (TREE_CODE (arg0) == MINUS_EXPR
-              && (! FLOAT_TYPE_P (type) || flag_fast_math))
+              && (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
        return build (MINUS_EXPR, type, TREE_OPERAND (arg0, 1),
                      TREE_OPERAND (arg0, 0));
 
@@ -5240,8 +5275,16 @@ fold (expr)
        {
          if (TREE_CODE (arg0) == INTEGER_CST)
            {
-             if (! TREE_UNSIGNED (type)
-                 && TREE_INT_CST_HIGH (arg0) < 0)
+             /* If the value is unsigned, then the absolute value is
+                the same as the ordinary value.  */
+             if (TREE_UNSIGNED (type))
+               return arg0;
+             /* Similarly, if the value is non-negative.  */
+             else if (INT_CST_LT (integer_minus_one_node, arg0))
+               return arg0;
+             /* If the value is negative, then the absolute value is
+                its negation.  */
+             else
                {
                  unsigned HOST_WIDE_INT low;
                  HOST_WIDE_INT high;
@@ -5276,8 +5319,8 @@ fold (expr)
                      TREE_OPERAND (arg0, 0),
                      negate_expr (TREE_OPERAND (arg0, 1)));
       else if (TREE_CODE (arg0) == COMPLEX_CST)
-       return build_complex (type, TREE_OPERAND (arg0, 0),
-                             negate_expr (TREE_OPERAND (arg0, 1)));
+       return build_complex (type, TREE_REALPART (arg0),
+                             negate_expr (TREE_IMAGPART (arg0)));
       else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
        return fold (build (TREE_CODE (arg0), type,
                            fold (build1 (CONJ_EXPR, type,
@@ -5424,7 +5467,7 @@ fold (expr)
        }
       /* In IEEE floating point, x+0 may not equal x.  */
       else if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
-               || flag_fast_math)
+               || flag_unsafe_math_optimizations)
               && real_zerop (arg1))
        return non_lvalue (convert (type, arg0));
       /* x+(-0) equals x, even for IEEE.  */
@@ -5508,11 +5551,11 @@ fold (expr)
         parentheses.  Rather than remember where the parentheses were, we
         don't associate floats at all.  It shouldn't matter much.  However,
         associating multiplications is only very slightly inaccurate, so do
-        that if -ffast-math is specified.  */
+        that if -funsafe-math-optimizations is specified.  */
 
       if (! wins
          && (! FLOAT_TYPE_P (type)
-             || (flag_fast_math && code != MULT_EXPR)))
+             || (flag_unsafe_math_optimizations && code == MULT_EXPR)))
        {
          tree var0, con0, lit0, var1, con1, lit1;
 
@@ -5589,7 +5632,7 @@ fold (expr)
        }
 
       else if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
-              || flag_fast_math)
+              || flag_unsafe_math_optimizations)
        {
          /* Except with IEEE floating point, 0-x equals -x.  */
          if (! wins && real_zerop (arg0))
@@ -5605,7 +5648,7 @@ fold (expr)
         Also note that operand_equal_p is always false if an operand
         is volatile.  */
 
-      if ((! FLOAT_TYPE_P (type) || flag_fast_math)
+      if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
          && operand_equal_p (arg0, arg1, 0))
        return convert (type, integer_zero_node);
 
@@ -5644,7 +5687,7 @@ fold (expr)
        {
          /* x*0 is 0, except for IEEE floating point.  */
          if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
-              || flag_fast_math)
+              || flag_unsafe_math_optimizations)
              && real_zerop (arg1))
            return omit_one_operand (type, arg1, arg0);
          /* In IEEE floating point, x*1 is not equivalent to x for snans.
@@ -5801,12 +5844,12 @@ fold (expr)
 
       /* If ARG1 is a constant, we can convert this to a multiply by the
         reciprocal.  This does not have the same rounding properties,
-        so only do this if -ffast-math.  We can actually always safely
-        do it if ARG1 is a power of two, but it's hard to tell if it is
-        or not in a portable manner.  */
+        so only do this if -funsafe-math-optimizations.  We can actually
+        always safely do it if ARG1 is a power of two, but it's hard to
+        tell if it is or not in a portable manner.  */
       if (TREE_CODE (arg1) == REAL_CST)
        {
-         if (flag_fast_math
+         if (flag_unsafe_math_optimizations
              && 0 != (tem = const_binop (code, build_real (type, dconst1),
                                          arg1, 0)))
            return fold (build (MULT_EXPR, type, arg0, tem));
@@ -5961,7 +6004,9 @@ fold (expr)
       /* If either arg is constant true, drop it.  */
       if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
        return non_lvalue (convert (type, arg1));
-      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
+      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
+         /* Preserve sequence points.  */
+         && (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
        return non_lvalue (convert (type, arg0));
       /* If second arg is constant zero, result is zero, but first arg
         must be evaluated.  */
@@ -6047,7 +6092,9 @@ fold (expr)
       /* If either arg is constant zero, drop it.  */
       if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
        return non_lvalue (convert (type, arg1));
-      if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1))
+      if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
+         /* Preserve sequence points.  */
+         && (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
        return non_lvalue (convert (type, arg0));
       /* If second arg is constant true, result is true, but we must
         evaluate first arg.  */
@@ -6566,7 +6613,9 @@ fold (expr)
            else if (TREE_INT_CST_HIGH (arg1) == 0
                      && (TREE_INT_CST_LOW (arg1)
                          == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
-                     && TREE_UNSIGNED (TREE_TYPE (arg1)))
+                     && TREE_UNSIGNED (TREE_TYPE (arg1))
+                        /* signed_type does not work on pointer types.  */
+                     && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
 
              switch (TREE_CODE (t))
                {
@@ -6862,7 +6911,7 @@ fold (expr)
       if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
          && (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
              || ! FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
-             || flag_fast_math)
+             || flag_unsafe_math_optimizations)
          && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
                                             arg1, TREE_OPERAND (arg0, 1)))
        {
@@ -7249,6 +7298,25 @@ multiple_of_p (type, top, bottom)
       return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
              && multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
 
+    case LSHIFT_EXPR:
+      if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
+       {
+         tree op1, t1;
+
+         op1 = TREE_OPERAND (top, 1);
+         /* const_binop may not detect overflow correctly,
+            so check for it explicitly here.  */
+         if (TYPE_PRECISION (TREE_TYPE (size_one_node))
+             > TREE_INT_CST_LOW (op1)
+             && TREE_INT_CST_HIGH (op1) == 0
+             && 0 != (t1 = convert (type,
+                                    const_binop (LSHIFT_EXPR, size_one_node,
+                                                 op1, 0)))
+             && ! TREE_OVERFLOW (t1))
+           return multiple_of_p (type, t1, bottom);
+       }
+      return 0;
+
     case NOP_EXPR:
       /* Can't handle conversions from non-integral or wider integral type.  */
       if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
@@ -7262,9 +7330,10 @@ multiple_of_p (type, top, bottom)
       return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);
 
     case INTEGER_CST:
-      if ((TREE_CODE (bottom) != INTEGER_CST)
-         || (tree_int_cst_sgn (top) < 0)
-         || (tree_int_cst_sgn (bottom) < 0))
+      if (TREE_CODE (bottom) != INTEGER_CST
+         || (TREE_UNSIGNED (type)
+             && (tree_int_cst_sgn (top) < 0
+                 || tree_int_cst_sgn (bottom) < 0)))
        return 0;
       return integer_zerop (const_binop (TRUNC_MOD_EXPR,
                                         top, bottom, 0));
@@ -7293,8 +7362,12 @@ tree_expr_nonnegative_p (t)
       return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
       
     default:
-      /* We don't know sign of `t', so be safe and return false.  */
-      return 0;
+      if (truth_value_p (TREE_CODE (t)))
+       /* Truth values evaluate to 0 or 1, which is nonnegative.  */
+       return 1;
+      else
+       /* We don't know sign of `t', so be conservative and return false.  */
+       return 0;
     }
 }