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.  */
>
>

Reply via email to