Move fmin and fmax folds to match.pd
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 27 Oct 2015 11:57:34 +0000 (11:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 27 Oct 2015 11:57:34 +0000 (11:57 +0000)
Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.

gcc/
* builtins.c (fold_builtin_fmin_fmax): Delete.
(fold_builtin_2): Handle constant fmin and fmax arguments here.
* match.pd: Add rules previously handled by fold_builtin_fmin_fmax.

From-SVN: r229432

gcc/ChangeLog
gcc/builtins.c
gcc/match.pd

index ff593e13cb8529b19c44d57275ba7ac87d958c79..b4e1018a3768b5a7776e07be80afab85d5c60305 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-27  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * builtins.c (fold_builtin_fmin_fmax): Delete.
+       (fold_builtin_2): Handle constant fmin and fmax arguments here.
+       * match.pd: Add rules previously handled by fold_builtin_fmin_fmax.
+
 2015-10-27  Evandro Menezes  <e.menezes@samsung.com>
 
        * config/aarch64/aarch64-protos.h (cpu_addrcost_table): Split member
index 6cd8879e12d56580f5d902c121de1e515aa133f3..86eac5c66fd2842e05b282c629000480edd64334 100644 (file)
@@ -7891,51 +7891,6 @@ fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
   return NULL_TREE;
 }
 
-/* Fold a call to builtin fmin or fmax.  */
-
-static tree
-fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
-                       tree type, bool max)
-{
-  if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
-    {
-      /* Calculate the result when the argument is a constant.  */
-      tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
-
-      if (res)
-       return res;
-
-      /* If either argument is NaN, return the other one.  Avoid the
-        transformation if we get (and honor) a signalling NaN.  Using
-        omit_one_operand() ensures we create a non-lvalue.  */
-      if (TREE_CODE (arg0) == REAL_CST
-         && real_isnan (&TREE_REAL_CST (arg0))
-         && (! HONOR_SNANS (arg0)
-             || ! TREE_REAL_CST (arg0).signalling))
-       return omit_one_operand_loc (loc, type, arg1, arg0);
-      if (TREE_CODE (arg1) == REAL_CST
-         && real_isnan (&TREE_REAL_CST (arg1))
-         && (! HONOR_SNANS (arg1)
-             || ! TREE_REAL_CST (arg1).signalling))
-       return omit_one_operand_loc (loc, type, arg0, arg1);
-
-      /* Transform fmin/fmax(x,x) -> x.  */
-      if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
-       return omit_one_operand_loc (loc, type, arg0, arg1);
-
-      /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
-        functions to return the numeric arg if the other one is NaN.
-        These tree codes don't honor that, so only transform if
-        -ffinite-math-only is set.  C99 doesn't require -0.0 to be
-        handled, so we don't have to worry about it either.  */
-      if (flag_finite_math_only)
-       return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
-                           fold_convert_loc (loc, type, arg0),
-                           fold_convert_loc (loc, type, arg1));
-    }
-  return NULL_TREE;
-}
-
 /* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
 
 static tree
@@ -9241,10 +9196,14 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
       break;
 
     CASE_FLT_FN (BUILT_IN_FMIN):
-      return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
+      if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
+       return do_mpfr_arg2 (arg0, arg1, type, mpfr_min);
+      break;
 
     CASE_FLT_FN (BUILT_IN_FMAX):
-      return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
+      if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
+       return do_mpfr_arg2 (arg0, arg1, type, mpfr_max);
+      break;
 
     case BUILT_IN_ISGREATER:
       return fold_builtin_unordered_cmp (loc, fndecl,
index 8de798765be269c802ea7c7a8388c93c44ff08ed..73090066d3a67be371009c78ab8cb1543be32855 100644 (file)
@@ -103,6 +103,8 @@ DEFINE_MATH_FN (CABS)
 DEFINE_MATH_FN (TRUNC)
 DEFINE_MATH_FN (NEARBYINT)
 DEFINE_MATH_FN (SIGNBIT)
+DEFINE_MATH_FN (FMIN)
+DEFINE_MATH_FN (FMAX)
 
 DEFINE_INT_AND_FLOAT_ROUND_FN (FLOOR)
 DEFINE_INT_AND_FLOAT_ROUND_FN (CEIL)
@@ -1170,9 +1172,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      (minus (convert @1) (convert @2)))))))
 
 
-/* Simplifications of MIN_EXPR and MAX_EXPR.  */
+/* Simplifications of MIN_EXPR, MAX_EXPR, fmin() and fmax().  */
 
-(for minmax (min max)
+(for minmax (min max FMIN FMAX)
  (simplify
   (minmax @0 @0)
   @0))
@@ -1196,7 +1198,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && TYPE_MAX_VALUE (type)
       && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
   @1))
-
+(for minmax (FMIN FMAX)
+ /* If either argument is NaN, return the other one.  Avoid the
+    transformation if we get (and honor) a signalling NaN.  */
+ (simplify
+  (minmax:c @0 REAL_CST@1)
+  (if (real_isnan (TREE_REAL_CST_PTR (@1))
+       && (!HONOR_SNANS (@1) || !TREE_REAL_CST (@1).signalling))
+   @0)))
+/* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
+   functions to return the numeric arg if the other one is NaN.
+   MIN and MAX don't honor that, so only transform if -ffinite-math-only
+   is set.  C99 doesn't require -0.0 to be handled, so we don't have to
+   worry about it either.  */
+(if (flag_finite_math_only)
+ (simplify
+  (FMIN @0 @1)
+  (min @0 @1))
+ (simplify
+  (FMAX @0 @1)
+  (max @0 @1)))
 
 /* Simplifications of shift and rotates.  */