From 0122e8e5212582669a58272d3fcc4beba9f42d58 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 27 Oct 2015 11:57:34 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++++ gcc/builtins.c | 53 ++++++-------------------------------------------- gcc/match.pd | 27 ++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 50 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff593e13cb8..b4e1018a376 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-10-27 Richard Sandiford + + * 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 * config/aarch64/aarch64-protos.h (cpu_addrcost_table): Split member diff --git a/gcc/builtins.c b/gcc/builtins.c index 6cd8879e12d..86eac5c66fd 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 8de798765be..73090066d3a 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. */ -- 2.30.2