OSDN Git Service

libgo: Define CC_FOR_BUILD in Makefile.
[pf3gnuchains/gcc-fork.git] / gcc / fold-const.c
index 9baa9eb..9640264 100644 (file)
@@ -141,6 +141,15 @@ static tree fold_not_const (const_tree, tree);
 static tree fold_relational_const (enum tree_code, tree, tree, tree);
 static tree fold_convert_const (enum tree_code, tree, tree);
 
+/* Return EXPR_LOCATION of T if it is not UNKNOWN_LOCATION.
+   Otherwise, return LOC.  */
+
+static location_t
+expr_location_or (tree t, location_t loc)
+{
+  location_t tloc = EXPR_LOCATION (t);
+  return tloc != UNKNOWN_LOCATION ? tloc : loc;
+}
 
 /* Similar to protected_set_expr_location, but never modify x in place,
    if location can and needs to be set, unshare it.  */
@@ -927,12 +936,10 @@ int_binop_types_match_p (enum tree_code code, const_tree type1, const_tree type2
 
 /* Combine two integer constants ARG1 and ARG2 under operation CODE
    to produce a new constant.  Return NULL_TREE if we don't know how
-   to evaluate CODE at compile-time.
-
-   If NOTRUNC is nonzero, do not truncate the result to fit the data type.  */
+   to evaluate CODE at compile-time.  */
 
 tree
-int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int notrunc)
+int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
 {
   double_int op1, op2, res, tmp;
   tree t;
@@ -1074,22 +1081,9 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int notr
       return NULL_TREE;
     }
 
-  if (notrunc)
-    {
-      t = build_int_cst_wide (TREE_TYPE (arg1), res.low, res.high);
-
-      /* Propagate overflow flags ourselves.  */
-      if (((!uns || is_sizetype) && overflow)
-         | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
-       {
-         t = copy_node (t);
-         TREE_OVERFLOW (t) = 1;
-       }
-    }
-  else
-    t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
-                              ((!uns || is_sizetype) && overflow)
-                              | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
+  t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
+                            ((!uns || is_sizetype) && overflow)
+                            | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
 
   return t;
 }
@@ -1110,7 +1104,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
   STRIP_NOPS (arg2);
 
   if (TREE_CODE (arg1) == INTEGER_CST)
-    return int_const_binop (code, arg1, arg2, 0);
+    return int_const_binop (code, arg1, arg2);
 
   if (TREE_CODE (arg1) == REAL_CST)
     {
@@ -1455,7 +1449,7 @@ size_binop_loc (location_t loc, enum tree_code code, tree arg0, tree arg1)
        }
 
       /* Handle general case of two integer constants.  */
-      return int_const_binop (code, arg0, arg1, 0);
+      return int_const_binop (code, arg0, arg1);
     }
 
   return fold_build2_loc (loc, code, type, arg0, arg1);
@@ -2020,8 +2014,6 @@ fold_convert_loc (location_t loc, tree type, tree arg)
 
     case VOID_TYPE:
       tem = fold_ignored_result (arg);
-      if (TREE_CODE (tem) == MODIFY_EXPR)
-       goto fold_convert_exit;
       return fold_build1_loc (loc, NOP_EXPR, type, tem);
 
     default:
@@ -2466,9 +2458,12 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
      equal if they have no side effects.  If we have two identical
      expressions with side effects that should be treated the same due
      to the only side effects being identical SAVE_EXPR's, that will
-     be detected in the recursive calls below.  */
+     be detected in the recursive calls below.
+     If we are taking an invariant address of two identical objects
+     they are necessarily equal as well.  */
   if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
       && (TREE_CODE (arg0) == SAVE_EXPR
+         || (flags & OEP_CONSTANT_ADDRESS_OF)
          || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
     return 1;
 
@@ -2531,7 +2526,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 
       case ADDR_EXPR:
        return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
-                               0);
+                               TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1)
+                               ? OEP_CONSTANT_ADDRESS_OF : 0);
       default:
        break;
       }
@@ -3079,23 +3075,15 @@ fold_truth_not_expr (location_t loc, tree arg)
       return constant_boolean_node (integer_zerop (arg), type);
 
     case TRUTH_AND_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
-      loc2 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
-      if (loc2 == UNKNOWN_LOCATION)
-       loc2 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
+      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
       return build2_loc (loc, TRUTH_OR_EXPR, type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
                         invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
 
     case TRUTH_OR_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
-      loc2 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
-      if (loc2 == UNKNOWN_LOCATION)
-       loc2 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
+      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
       return build2_loc (loc, TRUTH_AND_EXPR, type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
                         invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
@@ -3115,23 +3103,15 @@ fold_truth_not_expr (location_t loc, tree arg)
                           TREE_OPERAND (arg, 1));
 
     case TRUTH_ANDIF_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
-      loc2 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
-      if (loc2 == UNKNOWN_LOCATION)
-       loc2 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
+      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
       return build2_loc (loc, TRUTH_ORIF_EXPR, type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
                         invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
 
     case TRUTH_ORIF_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
-      loc2 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
-      if (loc2 == UNKNOWN_LOCATION)
-       loc2 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
+      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
       return build2_loc (loc, TRUTH_ANDIF_EXPR, type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
                         invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
@@ -3144,12 +3124,8 @@ fold_truth_not_expr (location_t loc, tree arg)
        tree arg1 = TREE_OPERAND (arg, 1);
        tree arg2 = TREE_OPERAND (arg, 2);
 
-       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
-       loc2 = EXPR_LOCATION (TREE_OPERAND (arg, 2));
-       if (loc1 == UNKNOWN_LOCATION)
-         loc1 = loc;
-       if (loc2 == UNKNOWN_LOCATION)
-         loc2 = loc;
+       loc1 = expr_location_or (TREE_OPERAND (arg, 1), loc);
+       loc2 = expr_location_or (TREE_OPERAND (arg, 2), loc);
 
        /* A COND_EXPR may have a throw as one operand, which
           then has void type.  Just leave void operands
@@ -3162,17 +3138,13 @@ fold_truth_not_expr (location_t loc, tree arg)
       }
 
     case COMPOUND_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 1), loc);
       return build2_loc (loc, COMPOUND_EXPR, type,
                         TREE_OPERAND (arg, 0),
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 1)));
 
     case NON_LVALUE_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
       return invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0));
 
     CASE_CONVERT:
@@ -3182,9 +3154,7 @@ fold_truth_not_expr (location_t loc, tree arg)
       /* ... fall through ...  */
 
     case FLOAT_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
       return build1_loc (loc, TREE_CODE (arg), type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
 
@@ -3197,9 +3167,7 @@ fold_truth_not_expr (location_t loc, tree arg)
       return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);
 
     case CLEANUP_POINT_EXPR:
-      loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
-      if (loc1 == UNKNOWN_LOCATION)
-       loc1 = loc;
+      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
       return build1_loc (loc, CLEANUP_POINT_EXPR, type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
 
@@ -4854,7 +4822,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type,
   if ((lhs == 0 || rhs == 0 || operand_equal_p (lhs, rhs, 0))
       && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
                       in1_p, low1, high1)
-      && 0 != (tem = (build_range_check (UNKNOWN_LOCATION, type,
+      && 0 != (tem = (build_range_check (loc, type,
                                         lhs != 0 ? lhs
                                         : rhs != 0 ? rhs : integer_zero_node,
                                         in_p, low, high))))
@@ -4881,8 +4849,8 @@ fold_range_test (location_t loc, enum tree_code code, tree type,
                           ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
                           type, op0, op1);
 
-      else if (lang_hooks.decls.global_bindings_p () == 0
-              && ! CONTAINS_PLACEHOLDER_P (lhs))
+      else if (!lang_hooks.decls.global_bindings_p ()
+              && !CONTAINS_PLACEHOLDER_P (lhs))
        {
          tree common = save_expr (lhs);
 
@@ -5890,16 +5858,33 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
 
       /* If these are the same operation types, we can associate them
         assuming no overflow.  */
-      if (tcode == code
-         && 0 != (t1 = int_const_binop (MULT_EXPR,
-                                        fold_convert (ctype, op1),
-                                        fold_convert (ctype, c), 1))
-         && 0 != (t1 = force_fit_type_double (ctype, tree_to_double_int (t1),
-                                              (TYPE_UNSIGNED (ctype)
-                                               && tcode != MULT_EXPR) ? -1 : 1,
-                                              TREE_OVERFLOW (t1)))
-         && !TREE_OVERFLOW (t1))
-       return fold_build2 (tcode, ctype, fold_convert (ctype, op0), t1);
+      if (tcode == code)
+       {
+         double_int mul;
+         int overflow_p;
+         mul = double_int_mul_with_sign
+                 (double_int_ext
+                    (tree_to_double_int (op1),
+                     TYPE_PRECISION (ctype), TYPE_UNSIGNED (ctype)),
+                  double_int_ext
+                    (tree_to_double_int (c),
+                     TYPE_PRECISION (ctype), TYPE_UNSIGNED (ctype)),
+                  false, &overflow_p);
+         overflow_p = (((!TYPE_UNSIGNED (ctype)
+                         || (TREE_CODE (ctype) == INTEGER_TYPE
+                             && TYPE_IS_SIZETYPE (ctype)))
+                        && overflow_p)
+                       | TREE_OVERFLOW (c) | TREE_OVERFLOW (op1));
+         if (!double_int_fits_to_tree_p (ctype, mul)
+             && ((TYPE_UNSIGNED (ctype) && tcode != MULT_EXPR)
+                 || !TYPE_UNSIGNED (ctype)
+                 || (TREE_CODE (ctype) == INTEGER_TYPE
+                     && TYPE_IS_SIZETYPE (ctype))))
+           overflow_p = 1;
+         if (!overflow_p)
+           return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
+                               double_int_to_tree (ctype, mul));
+       }
 
       /* If these operations "cancel" each other, we have the main
         optimizations of this pass, which occur when either constant is a
@@ -6163,10 +6148,6 @@ fold_mathfn_compare (location_t loc,
                                    build_real (TREE_TYPE (arg), dconst0));
 
              /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
-             if (lang_hooks.decls.global_bindings_p () != 0
-                 || CONTAINS_PLACEHOLDER_P (arg))
-               return NULL_TREE;
-
              arg = save_expr (arg);
              return fold_build2_loc (loc, TRUTH_ANDIF_EXPR, type,
                                  fold_build2_loc (loc, GE_EXPR, type, arg,
@@ -6183,18 +6164,14 @@ fold_mathfn_compare (location_t loc,
                                build_real (TREE_TYPE (arg), c2));
 
          /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
-         if (lang_hooks.decls.global_bindings_p () == 0
-             && ! CONTAINS_PLACEHOLDER_P (arg))
-           {
-             arg = save_expr (arg);
-             return fold_build2_loc (loc, TRUTH_ANDIF_EXPR, type,
+         arg = save_expr (arg);
+         return fold_build2_loc (loc, TRUTH_ANDIF_EXPR, type,
                                  fold_build2_loc (loc, GE_EXPR, type, arg,
                                               build_real (TREE_TYPE (arg),
                                                           dconst0)),
                                  fold_build2_loc (loc, code, type, arg,
                                               build_real (TREE_TYPE (arg),
                                                           c2)));
-           }
        }
     }
 
@@ -6241,13 +6218,8 @@ fold_inf_compare (location_t loc, enum tree_code code, tree type,
        return omit_one_operand_loc (loc, type, integer_one_node, arg0);
 
       /* x <= +Inf is the same as x == x, i.e. isfinite(x).  */
-      if (lang_hooks.decls.global_bindings_p () == 0
-         && ! CONTAINS_PLACEHOLDER_P (arg0))
-       {
-         arg0 = save_expr (arg0);
-         return fold_build2_loc (loc, EQ_EXPR, type, arg0, arg0);
-       }
-      break;
+      arg0 = save_expr (arg0);
+      return fold_build2_loc (loc, EQ_EXPR, type, arg0, arg0);
 
     case EQ_EXPR:
     case GE_EXPR:
@@ -6304,7 +6276,7 @@ fold_div_compare (location_t loc,
   int overflow;
 
   /* We have to do this the hard way to detect unsigned overflow.
-     prod = int_const_binop (MULT_EXPR, arg01, arg1, 0);  */
+     prod = int_const_binop (MULT_EXPR, arg01, arg1);  */
   overflow = mul_double_with_sign (TREE_INT_CST_LOW (arg01),
                                   TREE_INT_CST_HIGH (arg01),
                                   TREE_INT_CST_LOW (arg1),
@@ -6316,10 +6288,10 @@ fold_div_compare (location_t loc,
   if (unsigned_p)
     {
       tmp = int_const_binop (MINUS_EXPR, arg01,
-                             build_int_cst (TREE_TYPE (arg01), 1), 0);
+                             build_int_cst (TREE_TYPE (arg01), 1));
       lo = prod;
 
-      /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp, 0).  */
+      /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp).  */
       overflow = add_double_with_sign (TREE_INT_CST_LOW (prod),
                                       TREE_INT_CST_HIGH (prod),
                                       TREE_INT_CST_LOW (tmp),
@@ -6331,12 +6303,12 @@ fold_div_compare (location_t loc,
   else if (tree_int_cst_sgn (arg01) >= 0)
     {
       tmp = int_const_binop (MINUS_EXPR, arg01,
-                            build_int_cst (TREE_TYPE (arg01), 1), 0);
+                            build_int_cst (TREE_TYPE (arg01), 1));
       switch (tree_int_cst_sgn (arg1))
        {
        case -1:
          neg_overflow = true;
-         lo = int_const_binop (MINUS_EXPR, prod, tmp, 0);
+         lo = int_const_binop (MINUS_EXPR, prod, tmp);
          hi = prod;
          break;
 
@@ -6346,7 +6318,7 @@ fold_div_compare (location_t loc,
          break;
 
        case  1:
-          hi = int_const_binop (PLUS_EXPR, prod, tmp, 0);
+          hi = int_const_binop (PLUS_EXPR, prod, tmp);
          lo = prod;
          break;
 
@@ -6360,11 +6332,11 @@ fold_div_compare (location_t loc,
       code = swap_tree_comparison (code);
 
       tmp = int_const_binop (PLUS_EXPR, arg01,
-                            build_int_cst (TREE_TYPE (arg01), 1), 0);
+                            build_int_cst (TREE_TYPE (arg01), 1));
       switch (tree_int_cst_sgn (arg1))
        {
        case -1:
-         hi = int_const_binop (MINUS_EXPR, prod, tmp, 0);
+         hi = int_const_binop (MINUS_EXPR, prod, tmp);
          lo = prod;
          break;
 
@@ -6375,7 +6347,7 @@ fold_div_compare (location_t loc,
 
        case  1:
          neg_overflow = true;
-         lo = int_const_binop (PLUS_EXPR, prod, tmp, 0);
+         lo = int_const_binop (PLUS_EXPR, prod, tmp);
          hi = prod;
          break;
 
@@ -7589,7 +7561,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
   if (arg0)
     {
       if (CONVERT_EXPR_CODE_P (code)
-         || code == FLOAT_EXPR || code == ABS_EXPR)
+         || code == FLOAT_EXPR || code == ABS_EXPR || code == NEGATE_EXPR)
        {
          /* Don't use STRIP_NOPS, because signedness of argument type
             matters.  */
@@ -7667,21 +7639,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
                                                    0)));
          return tem;
        }
-      else if (COMPARISON_CLASS_P (arg0))
-       {
-         if (TREE_CODE (type) == BOOLEAN_TYPE)
-           {
-             arg0 = copy_node (arg0);
-             TREE_TYPE (arg0) = type;
-             return arg0;
-           }
-         else if (TREE_CODE (type) != INTEGER_TYPE)
-           return fold_build3_loc (loc, COND_EXPR, type, arg0,
-                               fold_build1_loc (loc, code, type,
-                                            integer_one_node),
-                               fold_build1_loc (loc, code, type,
-                                            integer_zero_node));
-       }
    }
 
   switch (code)
@@ -7700,11 +7657,23 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
       if (TREE_TYPE (op0) == type)
        return op0;
 
-      /* If we have (type) (a CMP b) and type is an integral type, return
-         new expression involving the new type.  */
-      if (COMPARISON_CLASS_P (op0) && INTEGRAL_TYPE_P (type))
-       return fold_build2_loc (loc, TREE_CODE (op0), type, TREE_OPERAND (op0, 0),
-                           TREE_OPERAND (op0, 1));
+      if (COMPARISON_CLASS_P (op0))
+       {
+         /* If we have (type) (a CMP b) and type is an integral type, return
+            new expression involving the new type.  Canonicalize
+            (type) (a CMP b) to (a CMP b) ? (type) true : (type) false for
+            non-integral type.
+            Do not fold the result as that would not simplify further, also
+            folding again results in recursions.  */
+         if (INTEGRAL_TYPE_P (type))
+           return build2_loc (loc, TREE_CODE (op0), type,
+                              TREE_OPERAND (op0, 0),
+                              TREE_OPERAND (op0, 1));
+         else
+           return build3_loc (loc, COND_EXPR, type, op0,
+                              fold_convert (type, boolean_true_node),
+                              fold_convert (type, boolean_false_node));
+       }
 
       /* Handle cases of two conversions in a row.  */
       if (CONVERT_EXPR_P (op0))
@@ -8242,6 +8211,97 @@ fold_unary_ignore_overflow_loc (location_t loc, enum tree_code code,
   return res;
 }
 
+/* Fold a binary bitwise/truth expression of code CODE and type TYPE with
+   operands OP0 and OP1.  LOC is the location of the resulting expression.
+   ARG0 and ARG1 are the NOP_STRIPed results of OP0 and OP1.
+   Return the folded expression if folding is successful.  Otherwise,
+   return NULL_TREE.  */
+static tree
+fold_truth_andor (location_t loc, enum tree_code code, tree type,
+                 tree arg0, tree arg1, tree op0, tree op1)
+{
+  tree tem;
+
+  /* We only do these simplifications if we are optimizing.  */
+  if (!optimize)
+    return NULL_TREE;
+
+  /* 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_loc (loc, TREE_CODE (arg0), type, a00,
+                           fold_build2_loc (loc, code, type, a01, a11));
+      else if (commutative && operand_equal_p (a00, a11, 0))
+       return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
+                           fold_build2_loc (loc, code, type, a01, a10));
+      else if (commutative && operand_equal_p (a01, a10, 0))
+       return fold_build2_loc (loc, TREE_CODE (arg0), type, a01,
+                           fold_build2_loc (loc, 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_loc (loc, TREE_CODE (arg0), type,
+                           fold_build2_loc (loc, code, type, a00, a10),
+                           a01);
+    }
+
+  /* See if we can build a range comparison.  */
+  if (0 != (tem = fold_range_test (loc, code, type, op0, op1)))
+    return tem;
+
+  if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg0) == TRUTH_ORIF_EXPR)
+      || (code == TRUTH_ORIF_EXPR && TREE_CODE (arg0) == TRUTH_ANDIF_EXPR))
+    {
+      tem = merge_truthop_with_opposite_arm (loc, arg0, arg1, true);
+      if (tem)
+       return fold_build2_loc (loc, code, type, tem, arg1);
+    }
+
+  if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg1) == TRUTH_ORIF_EXPR)
+      || (code == TRUTH_ORIF_EXPR && TREE_CODE (arg1) == TRUTH_ANDIF_EXPR))
+    {
+      tem = merge_truthop_with_opposite_arm (loc, arg1, arg0, false);
+      if (tem)
+       return fold_build2_loc (loc, code, type, arg0, 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 (loc, code, type,
+                                  TREE_OPERAND (arg0, 1), arg1)))
+    return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);
+
+  if ((tem = fold_truthop (loc, code, type, arg0, arg1)) != 0)
+    return tem;
+
+  return NULL_TREE;
+}
+
 /* Fold a binary expression of code CODE and type TYPE with operands
    OP0 and OP1, containing either a MIN-MAX or a MAX-MIN combination.
    Return the folded expression if folding is successful.  Otherwise,
@@ -8385,7 +8445,7 @@ maybe_canonicalize_comparison_1 (location_t loc, enum tree_code code, tree type,
     return NULL_TREE;
 
   t = int_const_binop (sgn0 == -1 ? PLUS_EXPR : MINUS_EXPR,
-                      cst0, build_int_cst (TREE_TYPE (cst0), 1), 0);
+                      cst0, build_int_cst (TREE_TYPE (cst0), 1));
   if (code0 != INTEGER_CST)
     t = fold_build2_loc (loc, code0, TREE_TYPE (arg0), TREE_OPERAND (arg0, 0), t);
 
@@ -8820,7 +8880,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
         of lower absolute value than before.  */
       cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
                             ? MINUS_EXPR : PLUS_EXPR,
-                            const2, const1, 0);
+                            const2, const1);
       if (!TREE_OVERFLOW (cst)
          && tree_int_cst_compare (const2, cst) == tree_int_cst_sgn (const2))
        {
@@ -8834,7 +8894,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
 
       cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
                             ? MINUS_EXPR : PLUS_EXPR,
-                            const1, const2, 0);
+                            const1, const2);
       if (!TREE_OVERFLOW (cst)
          && tree_int_cst_compare (const1, cst) == tree_int_cst_sgn (const1))
        {
@@ -9249,30 +9309,10 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue,
   code = TREE_CODE (expr);
   if (code == ADDR_EXPR)
     {
-      expr = TREE_OPERAND (expr, 0);
-      if (handled_component_p (expr))
-       {
-         HOST_WIDE_INT bitsize, bitpos;
-         tree offset;
-         enum machine_mode mode;
-         int unsignedp, volatilep;
-
-         expr = get_inner_reference (expr, &bitsize, &bitpos, &offset,
-                                     &mode, &unsignedp, &volatilep, false);
-         *residue = bitpos / BITS_PER_UNIT;
-         if (offset)
-           {
-             if (TREE_CODE (offset) == INTEGER_CST)
-               *residue += TREE_INT_CST_LOW (offset);
-             else
-               /* We don't handle more complicated offset expressions.  */
-               return 1;
-           }
-       }
-
-      if (DECL_P (expr)
-         && (allow_func_align || TREE_CODE (expr) != FUNCTION_DECL))
-       return DECL_ALIGN_UNIT (expr);
+      unsigned int bitalign;
+      bitalign = get_object_alignment_1 (TREE_OPERAND (expr, 0), residue);
+      *residue /= BITS_PER_UNIT;
+      return bitalign / BITS_PER_UNIT;
     }
   else if (code == POINTER_PLUS_EXPR)
     {
@@ -9317,9 +9357,9 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue,
        }
     }
 
-    /* If we get here, we were unable to determine anything useful about the
-       expression.  */
-    return 1;
+  /* If we get here, we were unable to determine anything useful about the
+     expression.  */
+  return 1;
 }
 
 
@@ -9495,7 +9535,7 @@ fold_binary_loc (location_t loc,
          return fold_build2 (MEM_REF, type,
                              TREE_OPERAND (iref, 0),
                              int_const_binop (PLUS_EXPR, arg1,
-                                              TREE_OPERAND (iref, 1), 0));
+                                              TREE_OPERAND (iref, 1)));
        }
 
       /* MEM[&a.b, CST2] -> MEM[&a, offsetof (a, b) + CST2].  */
@@ -9511,7 +9551,7 @@ fold_binary_loc (location_t loc,
          return fold_build2 (MEM_REF, type,
                              build_fold_addr_expr (base),
                              int_const_binop (PLUS_EXPR, arg1,
-                                              size_int (coffset), 0));
+                                              size_int (coffset)));
        }
 
       return NULL_TREE;
@@ -9535,13 +9575,6 @@ fold_binary_loc (location_t loc,
                                              fold_convert_loc (loc, sizetype,
                                                                arg0)));
 
-      /* index +p PTR -> PTR +p index */
-      if (POINTER_TYPE_P (TREE_TYPE (arg1))
-         && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
-        return fold_build2_loc (loc, POINTER_PLUS_EXPR, type,
-                           fold_convert_loc (loc, type, arg1),
-                           fold_convert_loc (loc, sizetype, arg0));
-
       /* (PTR +p B) +p A -> PTR +p (B + A) */
       if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
        {
@@ -10570,7 +10603,8 @@ fold_binary_loc (location_t loc,
                }
 
              /* Optimize x*x as pow(x,2.0), which is expanded as x*x.  */
-             if (optimize_function_for_speed_p (cfun)
+             if (!in_gimple_form
+                 && optimize_function_for_speed_p (cfun)
                  && operand_equal_p (arg0, arg1, 0))
                {
                  tree powfn = mathfn_built_in (type, BUILT_IN_POW);
@@ -10699,6 +10733,28 @@ fold_binary_loc (location_t loc,
          && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
        return omit_one_operand_loc (loc, type, arg0, TREE_OPERAND (arg1, 0));
 
+      /* (X & ~Y) | (~X & Y) is X ^ Y */
+      if (TREE_CODE (arg0) == BIT_AND_EXPR
+         && TREE_CODE (arg1) == BIT_AND_EXPR)
+        {
+         tree a0, a1, l0, l1, n0, n1;
+
+         a0 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
+         a1 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));
+
+         l0 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
+         l1 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
+         
+         n0 = fold_build1_loc (loc, BIT_NOT_EXPR, type, l0);
+         n1 = fold_build1_loc (loc, BIT_NOT_EXPR, type, l1);
+         
+         if ((operand_equal_p (n0, a0, 0)
+              && operand_equal_p (n1, a1, 0))
+             || (operand_equal_p (n0, a1, 0)
+                 && operand_equal_p (n1, a0, 0)))
+           return fold_build2_loc (loc, BIT_XOR_EXPR, type, l0, n1);
+       }
+
       t1 = distribute_bit_expr (loc, code, type, arg0, arg1);
       if (t1 != NULL_TREE)
        return t1;
@@ -10894,13 +10950,19 @@ fold_binary_loc (location_t loc,
       if (operand_equal_p (arg0, arg1, 0))
        return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
 
-      /* ~X & X is always zero.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
+      /* ~X & X, (X == 0) & X, and !X & X are always zero.  */
+      if ((TREE_CODE (arg0) == BIT_NOT_EXPR
+          || TREE_CODE (arg0) == TRUTH_NOT_EXPR
+          || (TREE_CODE (arg0) == EQ_EXPR
+              && integer_zerop (TREE_OPERAND (arg0, 1))))
          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
        return omit_one_operand_loc (loc, type, integer_zero_node, arg1);
 
-      /* X & ~X is always zero.  */
-      if (TREE_CODE (arg1) == BIT_NOT_EXPR
+      /* X & ~X , X & (X == 0), and X & !X are always zero.  */
+      if ((TREE_CODE (arg1) == BIT_NOT_EXPR
+          || TREE_CODE (arg1) == TRUTH_NOT_EXPR
+          || (TREE_CODE (arg1) == EQ_EXPR
+              && integer_zerop (TREE_OPERAND (arg1, 1))))
          && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
        return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
 
@@ -10961,6 +11023,14 @@ fold_binary_loc (location_t loc,
                                           build_int_cst (TREE_TYPE (tem), 1)),
                              build_int_cst (TREE_TYPE (tem), 0));
        }
+      /* Fold !X & 1 as X == 0.  */
+      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
+         && integer_onep (arg1))
+       {
+         tem = TREE_OPERAND (arg0, 0);
+         return fold_build2_loc (loc, EQ_EXPR, type, tem,
+                                 build_int_cst (TREE_TYPE (tem), 0));
+       }
 
       /* Fold (X ^ Y) & Y as ~X & Y.  */
       if (TREE_CODE (arg0) == BIT_XOR_EXPR
@@ -11548,7 +11618,7 @@ fold_binary_loc (location_t loc,
 
            return fold_build2_loc (loc, RSHIFT_EXPR, type,
                          TREE_OPERAND (arg0, 0),
-                         build_int_cst (NULL_TREE, pow2));
+                         build_int_cst (integer_type_node, pow2));
          }
        }
 
@@ -11580,7 +11650,9 @@ fold_binary_loc (location_t loc,
                                       WARN_STRICT_OVERFLOW_MISC);
 
              sh_cnt = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (sh_cnt),
-                                   sh_cnt, build_int_cst (NULL_TREE, pow2));
+                                       sh_cnt,
+                                       build_int_cst (TREE_TYPE (sh_cnt),
+                                                      pow2));
              return fold_build2_loc (loc, RSHIFT_EXPR, type,
                                  fold_convert_loc (loc, type, arg0), sh_cnt);
            }
@@ -11828,7 +11900,7 @@ fold_binary_loc (location_t loc,
              arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
 
              lshift = build_int_cst (type, -1);
-             lshift = int_const_binop (code, lshift, arg1, 0);
+             lshift = int_const_binop (code, lshift, arg1);
 
              return fold_build2_loc (loc, BIT_AND_EXPR, type, arg00, lshift);
            }
@@ -11965,83 +12037,9 @@ fold_binary_loc (location_t loc,
            return fold_build2_loc (loc, code, type, arg0, tem);
        }
 
-    truth_andor:
-      /* We only do these simplifications if we are optimizing.  */
-      if (!optimize)
-       return NULL_TREE;
-
-      /* 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_loc (loc, TREE_CODE (arg0), type, a00,
-                               fold_build2_loc (loc, code, type, a01, a11));
-         else if (commutative && operand_equal_p (a00, a11, 0))
-           return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
-                               fold_build2_loc (loc, code, type, a01, a10));
-         else if (commutative && operand_equal_p (a01, a10, 0))
-           return fold_build2_loc (loc, TREE_CODE (arg0), type, a01,
-                               fold_build2_loc (loc, 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_loc (loc, TREE_CODE (arg0), type,
-                               fold_build2_loc (loc, code, type, a00, a10),
-                               a01);
-       }
-
-      /* See if we can build a range comparison.  */
-      if (0 != (tem = fold_range_test (loc, code, type, op0, op1)))
-       return tem;
-
-      if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg0) == TRUTH_ORIF_EXPR)
-         || (code == TRUTH_ORIF_EXPR && TREE_CODE (arg0) == TRUTH_ANDIF_EXPR))
-       {
-         tem = merge_truthop_with_opposite_arm (loc, arg0, arg1, true);
-         if (tem)
-           return fold_build2_loc (loc, code, type, tem, arg1);
-       }
-
-      if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg1) == TRUTH_ORIF_EXPR)
-         || (code == TRUTH_ORIF_EXPR && TREE_CODE (arg1) == TRUTH_ANDIF_EXPR))
-       {
-         tem = merge_truthop_with_opposite_arm (loc, arg1, arg0, false);
-         if (tem)
-           return fold_build2_loc (loc, code, type, arg0, 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 (loc, code, type,
-                                      TREE_OPERAND (arg0, 1), arg1)))
-       return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);
-
-      if ((tem = fold_truthop (loc, code, type, arg0, arg1)) != 0)
-       return tem;
+      if ((tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1))
+          != NULL_TREE)
+        return tem;
 
       return NULL_TREE;
 
@@ -12078,7 +12076,33 @@ fold_binary_loc (location_t loc,
          && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
        return omit_one_operand_loc (loc, type, integer_one_node, arg0);
 
-      goto truth_andor;
+      /* (X && !Y) || (!X && Y) is X ^ Y */
+      if (TREE_CODE (arg0) == TRUTH_AND_EXPR
+         && TREE_CODE (arg1) == TRUTH_AND_EXPR)
+        {
+         tree a0, a1, l0, l1, n0, n1;
+
+         a0 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
+         a1 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));
+
+         l0 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
+         l1 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
+         
+         n0 = fold_build1_loc (loc, TRUTH_NOT_EXPR, type, l0);
+         n1 = fold_build1_loc (loc, TRUTH_NOT_EXPR, type, l1);
+         
+         if ((operand_equal_p (n0, a0, 0)
+              && operand_equal_p (n1, a1, 0))
+             || (operand_equal_p (n0, a1, 0)
+                 && operand_equal_p (n1, a0, 0)))
+           return fold_build2_loc (loc, TRUTH_XOR_EXPR, type, l0, n1);
+       }
+
+      if ((tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1))
+          != NULL_TREE)
+        return tem;
+
+      return NULL_TREE;
 
     case TRUTH_XOR_EXPR:
       /* If the second arg is constant zero, drop it.  */
@@ -12362,14 +12386,6 @@ fold_binary_loc (location_t loc,
            }
        }
 
-      /* 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_loc (loc, 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 (TREE_CODE (arg0) == BIT_AND_EXPR
@@ -12625,13 +12641,21 @@ fold_binary_loc (location_t loc,
             operand_equal_p guarantees no side-effects so we don't need
             to use omit_one_operand on Z.  */
          if (operand_equal_p (arg01, arg11, 0))
-           return fold_build2_loc (loc, code, type, arg00, arg10);
+           return fold_build2_loc (loc, code, type, arg00,
+                                   fold_convert_loc (loc, TREE_TYPE (arg00),
+                                                     arg10));
          if (operand_equal_p (arg01, arg10, 0))
-           return fold_build2_loc (loc, code, type, arg00, arg11);
+           return fold_build2_loc (loc, code, type, arg00,
+                                   fold_convert_loc (loc, TREE_TYPE (arg00),
+                                                     arg11));
          if (operand_equal_p (arg00, arg11, 0))
-           return fold_build2_loc (loc, code, type, arg01, arg10);
+           return fold_build2_loc (loc, code, type, arg01,
+                                   fold_convert_loc (loc, TREE_TYPE (arg01),
+                                                     arg10));
          if (operand_equal_p (arg00, arg10, 0))
-           return fold_build2_loc (loc, code, type, arg01, arg11);
+           return fold_build2_loc (loc, code, type, arg01,
+                                   fold_convert_loc (loc, TREE_TYPE (arg01),
+                                                     arg11));
 
          /* Optimize (X ^ C1) op (Y ^ C2) as (X ^ (C1 ^ C2)) op Y.  */
          if (TREE_CODE (arg01) == INTEGER_CST
@@ -13327,7 +13351,8 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
                                             TREE_OPERAND (arg0, 1))
          && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2))))
        {
-         tem = fold_truth_not_expr (loc, arg0);
+         location_t loc0 = expr_location_or (arg0, loc);
+         tem = fold_truth_not_expr (loc0, arg0);
          if (tem && COMPARISON_CLASS_P (tem))
            {
              tem = fold_cond_expr_with_comparison (loc, type, tem, op2, op1);
@@ -13341,10 +13366,11 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
       if (truth_value_p (TREE_CODE (arg0))
          && tree_swap_operands_p (op1, op2, false))
        {
+         location_t loc0 = expr_location_or (arg0, loc);
          /* See if this can be inverted.  If it can't, possibly because
             it was a floating-point inequality comparison, don't do
             anything.  */
-         tem = fold_truth_not_expr (loc, arg0);
+         tem = fold_truth_not_expr (loc0, arg0);
          if (tem)
            return fold_build3_loc (loc, code, type, tem, op2, op1);
        }
@@ -13489,8 +13515,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
          && truth_value_p (TREE_CODE (arg0))
          && truth_value_p (TREE_CODE (arg1)))
        {
+         location_t loc0 = expr_location_or (arg0, loc);
          /* Only perform transformation if ARG0 is easily inverted.  */
-         tem = fold_truth_not_expr (loc, arg0);
+         tem = fold_truth_not_expr (loc0, arg0);
          if (tem)
            return fold_build2_loc (loc, TRUTH_ORIF_EXPR, type,
                                fold_convert_loc (loc, type, tem),
@@ -13502,8 +13529,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
          && truth_value_p (TREE_CODE (arg0))
          && truth_value_p (TREE_CODE (op2)))
        {
+         location_t loc0 = expr_location_or (arg0, loc);
          /* Only perform transformation if ARG0 is easily inverted.  */
-         tem = fold_truth_not_expr (loc, arg0);
+         tem = fold_truth_not_expr (loc0, arg0);
          if (tem)
            return fold_build2_loc (loc, TRUTH_ANDIF_EXPR, type,
                                fold_convert_loc (loc, type, tem),
@@ -13813,7 +13841,8 @@ recursive_label:
   if (TREE_CODE_CLASS (code) != tcc_type
       && TREE_CODE_CLASS (code) != tcc_declaration
       && code != TREE_LIST
-      && code != SSA_NAME)
+      && code != SSA_NAME
+      && CODE_CONTAINS_STRUCT (code, TS_COMMON))
     fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
   switch (TREE_CODE_CLASS (code))
     {
@@ -14343,7 +14372,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom)
                  || tree_int_cst_sgn (bottom) < 0)))
        return 0;
       return integer_zerop (int_const_binop (TRUNC_MOD_EXPR,
-                                            top, bottom, 0));
+                                            top, bottom));
 
     default:
       return 0;