OSDN Git Service

* fold-const.c (fold): Remove handling of binary expressions.
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 Mar 2005 00:42:56 +0000 (00:42 +0000)
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 Mar 2005 00:42:56 +0000 (00:42 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95961 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c

index 3224ef2..e6c7fa8 100644 (file)
@@ -6,6 +6,8 @@
        (NON_TYPE_CHECK): Use TYPE_P instead of
        IS_NON_TYPE_CODE_CLASS.
 
+       * fold-const.c (fold): Remove handling of binary expressions.
+
 2005-03-05  James A. Morrison  <phython@gcc.gnu.org>
 
        * doc/c-tree.texi: Wrap comments in @r{}.
index 22e2ecd..04f56eb 100644 (file)
@@ -9873,17 +9873,9 @@ tree
 fold (tree expr)
 {
   const tree t = expr;
-  const tree type = TREE_TYPE (expr);
-  tree t1 = NULL_TREE;
-  tree tem;
-  tree arg0 = NULL_TREE, arg1 = NULL_TREE;
   enum tree_code code = TREE_CODE (t);
   enum tree_code_class kind = TREE_CODE_CLASS (code);
 
-  /* WINS will be nonzero when the switch is done
-     if all operands are constant.  */
-  int wins = 1;
-
   /* Return right away if a constant.  */
   if (kind == tcc_constant)
     return t;
@@ -9903,2601 +9895,11 @@ fold (tree expr)
        }
     }
 
-  if (IS_EXPR_CODE_CLASS (kind))
-    {
-      int len = TREE_CODE_LENGTH (code);
-      int i;
-      for (i = 0; i < len; i++)
-       {
-         tree op = TREE_OPERAND (t, i);
-         tree subop;
-
-         if (op == 0)
-           continue;           /* Valid for CALL_EXPR, at least.  */
-
-         /* Strip any conversions that don't change the mode.  This is
-            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.
-
-            Note that this is done as an internal manipulation within the
-            constant folder, in order to find the simplest representation
-            of the arguments so that their form can be studied.  In any
-            cases, the appropriate type conversions should be put back in
-            the tree that will get out of the constant folder.  */
-         if (kind == tcc_comparison)
-           STRIP_SIGN_NOPS (op);
-         else
-           STRIP_NOPS (op);
-
-         if (TREE_CODE (op) == COMPLEX_CST)
-           subop = TREE_REALPART (op);
-         else
-           subop = op;
-
-         if (TREE_CODE (subop) != INTEGER_CST
-             && TREE_CODE (subop) != REAL_CST)
-           /* Note that TREE_CONSTANT isn't enough:
-              static var addresses are constant but we can't
-              do arithmetic on them.  */
-           wins = 0;
-
-         if (i == 0)
-           arg0 = op;
-         else if (i == 1)
-           arg1 = op;
-       }
-    }
-
-  /* If this is a commutative operation, and ARG0 is a constant, move it
-     to ARG1 to reduce the number of tests below.  */
-  if (commutative_tree_code (code)
-      && tree_swap_operands_p (arg0, arg1, true))
-    return fold (build2 (code, type, TREE_OPERAND (t, 1),
-                        TREE_OPERAND (t, 0)));
-
-  /* Now WINS is set as described above,
-     ARG0 is the first operand of EXPR,
-     and ARG1 is the second operand (if it has more than one operand).
-
-     First check for cases where an arithmetic operation is applied to a
-     compound, conditional, or comparison operation.  Push the arithmetic
-     operation inside the compound or conditional to see if any folding
-     can then be done.  Convert comparison to conditional for this purpose.
-     The also optimizes non-constant cases that used to be done in
-     expand_expr.
-
-     Before we do that, see if this is a BIT_AND_EXPR or a BIT_IOR_EXPR,
-     one of the operands is a comparison and the other is a comparison, a
-     BIT_AND_EXPR with the constant 1, or a truth value.  In that case, the
-     code below would make the expression more complex.  Change it to a
-     TRUTH_{AND,OR}_EXPR.  Likewise, convert a similar NE_EXPR to
-     TRUTH_XOR_EXPR and an EQ_EXPR to the inversion of a TRUTH_XOR_EXPR.  */
-
-  if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
-       || code == EQ_EXPR || code == NE_EXPR)
-      && ((truth_value_p (TREE_CODE (arg0))
-          && (truth_value_p (TREE_CODE (arg1))
-              || (TREE_CODE (arg1) == BIT_AND_EXPR
-                  && integer_onep (TREE_OPERAND (arg1, 1)))))
-         || (truth_value_p (TREE_CODE (arg1))
-             && (truth_value_p (TREE_CODE (arg0))
-                 || (TREE_CODE (arg0) == BIT_AND_EXPR
-                     && integer_onep (TREE_OPERAND (arg0, 1)))))))
-    {
-      tem = fold (build2 (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
-                         : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
-                         : TRUTH_XOR_EXPR,
-                         type, fold_convert (boolean_type_node, arg0),
-                         fold_convert (boolean_type_node, arg1)));
-
-      if (code == EQ_EXPR)
-       tem = invert_truthvalue (tem);
-
-      return tem;
-    }
-
-  if (TREE_CODE_CLASS (code) == tcc_comparison
-          && TREE_CODE (arg0) == COMPOUND_EXPR)
-    return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
-                  fold (build2 (code, type, TREE_OPERAND (arg0, 1), arg1)));
-  else if (TREE_CODE_CLASS (code) == tcc_comparison
-          && TREE_CODE (arg1) == COMPOUND_EXPR)
-    return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
-                  fold (build2 (code, type, arg0, TREE_OPERAND (arg1, 1))));
-  else if (TREE_CODE_CLASS (code) == tcc_binary
-          || TREE_CODE_CLASS (code) == tcc_comparison)
-    {
-      if (TREE_CODE (arg0) == COMPOUND_EXPR)
-       return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
-                      fold (build2 (code, type, TREE_OPERAND (arg0, 1),
-                                    arg1)));
-      if (TREE_CODE (arg1) == COMPOUND_EXPR
-         && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
-       return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
-                      fold (build2 (code, type,
-                                    arg0, TREE_OPERAND (arg1, 1))));
-
-      if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0))
-       {
-         tem = fold_binary_op_with_conditional_arg (t, code, arg0, arg1, 
-                                                    /*cond_first_p=*/1);
-         if (tem != NULL_TREE)
-           return tem;
-       }
-
-      if (TREE_CODE (arg1) == COND_EXPR || COMPARISON_CLASS_P (arg1))
-       {
-         tem = fold_binary_op_with_conditional_arg (t, code, arg1, arg0, 
-                                                    /*cond_first_p=*/0);
-         if (tem != NULL_TREE)
-           return tem;
-       }
-    }
-
   switch (code)
     {
     case CONST_DECL:
       return fold (DECL_INITIAL (t));
 
-    case RANGE_EXPR:
-      if (TREE_CONSTANT (t) != wins)
-       {
-         tem = copy_node (t);
-         TREE_CONSTANT (tem) = wins;
-         TREE_INVARIANT (tem) = wins;
-         return tem;
-       }
-      return t;
-
-    case PLUS_EXPR:
-      /* A + (-B) -> A - B */
-      if (TREE_CODE (arg1) == NEGATE_EXPR)
-       return fold (build2 (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
-      /* (-A) + B -> B - A */
-      if (TREE_CODE (arg0) == NEGATE_EXPR
-         && reorder_operands_p (TREE_OPERAND (arg0, 0), arg1))
-       return fold (build2 (MINUS_EXPR, type, arg1, TREE_OPERAND (arg0, 0)));
-
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_add (type, arg0, arg1, PLUS_EXPR);
-         if (tem)
-           return tem;
-       }
-
-      if (! FLOAT_TYPE_P (type))
-       {
-         if (integer_zerop (arg1))
-           return non_lvalue (fold_convert (type, arg0));
-
-         /* If we are adding two BIT_AND_EXPR's, both of which are and'ing
-            with a constant, and the two constants have no bits in common,
-            we should treat this as a BIT_IOR_EXPR since this may produce more
-            simplifications.  */
-         if (TREE_CODE (arg0) == BIT_AND_EXPR
-             && TREE_CODE (arg1) == BIT_AND_EXPR
-             && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-             && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
-             && integer_zerop (const_binop (BIT_AND_EXPR,
-                                            TREE_OPERAND (arg0, 1),
-                                            TREE_OPERAND (arg1, 1), 0)))
-           {
-             code = BIT_IOR_EXPR;
-             goto bit_ior;
-           }
-
-         /* Reassociate (plus (plus (mult) (foo)) (mult)) as
-            (plus (plus (mult) (mult)) (foo)) so that we can
-            take advantage of the factoring cases below.  */
-         if (((TREE_CODE (arg0) == PLUS_EXPR
-               || TREE_CODE (arg0) == MINUS_EXPR)
-              && TREE_CODE (arg1) == MULT_EXPR)
-             || ((TREE_CODE (arg1) == PLUS_EXPR
-                  || TREE_CODE (arg1) == MINUS_EXPR)
-                 && TREE_CODE (arg0) == MULT_EXPR))
-           {
-             tree parg0, parg1, parg, marg;
-             enum tree_code pcode;
-
-             if (TREE_CODE (arg1) == MULT_EXPR)
-               parg = arg0, marg = arg1;
-             else
-               parg = arg1, marg = arg0;
-             pcode = TREE_CODE (parg);
-             parg0 = TREE_OPERAND (parg, 0);
-             parg1 = TREE_OPERAND (parg, 1);
-             STRIP_NOPS (parg0);
-             STRIP_NOPS (parg1);
-
-             if (TREE_CODE (parg0) == MULT_EXPR
-                 && TREE_CODE (parg1) != MULT_EXPR)
-               return fold (build2 (pcode, type,
-                                    fold (build2 (PLUS_EXPR, type,
-                                                  fold_convert (type, parg0),
-                                                  fold_convert (type, marg))),
-                                    fold_convert (type, parg1)));
-             if (TREE_CODE (parg0) != MULT_EXPR
-                 && TREE_CODE (parg1) == MULT_EXPR)
-               return fold (build2 (PLUS_EXPR, type,
-                                    fold_convert (type, parg0),
-                                    fold (build2 (pcode, type,
-                                                  fold_convert (type, marg),
-                                                  fold_convert (type,
-                                                                parg1)))));
-           }
-
-         if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR)
-           {
-             tree arg00, arg01, arg10, arg11;
-             tree alt0 = NULL_TREE, alt1 = NULL_TREE, same;
-
-             /* (A * C) + (B * C) -> (A+B) * C.
-                We are most concerned about the case where C is a constant,
-                but other combinations show up during loop reduction.  Since
-                it is not difficult, try all four possibilities.  */
-
-             arg00 = TREE_OPERAND (arg0, 0);
-             arg01 = TREE_OPERAND (arg0, 1);
-             arg10 = TREE_OPERAND (arg1, 0);
-             arg11 = TREE_OPERAND (arg1, 1);
-             same = NULL_TREE;
-
-             if (operand_equal_p (arg01, arg11, 0))
-               same = arg01, alt0 = arg00, alt1 = arg10;
-             else if (operand_equal_p (arg00, arg10, 0))
-               same = arg00, alt0 = arg01, alt1 = arg11;
-             else if (operand_equal_p (arg00, arg11, 0))
-               same = arg00, alt0 = arg01, alt1 = arg10;
-             else if (operand_equal_p (arg01, arg10, 0))
-               same = arg01, alt0 = arg00, alt1 = arg11;
-
-             /* No identical multiplicands; see if we can find a common
-                power-of-two factor in non-power-of-two multiplies.  This
-                can help in multi-dimensional array access.  */
-             else if (TREE_CODE (arg01) == INTEGER_CST
-                      && TREE_CODE (arg11) == INTEGER_CST
-                      && TREE_INT_CST_HIGH (arg01) == 0
-                      && TREE_INT_CST_HIGH (arg11) == 0)
-               {
-                 HOST_WIDE_INT int01, int11, tmp;
-                 int01 = TREE_INT_CST_LOW (arg01);
-                 int11 = TREE_INT_CST_LOW (arg11);
-
-                 /* Move min of absolute values to int11.  */
-                 if ((int01 >= 0 ? int01 : -int01)
-                     < (int11 >= 0 ? int11 : -int11))
-                   {
-                     tmp = int01, int01 = int11, int11 = tmp;
-                     alt0 = arg00, arg00 = arg10, arg10 = alt0;
-                     alt0 = arg01, arg01 = arg11, arg11 = alt0;
-                   }
-
-                 if (exact_log2 (int11) > 0 && int01 % int11 == 0)
-                   {
-                     alt0 = fold (build2 (MULT_EXPR, type, arg00,
-                                          build_int_cst (NULL_TREE,
-                                                         int01 / int11)));
-                     alt1 = arg10;
-                     same = arg11;
-                   }
-               }
-
-             if (same)
-               return fold (build2 (MULT_EXPR, type,
-                                    fold (build2 (PLUS_EXPR, type,
-                                                  fold_convert (type, alt0),
-                                                  fold_convert (type, alt1))),
-                                    same));
-           }
-
-         /* Try replacing &a[i1] + c * i2 with &a[i1 + i2], if c is step
-            of the array.  Loop optimizer sometimes produce this type of
-            expressions.  */
-         if (TREE_CODE (arg0) == ADDR_EXPR
-             && TREE_CODE (arg1) == MULT_EXPR)
-           {
-             tem = try_move_mult_to_index (PLUS_EXPR, arg0, arg1);
-             if (tem)
-               return fold_convert (type, fold (tem));
-           }
-         else if (TREE_CODE (arg1) == ADDR_EXPR
-                  && TREE_CODE (arg0) == MULT_EXPR)
-           {
-             tem = try_move_mult_to_index (PLUS_EXPR, arg1, arg0);
-             if (tem)
-               return fold_convert (type, fold (tem));
-           }
-       }
-      else
-       {
-         /* See if ARG1 is zero and X + ARG1 reduces to X.  */
-         if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
-           return non_lvalue (fold_convert (type, arg0));
-
-         /* Likewise if the operands are reversed.  */
-         if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
-           return non_lvalue (fold_convert (type, arg1));
-
-         /* Convert X + -C into X - C.  */
-         if (TREE_CODE (arg1) == REAL_CST
-             && REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))
-           {
-             tem = fold_negate_const (arg1, type);
-             if (!TREE_OVERFLOW (arg1) || !flag_trapping_math)
-               return fold (build2 (MINUS_EXPR, type,
-                                    fold_convert (type, arg0),
-                                    fold_convert (type, tem)));
-           }
-
-         /* Convert x+x into x*2.0.  */
-         if (operand_equal_p (arg0, arg1, 0)
-             && SCALAR_FLOAT_TYPE_P (type))
-           return fold (build2 (MULT_EXPR, type, arg0,
-                                build_real (type, dconst2)));
-
-         /* Convert x*c+x into x*(c+1).  */
-         if (flag_unsafe_math_optimizations
-             && TREE_CODE (arg0) == MULT_EXPR
-             && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
-             && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
-             && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-           {
-             REAL_VALUE_TYPE c;
-
-             c = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
-             real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
-             return fold (build2 (MULT_EXPR, type, arg1,
-                                  build_real (type, c)));
-           }
-
-         /* Convert x+x*c into x*(c+1).  */
-         if (flag_unsafe_math_optimizations
-             && TREE_CODE (arg1) == MULT_EXPR
-             && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
-             && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
-             && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
-           {
-             REAL_VALUE_TYPE c;
-
-             c = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
-             real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
-             return fold (build2 (MULT_EXPR, type, arg0,
-                                  build_real (type, c)));
-           }
-
-         /* Convert x*c1+x*c2 into x*(c1+c2).  */
-         if (flag_unsafe_math_optimizations
-             && TREE_CODE (arg0) == MULT_EXPR
-             && TREE_CODE (arg1) == MULT_EXPR
-             && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
-             && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
-             && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
-             && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
-             && operand_equal_p (TREE_OPERAND (arg0, 0),
-                                 TREE_OPERAND (arg1, 0), 0))
-           {
-             REAL_VALUE_TYPE c1, c2;
-
-             c1 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
-             c2 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
-             real_arithmetic (&c1, PLUS_EXPR, &c1, &c2);
-             return fold (build2 (MULT_EXPR, type,
-                                  TREE_OPERAND (arg0, 0),
-                                  build_real (type, c1)));
-           }
-          /* Convert a + (b*c + d*e) into (a + b*c) + d*e.  */
-          if (flag_unsafe_math_optimizations
-              && TREE_CODE (arg1) == PLUS_EXPR
-              && TREE_CODE (arg0) != MULT_EXPR)
-            {
-              tree tree10 = TREE_OPERAND (arg1, 0);
-              tree tree11 = TREE_OPERAND (arg1, 1);
-              if (TREE_CODE (tree11) == MULT_EXPR
-                 && TREE_CODE (tree10) == MULT_EXPR)
-                {
-                  tree tree0;
-                  tree0 = fold (build2 (PLUS_EXPR, type, arg0, tree10));
-                  return fold (build2 (PLUS_EXPR, type, tree0, tree11));
-                }
-            }
-          /* Convert (b*c + d*e) + a into b*c + (d*e +a).  */
-          if (flag_unsafe_math_optimizations
-              && TREE_CODE (arg0) == PLUS_EXPR
-              && TREE_CODE (arg1) != MULT_EXPR)
-            {
-              tree tree00 = TREE_OPERAND (arg0, 0);
-              tree tree01 = TREE_OPERAND (arg0, 1);
-              if (TREE_CODE (tree01) == MULT_EXPR
-                 && TREE_CODE (tree00) == MULT_EXPR)
-                {
-                  tree tree0;
-                  tree0 = fold (build2 (PLUS_EXPR, type, tree01, arg1));
-                  return fold (build2 (PLUS_EXPR, type, tree00, tree0));
-                }
-            }
-       }
-
-     bit_rotate:
-      /* (A << C1) + (A >> C2) if A is unsigned and C1+C2 is the size of A
-        is a rotate of A by C1 bits.  */
-      /* (A << B) + (A >> (Z - B)) if A is unsigned and Z is the size of A
-        is a rotate of A by B bits.  */
-      {
-       enum tree_code code0, code1;
-       code0 = TREE_CODE (arg0);
-       code1 = TREE_CODE (arg1);
-       if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
-            || (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
-           && operand_equal_p (TREE_OPERAND (arg0, 0),
-                               TREE_OPERAND (arg1, 0), 0)
-           && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
-         {
-           tree tree01, tree11;
-           enum tree_code code01, code11;
-
-           tree01 = TREE_OPERAND (arg0, 1);
-           tree11 = TREE_OPERAND (arg1, 1);
-           STRIP_NOPS (tree01);
-           STRIP_NOPS (tree11);
-           code01 = TREE_CODE (tree01);
-           code11 = TREE_CODE (tree11);
-           if (code01 == INTEGER_CST
-               && code11 == INTEGER_CST
-               && TREE_INT_CST_HIGH (tree01) == 0
-               && TREE_INT_CST_HIGH (tree11) == 0
-               && ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
-                   == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
-             return build2 (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
-                            code0 == LSHIFT_EXPR ? tree01 : tree11);
-           else if (code11 == MINUS_EXPR)
-             {
-               tree tree110, tree111;
-               tree110 = TREE_OPERAND (tree11, 0);
-               tree111 = TREE_OPERAND (tree11, 1);
-               STRIP_NOPS (tree110);
-               STRIP_NOPS (tree111);
-               if (TREE_CODE (tree110) == INTEGER_CST
-                   && 0 == compare_tree_int (tree110,
-                                             TYPE_PRECISION
-                                             (TREE_TYPE (TREE_OPERAND
-                                                         (arg0, 0))))
-                   && operand_equal_p (tree01, tree111, 0))
-                 return build2 ((code0 == LSHIFT_EXPR
-                                 ? LROTATE_EXPR
-                                 : RROTATE_EXPR),
-                                type, TREE_OPERAND (arg0, 0), tree01);
-             }
-           else if (code01 == MINUS_EXPR)
-             {
-               tree tree010, tree011;
-               tree010 = TREE_OPERAND (tree01, 0);
-               tree011 = TREE_OPERAND (tree01, 1);
-               STRIP_NOPS (tree010);
-               STRIP_NOPS (tree011);
-               if (TREE_CODE (tree010) == INTEGER_CST
-                   && 0 == compare_tree_int (tree010,
-                                             TYPE_PRECISION
-                                             (TREE_TYPE (TREE_OPERAND
-                                                         (arg0, 0))))
-                   && operand_equal_p (tree11, tree011, 0))
-                 return build2 ((code0 != LSHIFT_EXPR
-                                 ? LROTATE_EXPR
-                                 : RROTATE_EXPR),
-                                type, TREE_OPERAND (arg0, 0), tree11);
-             }
-         }
-      }
-
-    associate:
-      /* In most languages, can't associate operations on floats through
-        parentheses.  Rather than remember where the parentheses were, we
-        don't associate floats at all, unless the user has specified
-        -funsafe-math-optimizations.  */
-
-      if (! wins
-         && (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
-       {
-         tree var0, con0, lit0, minus_lit0;
-         tree var1, con1, lit1, minus_lit1;
-
-         /* Split both trees into variables, constants, and literals.  Then
-            associate each group together, the constants with literals,
-            then the result with variables.  This increases the chances of
-            literals being recombined later and of generating relocatable
-            expressions for the sum of a constant and literal.  */
-         var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0);
-         var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1,
-                            code == MINUS_EXPR);
-
-         /* Only do something if we found more than two objects.  Otherwise,
-            nothing has changed and we risk infinite recursion.  */
-         if (2 < ((var0 != 0) + (var1 != 0)
-                  + (con0 != 0) + (con1 != 0)
-                  + (lit0 != 0) + (lit1 != 0)
-                  + (minus_lit0 != 0) + (minus_lit1 != 0)))
-           {
-             /* Recombine MINUS_EXPR operands by using PLUS_EXPR.  */
-             if (code == MINUS_EXPR)
-               code = PLUS_EXPR;
-
-             var0 = associate_trees (var0, var1, code, type);
-             con0 = associate_trees (con0, con1, code, type);
-             lit0 = associate_trees (lit0, lit1, code, type);
-             minus_lit0 = associate_trees (minus_lit0, minus_lit1, code, type);
-
-             /* Preserve the MINUS_EXPR if the negative part of the literal is
-                greater than the positive part.  Otherwise, the multiplicative
-                folding code (i.e extract_muldiv) may be fooled in case
-                unsigned constants are subtracted, like in the following
-                example: ((X*2 + 4) - 8U)/2.  */
-             if (minus_lit0 && lit0)
-               {
-                 if (TREE_CODE (lit0) == INTEGER_CST
-                     && TREE_CODE (minus_lit0) == INTEGER_CST
-                     && tree_int_cst_lt (lit0, minus_lit0))
-                   {
-                     minus_lit0 = associate_trees (minus_lit0, lit0,
-                                                   MINUS_EXPR, type);
-                     lit0 = 0;
-                   }
-                 else
-                   {
-                     lit0 = associate_trees (lit0, minus_lit0,
-                                             MINUS_EXPR, type);
-                     minus_lit0 = 0;
-                   }
-               }
-             if (minus_lit0)
-               {
-                 if (con0 == 0)
-                   return fold_convert (type,
-                                        associate_trees (var0, minus_lit0,
-                                                         MINUS_EXPR, type));
-                 else
-                   {
-                     con0 = associate_trees (con0, minus_lit0,
-                                             MINUS_EXPR, type);
-                     return fold_convert (type,
-                                          associate_trees (var0, con0,
-                                                           PLUS_EXPR, type));
-                   }
-               }
-
-             con0 = associate_trees (con0, lit0, code, type);
-             return fold_convert (type, associate_trees (var0, con0,
-                                                         code, type));
-           }
-       }
-
-    binary:
-      if (wins)
-       t1 = const_binop (code, arg0, arg1, 0);
-      if (t1 != NULL_TREE)
-       {
-         /* The return value should always have
-            the same type as the original expression.  */
-         if (TREE_TYPE (t1) != type)
-           t1 = fold_convert (type, t1);
-
-         return t1;
-       }
-      return t;
-
-    case MINUS_EXPR:
-      /* A - (-B) -> A + B */
-      if (TREE_CODE (arg1) == NEGATE_EXPR)
-       return fold (build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
-      /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
-      if (TREE_CODE (arg0) == NEGATE_EXPR
-         && (FLOAT_TYPE_P (type)
-             || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
-         && negate_expr_p (arg1)
-         && reorder_operands_p (arg0, arg1))
-       return fold (build2 (MINUS_EXPR, type, negate_expr (arg1),
-                            TREE_OPERAND (arg0, 0)));
-
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_add (type, arg0, arg1, MINUS_EXPR);
-         if (tem)
-           return tem;
-       }
-
-      if (! FLOAT_TYPE_P (type))
-       {
-         if (! wins && integer_zerop (arg0))
-           return negate_expr (fold_convert (type, arg1));
-         if (integer_zerop (arg1))
-           return non_lvalue (fold_convert (type, arg0));
-
-         /* Fold A - (A & B) into ~B & A.  */
-         if (!TREE_SIDE_EFFECTS (arg0)
-             && TREE_CODE (arg1) == BIT_AND_EXPR)
-           {
-             if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
-               return fold (build2 (BIT_AND_EXPR, type,
-                                    fold (build1 (BIT_NOT_EXPR, type,
-                                                  TREE_OPERAND (arg1, 0))),
-                                    arg0));
-             if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-               return fold (build2 (BIT_AND_EXPR, type,
-                                    fold (build1 (BIT_NOT_EXPR, type,
-                                                  TREE_OPERAND (arg1, 1))),
-                                    arg0));
-           }
-
-         /* Fold (A & ~B) - (A & B) into (A ^ B) - B, where B is
-            any power of 2 minus 1.  */
-         if (TREE_CODE (arg0) == BIT_AND_EXPR
-             && TREE_CODE (arg1) == BIT_AND_EXPR
-             && operand_equal_p (TREE_OPERAND (arg0, 0),
-                                 TREE_OPERAND (arg1, 0), 0))
-           {
-             tree mask0 = TREE_OPERAND (arg0, 1);
-             tree mask1 = TREE_OPERAND (arg1, 1);
-             tree tem = fold (build1 (BIT_NOT_EXPR, type, mask0));
-
-             if (operand_equal_p (tem, mask1, 0))
-               {
-                 tem = fold (build2 (BIT_XOR_EXPR, type,
-                                     TREE_OPERAND (arg0, 0), mask1));
-                 return fold (build2 (MINUS_EXPR, type, tem, mask1));
-               }
-           }
-       }
-
-      /* See if ARG1 is zero and X - ARG1 reduces to X.  */
-      else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 1))
-       return non_lvalue (fold_convert (type, arg0));
-
-      /* (ARG0 - ARG1) is the same as (-ARG1 + ARG0).  So check whether
-        ARG0 is zero and X + ARG0 reduces to X, since that would mean
-        (-ARG1 + ARG0) reduces to -ARG1.  */
-      else if (!wins && fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
-       return negate_expr (fold_convert (type, arg1));
-
-      /* Fold &x - &x.  This can happen from &x.foo - &x.
-        This is unsafe for certain floats even in non-IEEE formats.
-        In IEEE, it is unsafe because it does wrong for NaNs.
-        Also note that operand_equal_p is always false if an operand
-        is volatile.  */
-
-      if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
-         && operand_equal_p (arg0, arg1, 0))
-       return fold_convert (type, integer_zero_node);
-
-      /* A - B -> A + (-B) if B is easily negatable.  */
-      if (!wins && negate_expr_p (arg1)
-         && ((FLOAT_TYPE_P (type)
-               /* Avoid this transformation if B is a positive REAL_CST.  */
-              && (TREE_CODE (arg1) != REAL_CST
-                  ||  REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
-             || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
-       return fold (build2 (PLUS_EXPR, type, arg0, negate_expr (arg1)));
-
-      /* Try folding difference of addresses.  */
-      {
-       HOST_WIDE_INT diff;
-
-       if ((TREE_CODE (arg0) == ADDR_EXPR
-            || TREE_CODE (arg1) == ADDR_EXPR)
-           && ptr_difference_const (arg0, arg1, &diff))
-         return build_int_cst_type (type, diff);
-      }
-         
-      /* Try replacing &a[i1] - c * i2 with &a[i1 - i2], if c is step
-        of the array.  Loop optimizer sometimes produce this type of
-        expressions.  */
-      if (TREE_CODE (arg0) == ADDR_EXPR
-         && TREE_CODE (arg1) == MULT_EXPR)
-       {
-         tem = try_move_mult_to_index (MINUS_EXPR, arg0, arg1);
-         if (tem)
-           return fold_convert (type, fold (tem));
-       }
-
-      if (TREE_CODE (arg0) == MULT_EXPR
-         && TREE_CODE (arg1) == MULT_EXPR
-         && (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
-       {
-          /* (A * C) - (B * C) -> (A-B) * C.  */
-         if (operand_equal_p (TREE_OPERAND (arg0, 1),
-                              TREE_OPERAND (arg1, 1), 0))
-           return fold (build2 (MULT_EXPR, type,
-                                fold (build2 (MINUS_EXPR, type,
-                                              TREE_OPERAND (arg0, 0),
-                                              TREE_OPERAND (arg1, 0))),
-                                TREE_OPERAND (arg0, 1)));
-          /* (A * C1) - (A * C2) -> A * (C1-C2).  */
-         if (operand_equal_p (TREE_OPERAND (arg0, 0),
-                              TREE_OPERAND (arg1, 0), 0))
-           return fold (build2 (MULT_EXPR, type,
-                                TREE_OPERAND (arg0, 0),
-                                fold (build2 (MINUS_EXPR, type,
-                                              TREE_OPERAND (arg0, 1),
-                                              TREE_OPERAND (arg1, 1)))));
-       }
-
-      goto associate;
-
-    case MULT_EXPR:
-      /* (-A) * (-B) -> A * B  */
-      if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
-       return fold (build2 (MULT_EXPR, type,
-                            TREE_OPERAND (arg0, 0),
-                            negate_expr (arg1)));
-      if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
-       return fold (build2 (MULT_EXPR, type,
-                            negate_expr (arg0),
-                            TREE_OPERAND (arg1, 0)));
-
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_mult (type, arg0, arg1);
-         if (tem)
-           return tem;
-       }
-
-      if (! FLOAT_TYPE_P (type))
-       {
-         if (integer_zerop (arg1))
-           return omit_one_operand (type, arg1, arg0);
-         if (integer_onep (arg1))
-           return non_lvalue (fold_convert (type, arg0));
-
-         /* (a * (1 << b)) is (a << b)  */
-         if (TREE_CODE (arg1) == LSHIFT_EXPR
-             && integer_onep (TREE_OPERAND (arg1, 0)))
-           return fold (build2 (LSHIFT_EXPR, type, arg0,
-                                TREE_OPERAND (arg1, 1)));
-         if (TREE_CODE (arg0) == LSHIFT_EXPR
-             && integer_onep (TREE_OPERAND (arg0, 0)))
-           return fold (build2 (LSHIFT_EXPR, type, arg1,
-                                TREE_OPERAND (arg0, 1)));
-
-         if (TREE_CODE (arg1) == INTEGER_CST
-             && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0),
-                                            fold_convert (type, arg1),
-                                            code, NULL_TREE)))
-           return fold_convert (type, tem);
-
-       }
-      else
-       {
-         /* Maybe fold x * 0 to 0.  The expressions aren't the same
-            when x is NaN, since x * 0 is also NaN.  Nor are they the
-            same in modes with signed zeros, since multiplying a
-            negative value by 0 gives -0, not +0.  */
-         if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
-             && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
-             && real_zerop (arg1))
-           return omit_one_operand (type, arg1, arg0);
-         /* In IEEE floating point, x*1 is not equivalent to x for snans.  */
-         if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
-             && real_onep (arg1))
-           return non_lvalue (fold_convert (type, arg0));
-
-         /* Transform x * -1.0 into -x.  */
-         if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
-             && real_minus_onep (arg1))
-           return fold_convert (type, negate_expr (arg0));
-
-         /* Convert (C1/X)*C2 into (C1*C2)/X.  */
-         if (flag_unsafe_math_optimizations
-             && TREE_CODE (arg0) == RDIV_EXPR
-             && TREE_CODE (arg1) == REAL_CST
-             && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST)
-           {
-             tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0),
-                                     arg1, 0);
-             if (tem)
-               return fold (build2 (RDIV_EXPR, type, tem,
-                                    TREE_OPERAND (arg0, 1)));
-           }
-
-          /* Strip sign operations from X in X*X, i.e. -Y*-Y -> Y*Y.  */
-         if (operand_equal_p (arg0, arg1, 0))
-           {
-             tree tem = fold_strip_sign_ops (arg0);
-             if (tem != NULL_TREE)
-               {
-                 tem = fold_convert (type, tem);
-                 return fold (build2 (MULT_EXPR, type, tem, tem));
-               }
-           }
-
-         if (flag_unsafe_math_optimizations)
-           {
-             enum built_in_function fcode0 = builtin_mathfn_code (arg0);
-             enum built_in_function fcode1 = builtin_mathfn_code (arg1);
-
-             /* Optimizations of root(...)*root(...).  */
-             if (fcode0 == fcode1 && BUILTIN_ROOT_P (fcode0))
-               {
-                 tree rootfn, arg, arglist;
-                 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
-                 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
-
-                 /* Optimize sqrt(x)*sqrt(x) as x.  */
-                 if (BUILTIN_SQRT_P (fcode0)
-                     && operand_equal_p (arg00, arg10, 0)
-                     && ! HONOR_SNANS (TYPE_MODE (type)))
-                   return arg00;
-
-                 /* Optimize root(x)*root(y) as root(x*y).  */
-                 rootfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
-                 arg = fold (build2 (MULT_EXPR, type, arg00, arg10));
-                 arglist = build_tree_list (NULL_TREE, arg);
-                 return build_function_call_expr (rootfn, arglist);
-               }
-
-             /* Optimize expN(x)*expN(y) as expN(x+y).  */
-             if (fcode0 == fcode1 && BUILTIN_EXPONENT_P (fcode0))
-               {
-                 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
-                 tree arg = build2 (PLUS_EXPR, type,
-                                    TREE_VALUE (TREE_OPERAND (arg0, 1)),
-                                    TREE_VALUE (TREE_OPERAND (arg1, 1)));
-                 tree arglist = build_tree_list (NULL_TREE, fold (arg));
-                 return build_function_call_expr (expfn, arglist);
-               }
-
-             /* Optimizations of pow(...)*pow(...).  */
-             if ((fcode0 == BUILT_IN_POW && fcode1 == BUILT_IN_POW)
-                 || (fcode0 == BUILT_IN_POWF && fcode1 == BUILT_IN_POWF)
-                 || (fcode0 == BUILT_IN_POWL && fcode1 == BUILT_IN_POWL))
-               {
-                 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
-                 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
-                                                                    1)));
-                 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
-                 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
-                                                                    1)));
-
-                 /* Optimize pow(x,y)*pow(z,y) as pow(x*z,y).  */
-                 if (operand_equal_p (arg01, arg11, 0))
-                   {
-                     tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
-                     tree arg = build2 (MULT_EXPR, type, arg00, arg10);
-                     tree arglist = tree_cons (NULL_TREE, fold (arg),
-                                               build_tree_list (NULL_TREE,
-                                                                arg01));
-                     return build_function_call_expr (powfn, arglist);
-                   }
-
-                 /* Optimize pow(x,y)*pow(x,z) as pow(x,y+z).  */
-                 if (operand_equal_p (arg00, arg10, 0))
-                   {
-                     tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
-                     tree arg = fold (build2 (PLUS_EXPR, type, arg01, arg11));
-                     tree arglist = tree_cons (NULL_TREE, arg00,
-                                               build_tree_list (NULL_TREE,
-                                                                arg));
-                     return build_function_call_expr (powfn, arglist);
-                   }
-               }
-
-             /* Optimize tan(x)*cos(x) as sin(x).  */
-             if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_COS)
-                  || (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_COSF)
-                  || (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_COSL)
-                  || (fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_TAN)
-                  || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
-                  || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
-                 && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
-                                     TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
-               {
-                 tree sinfn = mathfn_built_in (type, BUILT_IN_SIN);
-
-                 if (sinfn != NULL_TREE)
-                   return build_function_call_expr (sinfn,
-                                                    TREE_OPERAND (arg0, 1));
-               }
-
-             /* Optimize x*pow(x,c) as pow(x,c+1).  */
-             if (fcode1 == BUILT_IN_POW
-                 || fcode1 == BUILT_IN_POWF
-                 || fcode1 == BUILT_IN_POWL)
-               {
-                 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
-                 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
-                                                                    1)));
-                 if (TREE_CODE (arg11) == REAL_CST
-                     && ! TREE_CONSTANT_OVERFLOW (arg11)
-                     && operand_equal_p (arg0, arg10, 0))
-                   {
-                     tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
-                     REAL_VALUE_TYPE c;
-                     tree arg, arglist;
-
-                     c = TREE_REAL_CST (arg11);
-                     real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
-                     arg = build_real (type, c);
-                     arglist = build_tree_list (NULL_TREE, arg);
-                     arglist = tree_cons (NULL_TREE, arg0, arglist);
-                     return build_function_call_expr (powfn, arglist);
-                   }
-               }
-
-             /* Optimize pow(x,c)*x as pow(x,c+1).  */
-             if (fcode0 == BUILT_IN_POW
-                 || fcode0 == BUILT_IN_POWF
-                 || fcode0 == BUILT_IN_POWL)
-               {
-                 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
-                 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
-                                                                    1)));
-                 if (TREE_CODE (arg01) == REAL_CST
-                     && ! TREE_CONSTANT_OVERFLOW (arg01)
-                     && operand_equal_p (arg1, arg00, 0))
-                   {
-                     tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
-                     REAL_VALUE_TYPE c;
-                     tree arg, arglist;
-
-                     c = TREE_REAL_CST (arg01);
-                     real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
-                     arg = build_real (type, c);
-                     arglist = build_tree_list (NULL_TREE, arg);
-                     arglist = tree_cons (NULL_TREE, arg1, arglist);
-                     return build_function_call_expr (powfn, arglist);
-                   }
-               }
-
-             /* Optimize x*x as pow(x,2.0), which is expanded as x*x.  */
-             if (! optimize_size
-                 && operand_equal_p (arg0, arg1, 0))
-               {
-                 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
-
-                 if (powfn)
-                   {
-                     tree arg = build_real (type, dconst2);
-                     tree arglist = build_tree_list (NULL_TREE, arg);
-                     arglist = tree_cons (NULL_TREE, arg0, arglist);
-                     return build_function_call_expr (powfn, arglist);
-                   }
-               }
-           }
-       }
-      goto associate;
-
-    case BIT_IOR_EXPR:
-    bit_ior:
-      if (integer_all_onesp (arg1))
-       return omit_one_operand (type, arg1, arg0);
-      if (integer_zerop (arg1))
-       return non_lvalue (fold_convert (type, arg0));
-      if (operand_equal_p (arg0, arg1, 0))
-       return non_lvalue (fold_convert (type, arg0));
-
-      /* ~X | X is -1.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-         && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-       {
-         t1 = build_int_cst (type, -1);
-         t1 = force_fit_type (t1, 0, false, false);
-         return omit_one_operand (type, t1, arg1);
-       }
-
-      /* X | ~X is -1.  */
-      if (TREE_CODE (arg1) == BIT_NOT_EXPR
-         && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-       {
-         t1 = build_int_cst (type, -1);
-         t1 = force_fit_type (t1, 0, false, false);
-         return omit_one_operand (type, t1, arg0);
-       }
-
-      t1 = distribute_bit_expr (code, type, arg0, arg1);
-      if (t1 != NULL_TREE)
-       return t1;
-
-      /* Convert (or (not arg0) (not arg1)) to (not (and (arg0) (arg1))).
-
-        This results in more efficient code for machines without a NAND
-        instruction.  Combine will canonicalize to the first form
-        which will allow use of NAND instructions provided by the
-        backend if they exist.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-         && TREE_CODE (arg1) == BIT_NOT_EXPR)
-       {
-         return fold (build1 (BIT_NOT_EXPR, type,
-                              build2 (BIT_AND_EXPR, type,
-                                      TREE_OPERAND (arg0, 0),
-                                      TREE_OPERAND (arg1, 0))));
-       }
-
-      /* See if this can be simplified into a rotate first.  If that
-        is unsuccessful continue in the association code.  */
-      goto bit_rotate;
-
-    case BIT_XOR_EXPR:
-      if (integer_zerop (arg1))
-       return non_lvalue (fold_convert (type, arg0));
-      if (integer_all_onesp (arg1))
-       return fold (build1 (BIT_NOT_EXPR, type, arg0));
-      if (operand_equal_p (arg0, arg1, 0))
-       return omit_one_operand (type, integer_zero_node, arg0);
-
-      /* ~X ^ X is -1.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-         && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-       {
-         t1 = build_int_cst (type, -1);
-         t1 = force_fit_type (t1, 0, false, false);
-         return omit_one_operand (type, t1, arg1);
-       }
-
-      /* X ^ ~X is -1.  */
-      if (TREE_CODE (arg1) == BIT_NOT_EXPR
-         && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-       {
-         t1 = build_int_cst (type, -1);
-         t1 = force_fit_type (t1, 0, false, false);
-         return omit_one_operand (type, t1, arg0);
-       }
-
-      /* If we are XORing two BIT_AND_EXPR's, both of which are and'ing
-         with a constant, and the two constants have no bits in common,
-        we should treat this as a BIT_IOR_EXPR since this may produce more
-        simplifications.  */
-      if (TREE_CODE (arg0) == BIT_AND_EXPR
-         && TREE_CODE (arg1) == BIT_AND_EXPR
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-         && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
-         && integer_zerop (const_binop (BIT_AND_EXPR,
-                                        TREE_OPERAND (arg0, 1),
-                                        TREE_OPERAND (arg1, 1), 0)))
-       {
-         code = BIT_IOR_EXPR;
-         goto bit_ior;
-       }
-
-      /* See if this can be simplified into a rotate first.  If that
-        is unsuccessful continue in the association code.  */
-      goto bit_rotate;
-
-    case BIT_AND_EXPR:
-      if (integer_all_onesp (arg1))
-       return non_lvalue (fold_convert (type, arg0));
-      if (integer_zerop (arg1))
-       return omit_one_operand (type, arg1, arg0);
-      if (operand_equal_p (arg0, arg1, 0))
-       return non_lvalue (fold_convert (type, arg0));
-
-      /* ~X & X is always zero.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-         && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-       return omit_one_operand (type, integer_zero_node, arg1);
-
-      /* X & ~X is always zero.  */
-      if (TREE_CODE (arg1) == BIT_NOT_EXPR
-         && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-       return omit_one_operand (type, integer_zero_node, arg0);
-
-      t1 = distribute_bit_expr (code, type, arg0, arg1);
-      if (t1 != NULL_TREE)
-       return t1;
-      /* Simplify ((int)c & 0377) into (int)c, if c is unsigned char.  */
-      if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
-         && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
-       {
-         unsigned int prec
-           = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
-
-         if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
-             && (~TREE_INT_CST_LOW (arg1)
-                 & (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
-           return fold_convert (type, TREE_OPERAND (arg0, 0));
-       }
-
-      /* Convert (and (not arg0) (not arg1)) to (not (or (arg0) (arg1))).
-
-        This results in more efficient code for machines without a NOR
-        instruction.  Combine will canonicalize to the first form
-        which will allow use of NOR instructions provided by the
-        backend if they exist.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-         && TREE_CODE (arg1) == BIT_NOT_EXPR)
-       {
-         return fold (build1 (BIT_NOT_EXPR, type,
-                              build2 (BIT_IOR_EXPR, type,
-                                      TREE_OPERAND (arg0, 0),
-                                      TREE_OPERAND (arg1, 0))));
-       }
-
-      goto associate;
-
-    case RDIV_EXPR:
-      /* Don't touch a floating-point divide by zero unless the mode
-        of the constant can represent infinity.  */
-      if (TREE_CODE (arg1) == REAL_CST
-         && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1)))
-         && real_zerop (arg1))
-       return t;
-
-      /* (-A) / (-B) -> A / B  */
-      if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
-       return fold (build2 (RDIV_EXPR, type,
-                            TREE_OPERAND (arg0, 0),
-                            negate_expr (arg1)));
-      if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
-       return fold (build2 (RDIV_EXPR, type,
-                            negate_expr (arg0),
-                            TREE_OPERAND (arg1, 0)));
-
-      /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
-      if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
-         && real_onep (arg1))
-       return non_lvalue (fold_convert (type, arg0));
-
-      /* In IEEE floating point, x/-1 is not equivalent to -x for snans.  */
-      if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
-         && real_minus_onep (arg1))
-       return non_lvalue (fold_convert (type, negate_expr (arg0)));
-
-      /* 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 -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_unsafe_math_optimizations
-             && 0 != (tem = const_binop (code, build_real (type, dconst1),
-                                         arg1, 0)))
-           return fold (build2 (MULT_EXPR, type, arg0, tem));
-         /* Find the reciprocal if optimizing and the result is exact.  */
-         if (optimize)
-           {
-             REAL_VALUE_TYPE r;
-             r = TREE_REAL_CST (arg1);
-             if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
-               {
-                 tem = build_real (type, r);
-                 return fold (build2 (MULT_EXPR, type, arg0, tem));
-               }
-           }
-       }
-      /* Convert A/B/C to A/(B*C).  */
-      if (flag_unsafe_math_optimizations
-         && TREE_CODE (arg0) == RDIV_EXPR)
-       return fold (build2 (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
-                            fold (build2 (MULT_EXPR, type,
-                                          TREE_OPERAND (arg0, 1), arg1))));
-
-      /* Convert A/(B/C) to (A/B)*C.  */
-      if (flag_unsafe_math_optimizations
-         && TREE_CODE (arg1) == RDIV_EXPR)
-       return fold (build2 (MULT_EXPR, type,
-                            fold (build2 (RDIV_EXPR, type, arg0,
-                                          TREE_OPERAND (arg1, 0))),
-                            TREE_OPERAND (arg1, 1)));
-
-      /* Convert C1/(X*C2) into (C1/C2)/X.  */
-      if (flag_unsafe_math_optimizations
-         && TREE_CODE (arg1) == MULT_EXPR
-         && TREE_CODE (arg0) == REAL_CST
-         && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
-       {
-         tree tem = const_binop (RDIV_EXPR, arg0,
-                                 TREE_OPERAND (arg1, 1), 0);
-         if (tem)
-           return fold (build2 (RDIV_EXPR, type, tem,
-                                TREE_OPERAND (arg1, 0)));
-       }
-
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_div (type, arg0, arg1, code);
-         if (tem)
-           return tem;
-       }
-
-      if (flag_unsafe_math_optimizations)
-       {
-         enum built_in_function fcode = builtin_mathfn_code (arg1);
-         /* Optimize x/expN(y) into x*expN(-y).  */
-         if (BUILTIN_EXPONENT_P (fcode))
-           {
-             tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
-             tree arg = negate_expr (TREE_VALUE (TREE_OPERAND (arg1, 1)));
-             tree arglist = build_tree_list (NULL_TREE,
-                                             fold_convert (type, arg));
-             arg1 = build_function_call_expr (expfn, arglist);
-             return fold (build2 (MULT_EXPR, type, arg0, arg1));
-           }
-
-         /* Optimize x/pow(y,z) into x*pow(y,-z).  */
-         if (fcode == BUILT_IN_POW
-             || fcode == BUILT_IN_POWF
-             || fcode == BUILT_IN_POWL)
-           {
-             tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
-             tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
-             tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1, 1)));
-             tree neg11 = fold_convert (type, negate_expr (arg11));
-             tree arglist = tree_cons(NULL_TREE, arg10,
-                                      build_tree_list (NULL_TREE, neg11));
-             arg1 = build_function_call_expr (powfn, arglist);
-             return fold (build2 (MULT_EXPR, type, arg0, arg1));
-           }
-       }
-
-      if (flag_unsafe_math_optimizations)
-       {
-         enum built_in_function fcode0 = builtin_mathfn_code (arg0);
-         enum built_in_function fcode1 = builtin_mathfn_code (arg1);
-
-         /* Optimize sin(x)/cos(x) as tan(x).  */
-         if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_COS)
-              || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
-              || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
-             && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
-                                 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
-           {
-             tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
-
-             if (tanfn != NULL_TREE)
-               return build_function_call_expr (tanfn,
-                                                TREE_OPERAND (arg0, 1));
-           }
-
-         /* Optimize cos(x)/sin(x) as 1.0/tan(x).  */
-         if (((fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_SIN)
-              || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
-              || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
-             && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
-                                 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
-           {
-             tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
-
-             if (tanfn != NULL_TREE)
-               {
-                 tree tmp = TREE_OPERAND (arg0, 1);
-                 tmp = build_function_call_expr (tanfn, tmp);
-                 return fold (build2 (RDIV_EXPR, type,
-                                      build_real (type, dconst1), tmp));
-               }
-           }
-
-         /* Optimize pow(x,c)/x as pow(x,c-1).  */
-         if (fcode0 == BUILT_IN_POW
-             || fcode0 == BUILT_IN_POWF
-             || fcode0 == BUILT_IN_POWL)
-           {
-             tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
-             tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
-             if (TREE_CODE (arg01) == REAL_CST
-                 && ! TREE_CONSTANT_OVERFLOW (arg01)
-                 && operand_equal_p (arg1, arg00, 0))
-               {
-                 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
-                 REAL_VALUE_TYPE c;
-                 tree arg, arglist;
-
-                 c = TREE_REAL_CST (arg01);
-                 real_arithmetic (&c, MINUS_EXPR, &c, &dconst1);
-                 arg = build_real (type, c);
-                 arglist = build_tree_list (NULL_TREE, arg);
-                 arglist = tree_cons (NULL_TREE, arg1, arglist);
-                 return build_function_call_expr (powfn, arglist);
-               }
-           }
-       }
-      goto binary;
-
-    case TRUNC_DIV_EXPR:
-    case ROUND_DIV_EXPR:
-    case FLOOR_DIV_EXPR:
-    case CEIL_DIV_EXPR:
-    case EXACT_DIV_EXPR:
-      if (integer_onep (arg1))
-       return non_lvalue (fold_convert (type, arg0));
-      if (integer_zerop (arg1))
-       return t;
-      /* X / -1 is -X.  */
-      if (!TYPE_UNSIGNED (type)
-         && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
-         && TREE_INT_CST_HIGH (arg1) == -1)
-       return fold_convert (type, negate_expr (arg0));
-
-      /* If arg0 is a multiple of arg1, then rewrite to the fastest div
-        operation, EXACT_DIV_EXPR.
-
-        Note that only CEIL_DIV_EXPR and FLOOR_DIV_EXPR are rewritten now.
-        At one time others generated faster code, it's not clear if they do
-        after the last round to changes to the DIV code in expmed.c.  */
-      if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
-         && multiple_of_p (type, arg0, arg1))
-       return fold (build2 (EXACT_DIV_EXPR, type, arg0, arg1));
-
-      if (TREE_CODE (arg1) == INTEGER_CST
-         && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
-                                        code, NULL_TREE)))
-       return fold_convert (type, tem);
-
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_div (type, arg0, arg1, code);
-         if (tem)
-           return tem;
-       }
-      goto binary;
-
-    case CEIL_MOD_EXPR:
-    case FLOOR_MOD_EXPR:
-    case ROUND_MOD_EXPR:
-    case TRUNC_MOD_EXPR:
-      /* X % 1 is always zero, but be sure to preserve any side
-        effects in X.  */
-      if (integer_onep (arg1))
-       return omit_one_operand (type, integer_zero_node, arg0);
-
-      /* X % 0, return X % 0 unchanged so that we can get the
-        proper warnings and errors.  */
-      if (integer_zerop (arg1))
-       return t;
-
-      /* 0 % X is always zero, but be sure to preserve any side
-        effects in X.  Place this after checking for X == 0.  */
-      if (integer_zerop (arg0))
-       return omit_one_operand (type, integer_zero_node, arg1);
-
-      /* X % -1 is zero.  */
-      if (!TYPE_UNSIGNED (type)
-         && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
-         && TREE_INT_CST_HIGH (arg1) == -1)
-       return omit_one_operand (type, integer_zero_node, arg0);
-
-      /* Optimize unsigned TRUNC_MOD_EXPR by a power of two into a
-        BIT_AND_EXPR, i.e. "X % C" into "X & C2".  */
-      if (code == TRUNC_MOD_EXPR
-         && TYPE_UNSIGNED (type)
-         && integer_pow2p (arg1))
-       {
-         unsigned HOST_WIDE_INT high, low;
-         tree mask;
-         int l;
-
-         l = tree_log2 (arg1);
-         if (l >= HOST_BITS_PER_WIDE_INT)
-           {
-             high = ((unsigned HOST_WIDE_INT) 1
-                     << (l - HOST_BITS_PER_WIDE_INT)) - 1;
-             low = -1;
-           }
-         else
-           {
-             high = 0;
-             low = ((unsigned HOST_WIDE_INT) 1 << l) - 1;
-           }
-
-         mask = build_int_cst_wide (type, low, high);
-         return fold (build2 (BIT_AND_EXPR, type,
-                              fold_convert (type, arg0), mask));
-       }
-
-      /* X % -C is the same as X % C.  */
-      if (code == TRUNC_MOD_EXPR
-         && !TYPE_UNSIGNED (type)
-         && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_INT_CST_HIGH (arg1) < 0
-         && !flag_trapv
-         /* Avoid this transformation if C is INT_MIN, i.e. C == -C.  */
-         && !sign_bit_p (arg1, arg1))
-       return fold (build2 (code, type, fold_convert (type, arg0),
-                            fold_convert (type, negate_expr (arg1))));
-
-      /* X % -Y is the same as X % Y.  */
-      if (code == TRUNC_MOD_EXPR
-         && !TYPE_UNSIGNED (type)
-         && TREE_CODE (arg1) == NEGATE_EXPR
-         && !flag_trapv)
-       return fold (build2 (code, type, fold_convert (type, arg0),
-                            fold_convert (type, TREE_OPERAND (arg1, 0))));
-
-      if (TREE_CODE (arg1) == INTEGER_CST
-         && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
-                                        code, NULL_TREE)))
-       return fold_convert (type, tem);
-
-      goto binary;
-
-    case LROTATE_EXPR:
-    case RROTATE_EXPR:
-      if (integer_all_onesp (arg0))
-       return omit_one_operand (type, arg0, arg1);
-      goto shift;
-
-    case RSHIFT_EXPR:
-      /* Optimize -1 >> x for arithmetic right shifts.  */
-      if (integer_all_onesp (arg0) && !TYPE_UNSIGNED (type))
-       return omit_one_operand (type, arg0, arg1);
-      /* ... fall through ...  */
-
-    case LSHIFT_EXPR:
-    shift:
-      if (integer_zerop (arg1))
-       return non_lvalue (fold_convert (type, arg0));
-      if (integer_zerop (arg0))
-       return omit_one_operand (type, arg0, arg1);
-
-      /* Since negative shift count is not well-defined,
-        don't try to compute it in the compiler.  */
-      if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
-       return t;
-      /* Rewrite an LROTATE_EXPR by a constant into an
-        RROTATE_EXPR by a new constant.  */
-      if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
-       {
-         tree tem = build_int_cst (NULL_TREE,
-                                   GET_MODE_BITSIZE (TYPE_MODE (type)));
-         tem = fold_convert (TREE_TYPE (arg1), tem);
-         tem = const_binop (MINUS_EXPR, tem, arg1, 0);
-         return fold (build2 (RROTATE_EXPR, type, arg0, tem));
-       }
-
-      /* If we have a rotate of a bit operation with the rotate count and
-        the second operand of the bit operation both constant,
-        permute the two operations.  */
-      if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
-         && (TREE_CODE (arg0) == BIT_AND_EXPR
-             || TREE_CODE (arg0) == BIT_IOR_EXPR
-             || TREE_CODE (arg0) == BIT_XOR_EXPR)
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
-       return fold (build2 (TREE_CODE (arg0), type,
-                            fold (build2 (code, type,
-                                          TREE_OPERAND (arg0, 0), arg1)),
-                            fold (build2 (code, type,
-                                          TREE_OPERAND (arg0, 1), arg1))));
-
-      /* Two consecutive rotates adding up to the width of the mode can
-        be ignored.  */
-      if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_CODE (arg0) == RROTATE_EXPR
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-         && TREE_INT_CST_HIGH (arg1) == 0
-         && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
-         && ((TREE_INT_CST_LOW (arg1)
-              + TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
-             == (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type))))
-       return TREE_OPERAND (arg0, 0);
-
-      goto binary;
-
-    case MIN_EXPR:
-      if (operand_equal_p (arg0, arg1, 0))
-       return omit_one_operand (type, arg0, arg1);
-      if (INTEGRAL_TYPE_P (type)
-         && operand_equal_p (arg1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
-       return omit_one_operand (type, arg1, arg0);
-      goto associate;
-
-    case MAX_EXPR:
-      if (operand_equal_p (arg0, arg1, 0))
-       return omit_one_operand (type, arg0, arg1);
-      if (INTEGRAL_TYPE_P (type)
-         && TYPE_MAX_VALUE (type)
-         && operand_equal_p (arg1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
-       return omit_one_operand (type, arg1, arg0);
-      goto associate;
-
-    case TRUTH_ANDIF_EXPR:
-      /* Note that the operands of this must be ints
-        and their values must be 0 or 1.
-        ("true" is a fixed value perhaps depending on the language.)  */
-      /* If first arg is constant zero, return it.  */
-      if (integer_zerop (arg0))
-       return fold_convert (type, arg0);
-    case TRUTH_AND_EXPR:
-      /* If either arg is constant true, drop it.  */
-      if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
-       return non_lvalue (fold_convert (type, arg1));
-      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
-         /* Preserve sequence points.  */
-         && (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
-       return non_lvalue (fold_convert (type, arg0));
-      /* If second arg is constant zero, result is zero, but first arg
-        must be evaluated.  */
-      if (integer_zerop (arg1))
-       return omit_one_operand (type, arg1, arg0);
-      /* Likewise for first arg, but note that only the TRUTH_AND_EXPR
-        case will be handled here.  */
-      if (integer_zerop (arg0))
-       return omit_one_operand (type, arg0, arg1);
-
-      /* !X && X is always false.  */
-      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
-         && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-       return omit_one_operand (type, integer_zero_node, arg1);
-      /* X && !X is always false.  */
-      if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
-         && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-       return omit_one_operand (type, integer_zero_node, arg0);
-
-      /* A < X && A + 1 > Y ==> A < X && A >= Y.  Normally A + 1 > Y
-        means A >= Y && A != MAX, but in this case we know that
-        A < X <= MAX.  */
-
-      if (!TREE_SIDE_EFFECTS (arg0)
-         && !TREE_SIDE_EFFECTS (arg1))
-       {
-         tem = fold_to_nonsharp_ineq_using_bound (arg0, arg1);
-         if (tem)
-           return fold (build2 (code, type, tem, arg1));
-
-         tem = fold_to_nonsharp_ineq_using_bound (arg1, arg0);
-         if (tem)
-           return fold (build2 (code, type, arg0, tem));
-       }
-
-    truth_andor:
-      /* We only do these simplifications if we are optimizing.  */
-      if (!optimize)
-       return t;
-
-      /* Check for things like (A || B) && (A || C).  We can convert this
-        to A || (B && C).  Note that either operator can be any of the four
-        truth and/or operations and the transformation will still be
-        valid.   Also note that we only care about order for the
-        ANDIF and ORIF operators.  If B contains side effects, this
-        might change the truth-value of A.  */
-      if (TREE_CODE (arg0) == TREE_CODE (arg1)
-         && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
-             || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
-             || TREE_CODE (arg0) == TRUTH_AND_EXPR
-             || TREE_CODE (arg0) == TRUTH_OR_EXPR)
-         && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
-       {
-         tree a00 = TREE_OPERAND (arg0, 0);
-         tree a01 = TREE_OPERAND (arg0, 1);
-         tree a10 = TREE_OPERAND (arg1, 0);
-         tree a11 = TREE_OPERAND (arg1, 1);
-         int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
-                             || TREE_CODE (arg0) == TRUTH_AND_EXPR)
-                            && (code == TRUTH_AND_EXPR
-                                || code == TRUTH_OR_EXPR));
-
-         if (operand_equal_p (a00, a10, 0))
-           return fold (build2 (TREE_CODE (arg0), type, a00,
-                                fold (build2 (code, type, a01, a11))));
-         else if (commutative && operand_equal_p (a00, a11, 0))
-           return fold (build2 (TREE_CODE (arg0), type, a00,
-                                fold (build2 (code, type, a01, a10))));
-         else if (commutative && operand_equal_p (a01, a10, 0))
-           return fold (build2 (TREE_CODE (arg0), type, a01,
-                                fold (build2 (code, type, a00, a11))));
-
-         /* This case if tricky because we must either have commutative
-            operators or else A10 must not have side-effects.  */
-
-         else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
-                  && operand_equal_p (a01, a11, 0))
-           return fold (build2 (TREE_CODE (arg0), type,
-                                fold (build2 (code, type, a00, a10)),
-                                a01));
-       }
-
-      /* See if we can build a range comparison.  */
-      if (0 != (tem = fold_range_test (t)))
-       return tem;
-
-      /* Check for the possibility of merging component references.  If our
-        lhs is another similar operation, try to merge its rhs with our
-        rhs.  Then try to merge our lhs and rhs.  */
-      if (TREE_CODE (arg0) == code
-         && 0 != (tem = fold_truthop (code, type,
-                                      TREE_OPERAND (arg0, 1), arg1)))
-       return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
-
-      if ((tem = fold_truthop (code, type, arg0, arg1)) != 0)
-       return tem;
-
-      return t;
-
-    case TRUTH_ORIF_EXPR:
-      /* Note that the operands of this must be ints
-        and their values must be 0 or true.
-        ("true" is a fixed value perhaps depending on the language.)  */
-      /* If first arg is constant true, return it.  */
-      if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
-       return fold_convert (type, arg0);
-    case TRUTH_OR_EXPR:
-      /* If either arg is constant zero, drop it.  */
-      if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
-       return non_lvalue (fold_convert (type, arg1));
-      if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
-         /* Preserve sequence points.  */
-         && (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
-       return non_lvalue (fold_convert (type, arg0));
-      /* If second arg is constant true, result is true, but we must
-        evaluate first arg.  */
-      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
-       return omit_one_operand (type, arg1, arg0);
-      /* Likewise for first arg, but note this only occurs here for
-        TRUTH_OR_EXPR.  */
-      if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
-       return omit_one_operand (type, arg0, arg1);
-
-      /* !X || X is always true.  */
-      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
-         && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-       return omit_one_operand (type, integer_one_node, arg1);
-      /* X || !X is always true.  */
-      if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
-         && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-       return omit_one_operand (type, integer_one_node, arg0);
-
-      goto truth_andor;
-
-    case TRUTH_XOR_EXPR:
-      /* If the second arg is constant zero, drop it.  */
-      if (integer_zerop (arg1))
-       return non_lvalue (fold_convert (type, arg0));
-      /* If the second arg is constant true, this is a logical inversion.  */
-      if (integer_onep (arg1))
-       return non_lvalue (fold_convert (type, invert_truthvalue (arg0)));
-      /* Identical arguments cancel to zero.  */
-      if (operand_equal_p (arg0, arg1, 0))
-       return omit_one_operand (type, integer_zero_node, arg0);
-
-      /* !X ^ X is always true.  */
-      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
-         && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-       return omit_one_operand (type, integer_one_node, arg1);
-
-      /* X ^ !X is always true.  */
-      if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
-         && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-       return omit_one_operand (type, integer_one_node, arg0);
-
-      return t;
-
-    case EQ_EXPR:
-    case NE_EXPR:
-    case LT_EXPR:
-    case GT_EXPR:
-    case LE_EXPR:
-    case GE_EXPR:
-      /* If one arg is a real or integer constant, put it last.  */
-      if (tree_swap_operands_p (arg0, arg1, true))
-       return fold (build2 (swap_tree_comparison (code), type, arg1, arg0));
-
-      /* If this is an equality comparison of the address of a non-weak
-        object against zero, then we know the result.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (arg0) == ADDR_EXPR
-         && DECL_P (TREE_OPERAND (arg0, 0))
-         && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
-         && integer_zerop (arg1))
-       return constant_boolean_node (code != EQ_EXPR, type);
-
-      /* If this is an equality comparison of the address of two non-weak,
-        unaliased symbols neither of which are extern (since we do not
-        have access to attributes for externs), then we know the result.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (arg0) == ADDR_EXPR
-         && DECL_P (TREE_OPERAND (arg0, 0))
-         && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
-         && ! lookup_attribute ("alias",
-                                DECL_ATTRIBUTES (TREE_OPERAND (arg0, 0)))
-         && ! DECL_EXTERNAL (TREE_OPERAND (arg0, 0))
-         && TREE_CODE (arg1) == ADDR_EXPR
-         && DECL_P (TREE_OPERAND (arg1, 0))
-         && ! DECL_WEAK (TREE_OPERAND (arg1, 0))
-         && ! lookup_attribute ("alias",
-                                DECL_ATTRIBUTES (TREE_OPERAND (arg1, 0)))
-         && ! DECL_EXTERNAL (TREE_OPERAND (arg1, 0)))
-       return constant_boolean_node (operand_equal_p (arg0, arg1, 0)
-                                     ? code == EQ_EXPR : code != EQ_EXPR,
-                                     type);
-
-      /* If this is a comparison of two exprs that look like an
-        ARRAY_REF of the same object, then we can fold this to a
-        comparison of the two offsets.  */
-      if (COMPARISON_CLASS_P (t))
-       {
-         tree base0, offset0, base1, offset1;
-
-         if (extract_array_ref (arg0, &base0, &offset0)
-             && extract_array_ref (arg1, &base1, &offset1)
-             && operand_equal_p (base0, base1, 0))
-           {
-             if (offset0 == NULL_TREE
-                 && offset1 == NULL_TREE)
-               {
-                 offset0 = integer_zero_node;
-                 offset1 = integer_zero_node;
-               }
-             else if (offset0 == NULL_TREE)
-               offset0 = build_int_cst (TREE_TYPE (offset1), 0);
-             else if (offset1 == NULL_TREE)
-               offset1 = build_int_cst (TREE_TYPE (offset0), 0);
-
-             if (TREE_TYPE (offset0) == TREE_TYPE (offset1))
-               return fold (build2 (code, type, offset0, offset1));
-           }
-       }
-
-      if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
-       {
-         tree targ0 = strip_float_extensions (arg0);
-         tree targ1 = strip_float_extensions (arg1);
-         tree newtype = TREE_TYPE (targ0);
-
-         if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
-           newtype = TREE_TYPE (targ1);
-
-         /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
-         if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
-           return fold (build2 (code, type, fold_convert (newtype, targ0),
-                                fold_convert (newtype, targ1)));
-
-         /* (-a) CMP (-b) -> b CMP a  */
-         if (TREE_CODE (arg0) == NEGATE_EXPR
-             && TREE_CODE (arg1) == NEGATE_EXPR)
-           return fold (build2 (code, type, TREE_OPERAND (arg1, 0),
-                                TREE_OPERAND (arg0, 0)));
-
-         if (TREE_CODE (arg1) == REAL_CST)
-         {
-           REAL_VALUE_TYPE cst;
-           cst = TREE_REAL_CST (arg1);
-
-           /* (-a) CMP CST -> a swap(CMP) (-CST)  */
-           if (TREE_CODE (arg0) == NEGATE_EXPR)
-             return
-               fold (build2 (swap_tree_comparison (code), type,
-                             TREE_OPERAND (arg0, 0),
-                             build_real (TREE_TYPE (arg1),
-                                         REAL_VALUE_NEGATE (cst))));
-
-           /* IEEE doesn't distinguish +0 and -0 in comparisons.  */
-           /* a CMP (-0) -> a CMP 0  */
-           if (REAL_VALUE_MINUS_ZERO (cst))
-             return fold (build2 (code, type, arg0,
-                                  build_real (TREE_TYPE (arg1), dconst0)));
-
-           /* x != NaN is always true, other ops are always false.  */
-           if (REAL_VALUE_ISNAN (cst)
-               && ! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))))
-             {
-               tem = (code == NE_EXPR) ? integer_one_node : integer_zero_node;
-               return omit_one_operand (type, tem, arg0);
-             }
-
-           /* Fold comparisons against infinity.  */
-           if (REAL_VALUE_ISINF (cst))
-             {
-               tem = fold_inf_compare (code, type, arg0, arg1);
-               if (tem != NULL_TREE)
-                 return tem;
-             }
-         }
-
-         /* If this is a comparison of a real constant with a PLUS_EXPR
-            or a MINUS_EXPR of a real constant, we can convert it into a
-            comparison with a revised real constant as long as no overflow
-            occurs when unsafe_math_optimizations are enabled.  */
-         if (flag_unsafe_math_optimizations
-             && TREE_CODE (arg1) == REAL_CST
-             && (TREE_CODE (arg0) == PLUS_EXPR
-                 || TREE_CODE (arg0) == MINUS_EXPR)
-             && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
-             && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
-                                         ? MINUS_EXPR : PLUS_EXPR,
-                                         arg1, TREE_OPERAND (arg0, 1), 0))
-             && ! TREE_CONSTANT_OVERFLOW (tem))
-           return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
-
-         /* Likewise, we can simplify a comparison of a real constant with
-            a MINUS_EXPR whose first operand is also a real constant, i.e.
-            (c1 - x) < c2 becomes x > c1-c2.  */
-         if (flag_unsafe_math_optimizations
-             && TREE_CODE (arg1) == REAL_CST
-             && TREE_CODE (arg0) == MINUS_EXPR
-             && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST
-             && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
-                                         arg1, 0))
-             && ! TREE_CONSTANT_OVERFLOW (tem))
-           return fold (build2 (swap_tree_comparison (code), type,
-                                TREE_OPERAND (arg0, 1), tem));
-
-         /* Fold comparisons against built-in math functions.  */
-         if (TREE_CODE (arg1) == REAL_CST
-             && flag_unsafe_math_optimizations
-             && ! flag_errno_math)
-           {
-             enum built_in_function fcode = builtin_mathfn_code (arg0);
-
-             if (fcode != END_BUILTINS)
-               {
-                 tem = fold_mathfn_compare (fcode, code, type, arg0, arg1);
-                 if (tem != NULL_TREE)
-                   return tem;
-               }
-           }
-       }
-
-      /* Convert foo++ == CONST into ++foo == CONST + INCR.  */
-      if (TREE_CONSTANT (arg1)
-         && (TREE_CODE (arg0) == POSTINCREMENT_EXPR
-             || TREE_CODE (arg0) == POSTDECREMENT_EXPR)
-         /* This optimization is invalid for ordered comparisons
-            if CONST+INCR overflows or if foo+incr might overflow.
-            This optimization is invalid for floating point due to rounding.
-            For pointer types we assume overflow doesn't happen.  */
-         && (POINTER_TYPE_P (TREE_TYPE (arg0))
-             || (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
-                 && (code == EQ_EXPR || code == NE_EXPR))))
-       {
-         tree varop, newconst;
-
-         if (TREE_CODE (arg0) == POSTINCREMENT_EXPR)
-           {
-             newconst = fold (build2 (PLUS_EXPR, TREE_TYPE (arg0),
-                                      arg1, TREE_OPERAND (arg0, 1)));
-             varop = build2 (PREINCREMENT_EXPR, TREE_TYPE (arg0),
-                             TREE_OPERAND (arg0, 0),
-                             TREE_OPERAND (arg0, 1));
-           }
-         else
-           {
-             newconst = fold (build2 (MINUS_EXPR, TREE_TYPE (arg0),
-                                      arg1, TREE_OPERAND (arg0, 1)));
-             varop = build2 (PREDECREMENT_EXPR, TREE_TYPE (arg0),
-                             TREE_OPERAND (arg0, 0),
-                             TREE_OPERAND (arg0, 1));
-           }
-
-
-         /* If VAROP is a reference to a bitfield, we must mask
-            the constant by the width of the field.  */
-         if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
-             && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))
-             && host_integerp (DECL_SIZE (TREE_OPERAND
-                                          (TREE_OPERAND (varop, 0), 1)), 1))
-           {
-             tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
-             HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (fielddecl), 1);
-             tree folded_compare, shift;
-
-             /* First check whether the comparison would come out
-                always the same.  If we don't do that we would
-                change the meaning with the masking.  */
-             folded_compare = fold (build2 (code, type,
-                                            TREE_OPERAND (varop, 0), arg1));
-             if (integer_zerop (folded_compare)
-                 || integer_onep (folded_compare))
-               return omit_one_operand (type, folded_compare, varop);
-
-             shift = build_int_cst (NULL_TREE,
-                                    TYPE_PRECISION (TREE_TYPE (varop)) - size);
-             shift = fold_convert (TREE_TYPE (varop), shift);
-             newconst = fold (build2 (LSHIFT_EXPR, TREE_TYPE (varop),
-                                      newconst, shift));
-             newconst = fold (build2 (RSHIFT_EXPR, TREE_TYPE (varop),
-                                      newconst, shift));
-           }
-
-         return fold (build2 (code, type, varop, newconst));
-       }
-
-      /* Change X >= C to X > (C - 1) and X < C to X <= (C - 1) if C > 0.
-        This transformation affects the cases which are handled in later
-        optimizations involving comparisons with non-negative constants.  */
-      if (TREE_CODE (arg1) == INTEGER_CST
-         && TREE_CODE (arg0) != INTEGER_CST
-         && tree_int_cst_sgn (arg1) > 0)
-       {
-         switch (code)
-           {
-           case GE_EXPR:
-             arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-             return fold (build2 (GT_EXPR, type, arg0, arg1));
-
-           case LT_EXPR:
-             arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-             return fold (build2 (LE_EXPR, type, arg0, arg1));
-
-           default:
-             break;
-           }
-       }
-
-      /* Comparisons with the highest or lowest possible integer of
-        the specified size will have known values.
-
-        This is quite similar to fold_relational_hi_lo, however,
-        attempts to share the code have been nothing but trouble.  */
-      {
-       int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
-
-       if (TREE_CODE (arg1) == INTEGER_CST
-           && ! TREE_CONSTANT_OVERFLOW (arg1)
-           && width <= 2 * HOST_BITS_PER_WIDE_INT
-           && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-               || POINTER_TYPE_P (TREE_TYPE (arg1))))
-         {
-           HOST_WIDE_INT signed_max_hi;
-           unsigned HOST_WIDE_INT signed_max_lo;
-           unsigned HOST_WIDE_INT max_hi, max_lo, min_hi, min_lo;
-
-           if (width <= HOST_BITS_PER_WIDE_INT)
-             {
-               signed_max_lo = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
-                               - 1;
-               signed_max_hi = 0;
-               max_hi = 0;
-
-               if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
-                 {
-                   max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
-                   min_lo = 0;
-                   min_hi = 0;
-                 }
-               else
-                 {
-                   max_lo = signed_max_lo;
-                   min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
-                   min_hi = -1;
-                 }
-             }
-           else
-             {
-               width -= HOST_BITS_PER_WIDE_INT;
-               signed_max_lo = -1;
-               signed_max_hi = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
-                               - 1;
-               max_lo = -1;
-               min_lo = 0;
-
-               if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
-                 {
-                   max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
-                   min_hi = 0;
-                 }
-               else
-                 {
-                   max_hi = signed_max_hi;
-                   min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
-                 }
-             }
-
-           if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) == max_hi
-               && TREE_INT_CST_LOW (arg1) == max_lo)
-             switch (code)
-               {
-               case GT_EXPR:
-                 return omit_one_operand (type, integer_zero_node, arg0);
-
-               case GE_EXPR:
-                 return fold (build2 (EQ_EXPR, type, arg0, arg1));
-
-               case LE_EXPR:
-                 return omit_one_operand (type, integer_one_node, arg0);
-
-               case LT_EXPR:
-                 return fold (build2 (NE_EXPR, type, arg0, arg1));
-
-               /* The GE_EXPR and LT_EXPR cases above are not normally
-                  reached because of previous transformations.  */
-
-               default:
-                 break;
-               }
-           else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
-                    == max_hi
-                    && TREE_INT_CST_LOW (arg1) == max_lo - 1)
-             switch (code)
-               {
-               case GT_EXPR:
-                 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
-                 return fold (build2 (EQ_EXPR, type, arg0, arg1));
-               case LE_EXPR:
-                 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
-                 return fold (build2 (NE_EXPR, type, arg0, arg1));
-               default:
-                 break;
-               }
-           else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
-                    == min_hi
-                    && TREE_INT_CST_LOW (arg1) == min_lo)
-             switch (code)
-               {
-               case LT_EXPR:
-                 return omit_one_operand (type, integer_zero_node, arg0);
-
-               case LE_EXPR:
-                 return fold (build2 (EQ_EXPR, type, arg0, arg1));
-
-               case GE_EXPR:
-                 return omit_one_operand (type, integer_one_node, arg0);
-
-               case GT_EXPR:
-                 return fold (build2 (NE_EXPR, type, arg0, arg1));
-
-               default:
-                 break;
-               }
-           else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
-                    == min_hi
-                    && TREE_INT_CST_LOW (arg1) == min_lo + 1)
-             switch (code)
-               {
-               case GE_EXPR:
-                 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-                 return fold (build2 (NE_EXPR, type, arg0, arg1));
-               case LT_EXPR:
-                 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
-                 return fold (build2 (EQ_EXPR, type, arg0, arg1));
-               default:
-                 break;
-               }
-
-           else if (!in_gimple_form
-                    && TREE_INT_CST_HIGH (arg1) == signed_max_hi
-                    && TREE_INT_CST_LOW (arg1) == signed_max_lo
-                    && TYPE_UNSIGNED (TREE_TYPE (arg1))
-                    /* signed_type does not work on pointer types.  */
-                    && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
-             {
-               /* The following case also applies to X < signed_max+1
-                  and X >= signed_max+1 because previous transformations.  */
-               if (code == LE_EXPR || code == GT_EXPR)
-                 {
-                   tree st0, st1;
-                   st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0));
-                   st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1));
-                   return fold
-                     (build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
-                              type, fold_convert (st0, arg0),
-                              fold_convert (st1, integer_zero_node)));
-                 }
-             }
-         }
-      }
-
-      /* If this is an EQ or NE comparison of a constant with a PLUS_EXPR or
-        a MINUS_EXPR of a constant, we can convert it into a comparison with
-        a revised constant as long as no overflow occurs.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (arg1) == INTEGER_CST
-         && (TREE_CODE (arg0) == PLUS_EXPR
-             || TREE_CODE (arg0) == MINUS_EXPR)
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-         && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
-                                     ? MINUS_EXPR : PLUS_EXPR,
-                                     arg1, TREE_OPERAND (arg0, 1), 0))
-         && ! TREE_CONSTANT_OVERFLOW (tem))
-       return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
-
-      /* Similarly for a NEGATE_EXPR.  */
-      else if ((code == EQ_EXPR || code == NE_EXPR)
-              && TREE_CODE (arg0) == NEGATE_EXPR
-              && TREE_CODE (arg1) == INTEGER_CST
-              && 0 != (tem = negate_expr (arg1))
-              && TREE_CODE (tem) == INTEGER_CST
-              && ! TREE_CONSTANT_OVERFLOW (tem))
-       return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
-
-      /* If we have X - Y == 0, we can convert that to X == Y and similarly
-        for !=.  Don't do this for ordered comparisons due to overflow.  */
-      else if ((code == NE_EXPR || code == EQ_EXPR)
-              && integer_zerop (arg1) && TREE_CODE (arg0) == MINUS_EXPR)
-       return fold (build2 (code, type,
-                            TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)));
-
-      else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
-              && TREE_CODE (arg0) == NOP_EXPR)
-       {
-         /* If we are widening one operand of an integer comparison,
-            see if the other operand is similarly being widened.  Perhaps we
-            can do the comparison in the narrower type.  */
-         tem = fold_widened_comparison (code, type, arg0, arg1);
-         if (tem)
-           return tem;
-
-         /* Or if we are changing signedness.  */
-         tem = fold_sign_changed_comparison (code, type, arg0, arg1);
-         if (tem)
-           return tem;
-       }
-
-      /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a
-        constant, we can simplify it.  */
-      else if (TREE_CODE (arg1) == INTEGER_CST
-              && (TREE_CODE (arg0) == MIN_EXPR
-                  || TREE_CODE (arg0) == MAX_EXPR)
-              && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
-       return optimize_minmax_comparison (t);
-
-      /* If we are comparing an ABS_EXPR with a constant, we can
-        convert all the cases into explicit comparisons, but they may
-        well not be faster than doing the ABS and one comparison.
-        But ABS (X) <= C is a range comparison, which becomes a subtraction
-        and a comparison, and is probably faster.  */
-      else if (code == LE_EXPR && TREE_CODE (arg1) == INTEGER_CST
-              && TREE_CODE (arg0) == ABS_EXPR
-              && ! TREE_SIDE_EFFECTS (arg0)
-              && (0 != (tem = negate_expr (arg1)))
-              && TREE_CODE (tem) == INTEGER_CST
-              && ! TREE_CONSTANT_OVERFLOW (tem))
-       return fold (build2 (TRUTH_ANDIF_EXPR, type,
-                            build2 (GE_EXPR, type,
-                                    TREE_OPERAND (arg0, 0), tem),
-                            build2 (LE_EXPR, type,
-                                    TREE_OPERAND (arg0, 0), arg1)));
-
-      /* Convert ABS_EXPR<x> >= 0 to true.  */
-      else if (code == GE_EXPR
-              && tree_expr_nonnegative_p (arg0)
-              && (integer_zerop (arg1)
-                  || (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
-                       && real_zerop (arg1))))
-       return omit_one_operand (type, integer_one_node, arg0);
-
-      /* Convert ABS_EXPR<x> < 0 to false.  */
-      else if (code == LT_EXPR
-              && tree_expr_nonnegative_p (arg0)
-              && (integer_zerop (arg1) || real_zerop (arg1)))
-       return omit_one_operand (type, integer_zero_node, arg0);
-
-      /* Convert ABS_EXPR<x> == 0 or ABS_EXPR<x> != 0 to x == 0 or x != 0.  */
-      else if ((code == EQ_EXPR || code == NE_EXPR)
-              && TREE_CODE (arg0) == ABS_EXPR
-              && (integer_zerop (arg1) || real_zerop (arg1)))
-       return fold (build2 (code, type, TREE_OPERAND (arg0, 0), arg1));
-
-      /* If this is an EQ or NE comparison with zero and ARG0 is
-        (1 << foo) & bar, convert it to (bar >> foo) & 1.  Both require
-        two operations, but the latter can be done in one less insn
-        on machines that have only two-operand insns or on which a
-        constant cannot be the first operand.  */
-      if (integer_zerop (arg1) && (code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (arg0) == BIT_AND_EXPR)
-       {
-         tree arg00 = TREE_OPERAND (arg0, 0);
-         tree arg01 = TREE_OPERAND (arg0, 1);
-         if (TREE_CODE (arg00) == LSHIFT_EXPR
-             && integer_onep (TREE_OPERAND (arg00, 0)))
-           return
-             fold (build2 (code, type,
-                           build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
-                                   build2 (RSHIFT_EXPR, TREE_TYPE (arg00),
-                                           arg01, TREE_OPERAND (arg00, 1)),
-                                   fold_convert (TREE_TYPE (arg0),
-                                                 integer_one_node)),
-                           arg1));
-         else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
-                  && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
-           return
-             fold (build2 (code, type,
-                           build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
-                                   build2 (RSHIFT_EXPR, TREE_TYPE (arg01),
-                                           arg00, TREE_OPERAND (arg01, 1)),
-                                   fold_convert (TREE_TYPE (arg0),
-                                                 integer_one_node)),
-                           arg1));
-       }
-
-      /* If this is an NE or EQ comparison of zero against the result of a
-        signed MOD operation whose second operand is a power of 2, make
-        the MOD operation unsigned since it is simpler and equivalent.  */
-      if ((code == NE_EXPR || code == EQ_EXPR)
-         && integer_zerop (arg1)
-         && !TYPE_UNSIGNED (TREE_TYPE (arg0))
-         && (TREE_CODE (arg0) == TRUNC_MOD_EXPR
-             || TREE_CODE (arg0) == CEIL_MOD_EXPR
-             || TREE_CODE (arg0) == FLOOR_MOD_EXPR
-             || TREE_CODE (arg0) == ROUND_MOD_EXPR)
-         && integer_pow2p (TREE_OPERAND (arg0, 1)))
-       {
-         tree newtype = lang_hooks.types.unsigned_type (TREE_TYPE (arg0));
-         tree newmod = fold (build2 (TREE_CODE (arg0), newtype,
-                                     fold_convert (newtype,
-                                                   TREE_OPERAND (arg0, 0)),
-                                     fold_convert (newtype,
-                                                   TREE_OPERAND (arg0, 1))));
-
-         return fold (build2 (code, type, newmod,
-                              fold_convert (newtype, arg1)));
-       }
-
-      /* If this is an NE comparison of zero with an AND of one, remove the
-        comparison since the AND will give the correct value.  */
-      if (code == NE_EXPR && integer_zerop (arg1)
-         && TREE_CODE (arg0) == BIT_AND_EXPR
-         && integer_onep (TREE_OPERAND (arg0, 1)))
-       return fold_convert (type, arg0);
-
-      /* If we have (A & C) == C where C is a power of 2, convert this into
-        (A & C) != 0.  Similarly for NE_EXPR.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (arg0) == BIT_AND_EXPR
-         && integer_pow2p (TREE_OPERAND (arg0, 1))
-         && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
-       return fold (build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
-                            arg0, fold_convert (TREE_TYPE (arg0),
-                                                integer_zero_node)));
-
-      /* If we have (A & C) != 0 or (A & C) == 0 and C is a power of
-        2, then fold the expression into shifts and logical operations.  */
-      tem = fold_single_bit_test (code, arg0, arg1, type);
-      if (tem)
-       return tem;
-
-      /* If we have (A & C) == D where D & ~C != 0, convert this into 0.
-        Similarly for NE_EXPR.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (arg0) == BIT_AND_EXPR
-         && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
-       {
-         tree notc = fold (build1 (BIT_NOT_EXPR,
-                                   TREE_TYPE (TREE_OPERAND (arg0, 1)),
-                                   TREE_OPERAND (arg0, 1)));
-         tree dandnotc = fold (build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
-                                       arg1, notc));
-         tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
-         if (integer_nonzerop (dandnotc))
-           return omit_one_operand (type, rslt, arg0);
-       }
-
-      /* If we have (A | C) == D where C & ~D != 0, convert this into 0.
-        Similarly for NE_EXPR.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (arg0) == BIT_IOR_EXPR
-         && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
-       {
-         tree notd = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1));
-         tree candnotd = fold (build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
-                                       TREE_OPERAND (arg0, 1), notd));
-         tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
-         if (integer_nonzerop (candnotd))
-           return omit_one_operand (type, rslt, arg0);
-       }
-
-      /* If X is unsigned, convert X < (1 << Y) into X >> Y == 0
-        and similarly for >= into !=.  */
-      if ((code == LT_EXPR || code == GE_EXPR)
-         && TYPE_UNSIGNED (TREE_TYPE (arg0))
-         && TREE_CODE (arg1) == LSHIFT_EXPR
-         && integer_onep (TREE_OPERAND (arg1, 0)))
-       return build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
-                      build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
-                              TREE_OPERAND (arg1, 1)),
-                      fold_convert (TREE_TYPE (arg0), integer_zero_node));
-
-      else if ((code == LT_EXPR || code == GE_EXPR)
-              && TYPE_UNSIGNED (TREE_TYPE (arg0))
-              && (TREE_CODE (arg1) == NOP_EXPR
-                  || TREE_CODE (arg1) == CONVERT_EXPR)
-              && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
-              && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
-       return
-         build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
-                 fold_convert (TREE_TYPE (arg0),
-                               build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
-                                       TREE_OPERAND (TREE_OPERAND (arg1, 0),
-                                                     1))),
-                 fold_convert (TREE_TYPE (arg0), integer_zero_node));
-
-      /* Simplify comparison of something with itself.  (For IEEE
-        floating-point, we can only do some of these simplifications.)  */
-      if (operand_equal_p (arg0, arg1, 0))
-       {
-         switch (code)
-           {
-           case EQ_EXPR:
-             if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
-                 || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
-               return constant_boolean_node (1, type);
-             break;
-
-           case GE_EXPR:
-           case LE_EXPR:
-             if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
-                 || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
-               return constant_boolean_node (1, type);
-             return fold (build2 (EQ_EXPR, type, arg0, arg1));
-
-           case NE_EXPR:
-             /* For NE, we can only do this simplification if integer
-                or we don't honor IEEE floating point NaNs.  */
-             if (FLOAT_TYPE_P (TREE_TYPE (arg0))
-                 && HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
-               break;
-             /* ... fall through ...  */
-           case GT_EXPR:
-           case LT_EXPR:
-             return constant_boolean_node (0, type);
-           default:
-             gcc_unreachable ();
-           }
-       }
-
-      /* If we are comparing an expression that just has comparisons
-        of two integer values, arithmetic expressions of those comparisons,
-        and constants, we can simplify it.  There are only three cases
-        to check: the two values can either be equal, the first can be
-        greater, or the second can be greater.  Fold the expression for
-        those three values.  Since each value must be 0 or 1, we have
-        eight possibilities, each of which corresponds to the constant 0
-        or 1 or one of the six possible comparisons.
-
-        This handles common cases like (a > b) == 0 but also handles
-        expressions like  ((x > y) - (y > x)) > 0, which supposedly
-        occur in macroized code.  */
-
-      if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST)
-       {
-         tree cval1 = 0, cval2 = 0;
-         int save_p = 0;
-
-         if (twoval_comparison_p (arg0, &cval1, &cval2, &save_p)
-             /* Don't handle degenerate cases here; they should already
-                have been handled anyway.  */
-             && cval1 != 0 && cval2 != 0
-             && ! (TREE_CONSTANT (cval1) && TREE_CONSTANT (cval2))
-             && TREE_TYPE (cval1) == TREE_TYPE (cval2)
-             && INTEGRAL_TYPE_P (TREE_TYPE (cval1))
-             && TYPE_MAX_VALUE (TREE_TYPE (cval1))
-             && TYPE_MAX_VALUE (TREE_TYPE (cval2))
-             && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)),
-                                   TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0))
-           {
-             tree maxval = TYPE_MAX_VALUE (TREE_TYPE (cval1));
-             tree minval = TYPE_MIN_VALUE (TREE_TYPE (cval1));
-
-             /* We can't just pass T to eval_subst in case cval1 or cval2
-                was the same as ARG1.  */
-
-             tree high_result
-               = fold (build2 (code, type,
-                               eval_subst (arg0, cval1, maxval,
-                                           cval2, minval),
-                               arg1));
-             tree equal_result
-               = fold (build2 (code, type,
-                               eval_subst (arg0, cval1, maxval,
-                                           cval2, maxval),
-                               arg1));
-             tree low_result
-               = fold (build2 (code, type,
-                               eval_subst (arg0, cval1, minval,
-                                           cval2, maxval),
-                               arg1));
-
-             /* All three of these results should be 0 or 1.  Confirm they
-                are.  Then use those values to select the proper code
-                to use.  */
-
-             if ((integer_zerop (high_result)
-                  || integer_onep (high_result))
-                 && (integer_zerop (equal_result)
-                     || integer_onep (equal_result))
-                 && (integer_zerop (low_result)
-                     || integer_onep (low_result)))
-               {
-                 /* Make a 3-bit mask with the high-order bit being the
-                    value for `>', the next for '=', and the low for '<'.  */
-                 switch ((integer_onep (high_result) * 4)
-                         + (integer_onep (equal_result) * 2)
-                         + integer_onep (low_result))
-                   {
-                   case 0:
-                     /* Always false.  */
-                     return omit_one_operand (type, integer_zero_node, arg0);
-                   case 1:
-                     code = LT_EXPR;
-                     break;
-                   case 2:
-                     code = EQ_EXPR;
-                     break;
-                   case 3:
-                     code = LE_EXPR;
-                     break;
-                   case 4:
-                     code = GT_EXPR;
-                     break;
-                   case 5:
-                     code = NE_EXPR;
-                     break;
-                   case 6:
-                     code = GE_EXPR;
-                     break;
-                   case 7:
-                     /* Always true.  */
-                     return omit_one_operand (type, integer_one_node, arg0);
-                   }
-
-                 tem = build2 (code, type, cval1, cval2);
-                 if (save_p)
-                   return save_expr (tem);
-                 else
-                   return fold (tem);
-               }
-           }
-       }
-
-      /* If this is a comparison of a field, we may be able to simplify it.  */
-      if (((TREE_CODE (arg0) == COMPONENT_REF
-           && lang_hooks.can_use_bit_fields_p ())
-          || TREE_CODE (arg0) == BIT_FIELD_REF)
-         && (code == EQ_EXPR || code == NE_EXPR)
-         /* Handle the constant case even without -O
-            to make sure the warnings are given.  */
-         && (optimize || TREE_CODE (arg1) == INTEGER_CST))
-       {
-         t1 = optimize_bit_field_compare (code, type, arg0, arg1);
-         if (t1)
-           return t1;
-       }
-
-      /* If this is a comparison of complex values and either or both sides
-        are a COMPLEX_EXPR or COMPLEX_CST, it is best to split up the
-        comparisons and join them with a TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR.
-        This may prevent needless evaluations.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE
-         && (TREE_CODE (arg0) == COMPLEX_EXPR
-             || TREE_CODE (arg1) == COMPLEX_EXPR
-             || TREE_CODE (arg0) == COMPLEX_CST
-             || TREE_CODE (arg1) == COMPLEX_CST))
-       {
-         tree subtype = TREE_TYPE (TREE_TYPE (arg0));
-         tree real0, imag0, real1, imag1;
-
-         arg0 = save_expr (arg0);
-         arg1 = save_expr (arg1);
-         real0 = fold (build1 (REALPART_EXPR, subtype, arg0));
-         imag0 = fold (build1 (IMAGPART_EXPR, subtype, arg0));
-         real1 = fold (build1 (REALPART_EXPR, subtype, arg1));
-         imag1 = fold (build1 (IMAGPART_EXPR, subtype, arg1));
-
-         return fold (build2 ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR
-                               : TRUTH_ORIF_EXPR),
-                              type,
-                              fold (build2 (code, type, real0, real1)),
-                              fold (build2 (code, type, imag0, imag1))));
-       }
-
-      /* Optimize comparisons of strlen vs zero to a compare of the
-        first character of the string vs zero.  To wit,
-               strlen(ptr) == 0   =>  *ptr == 0
-               strlen(ptr) != 0   =>  *ptr != 0
-        Other cases should reduce to one of these two (or a constant)
-        due to the return value of strlen being unsigned.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && integer_zerop (arg1)
-         && TREE_CODE (arg0) == CALL_EXPR)
-       {
-         tree fndecl = get_callee_fndecl (arg0);
-         tree arglist;
-
-         if (fndecl
-             && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-             && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
-             && (arglist = TREE_OPERAND (arg0, 1))
-             && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
-             && ! TREE_CHAIN (arglist))
-           return fold (build2 (code, type,
-                                build1 (INDIRECT_REF, char_type_node,
-                                        TREE_VALUE (arglist)),
-                                fold_convert (char_type_node,
-                                              integer_zero_node)));
-       }
-
-      /* We can fold X/C1 op C2 where C1 and C2 are integer constants
-        into a single range test.  */
-      if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR
-          || TREE_CODE (arg0) == EXACT_DIV_EXPR)
-         && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-         && !integer_zerop (TREE_OPERAND (arg0, 1))
-         && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
-         && !TREE_OVERFLOW (arg1))
-       {
-         t1 = fold_div_compare (code, type, arg0, arg1);
-         if (t1 != NULL_TREE)
-           return t1;
-       }
-
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && !TREE_SIDE_EFFECTS (arg0)
-         && integer_zerop (arg1)
-         && tree_expr_nonzero_p (arg0))
-       return constant_boolean_node (code==NE_EXPR, type);
-
-      t1 = fold_relational_const (code, type, arg0, arg1);
-      return t1 == NULL_TREE ? t : t1;
-
-    case UNORDERED_EXPR:
-    case ORDERED_EXPR:
-    case UNLT_EXPR:
-    case UNLE_EXPR:
-    case UNGT_EXPR:
-    case UNGE_EXPR:
-    case UNEQ_EXPR:
-    case LTGT_EXPR:
-      if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
-       {
-         t1 = fold_relational_const (code, type, arg0, arg1);
-         if (t1 != NULL_TREE)
-           return t1;
-       }
-
-      /* If the first operand is NaN, the result is constant.  */
-      if (TREE_CODE (arg0) == REAL_CST
-         && REAL_VALUE_ISNAN (TREE_REAL_CST (arg0))
-         && (code != LTGT_EXPR || ! flag_trapping_math))
-       {
-         t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
-              ? integer_zero_node
-              : integer_one_node;
-         return omit_one_operand (type, t1, arg1);
-       }
-
-      /* If the second operand is NaN, the result is constant.  */
-      if (TREE_CODE (arg1) == REAL_CST
-         && REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
-         && (code != LTGT_EXPR || ! flag_trapping_math))
-       {
-         t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
-              ? integer_zero_node
-              : integer_one_node;
-         return omit_one_operand (type, t1, arg0);
-       }
-
-      /* Simplify unordered comparison of something with itself.  */
-      if ((code == UNLE_EXPR || code == UNGE_EXPR || code == UNEQ_EXPR)
-         && operand_equal_p (arg0, arg1, 0))
-       return constant_boolean_node (1, type);
-
-      if (code == LTGT_EXPR
-         && !flag_trapping_math
-         && operand_equal_p (arg0, arg1, 0))
-       return constant_boolean_node (0, type);
-
-      /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
-      {
-       tree targ0 = strip_float_extensions (arg0);
-       tree targ1 = strip_float_extensions (arg1);
-       tree newtype = TREE_TYPE (targ0);
-
-       if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
-         newtype = TREE_TYPE (targ1);
-
-       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
-         return fold (build2 (code, type, fold_convert (newtype, targ0),
-                              fold_convert (newtype, targ1)));
-      }
-
-      return t;
-
-    case COMPOUND_EXPR:
-      /* When pedantic, a compound expression can be neither an lvalue
-        nor an integer constant expression.  */
-      if (TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1))
-       return t;
-      /* Don't let (0, 0) be null pointer constant.  */
-      tem = integer_zerop (arg1) ? build1 (NOP_EXPR, type, arg1)
-                                : fold_convert (type, arg1);
-      return pedantic_non_lvalue (tem);
-
-    case COMPLEX_EXPR:
-      if (wins)
-       return build_complex (type, arg0, arg1);
-      return t;
-
     default:
       return t;
     } /* switch (code) */