aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2015-10-27 11:57:34 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2015-10-27 11:57:34 +0000
commit0122e8e5212582669a58272d3fcc4beba9f42d58 (patch)
tree745740d734f1d7a2350948b3d5b6f428d3620a3c
parent783879e617bf3b4d0d94ccabb9a6f40b43c985a2 (diff)
downloadgcc-0122e8e5212582669a58272d3fcc4beba9f42d58.zip
gcc-0122e8e5212582669a58272d3fcc4beba9f42d58.tar.gz
gcc-0122e8e5212582669a58272d3fcc4beba9f42d58.tar.bz2
Move fmin and fmax folds to match.pd
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/builtins.c53
-rw-r--r--gcc/match.pd27
3 files changed, 36 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff593e1..b4e1018 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6cd8879..86eac5c 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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,
diff --git a/gcc/match.pd b/gcc/match.pd
index 8de7987..7309006 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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. */