On Mon, Oct 26, 2015 at 11:02 AM, Richard Sandiford <richard.sandif...@arm.com> wrote: > Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. > OK to install?
Ok. Thanks, Richard. > Thanks, > Richard > > > 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. > > 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 338644c..f2e7d64 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. */ > >