fold-const.c (fold): Prefer fold_convert (negate_expr (...)) to fold (build1 (NEGATE_...
authorRoger Sayle <roger@eyesopen.com>
Mon, 26 Apr 2004 03:43:17 +0000 (03:43 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 26 Apr 2004 03:43:17 +0000 (03:43 +0000)
* fold-const.c (fold): Prefer fold_convert (negate_expr (...)) to
fold (build1 (NEGATE_EXPR, ...)).  Optimize X / -1 as -X and
X % -1 as 0.

From-SVN: r81177

gcc/ChangeLog
gcc/fold-const.c

index f9f097fe242800b1e261a6bef49a953d0d79f387..6cb1567b24d27867980f4b4f7e1eaf2a63699eb2 100644 (file)
@@ -1,3 +1,9 @@
+2004-04-25  Roger Sayle  <roger@eyesopen.com>
+
+       * fold-const.c (fold): Prefer fold_convert (negate_expr (...)) to
+       fold (build1 (NEGATE_EXPR, ...)).  Optimize X / -1 as -X and
+       X % -1 as 0.
+
 2004-04-26  Hans-Peter Nilsson  <hp@bitrange.com>
 
        PR bootstrap/15141
index 86fd91065b0ff03d2f730d933f964642bc056c80..57ae918392c6179162969c4214f2561fda68cfeb 100644 (file)
@@ -6412,7 +6412,7 @@ fold (tree expr)
          /* Transform x * -1.0 into -x.  */
          if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
              && real_minus_onep (arg1))
-           return fold (build1 (NEGATE_EXPR, type, arg0));
+           return fold_convert (type, negate_expr (arg0));
 
          /* Convert (C1/X)*C2 into (C1*C2)/X.  */
          if (flag_unsafe_math_optimizations
@@ -6768,9 +6768,9 @@ fold (tree expr)
          if (BUILTIN_EXPONENT_P (fcode))
            {
              tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
-             tree arg = build1 (NEGATE_EXPR, type,
-                                TREE_VALUE (TREE_OPERAND (arg1, 1)));
-             tree arglist = build_tree_list (NULL_TREE, fold (arg));
+             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 (build (MULT_EXPR, type, arg0, arg1));
            }
@@ -6783,7 +6783,7 @@ fold (tree expr)
              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 (build1 (NEGATE_EXPR, type, arg11));
+             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);
@@ -6864,6 +6864,12 @@ fold (tree expr)
        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.
@@ -6890,6 +6896,12 @@ fold (tree expr)
        return omit_one_operand (type, integer_zero_node, arg0);
       if (integer_zerop (arg1))
        return t;
+      /* 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);
 
       if (TREE_CODE (arg1) == INTEGER_CST
          && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,