Commit 0122e8e5 by Richard Sandiford Committed by Richard Sandiford

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
parent 783879e6
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> 2015-10-27 Evandro Menezes <e.menezes@samsung.com>
* config/aarch64/aarch64-protos.h (cpu_addrcost_table): Split member * config/aarch64/aarch64-protos.h (cpu_addrcost_table): Split member
...@@ -7891,51 +7891,6 @@ fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type) ...@@ -7891,51 +7891,6 @@ fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
return NULL_TREE; 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). */ /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
static tree static tree
...@@ -9241,10 +9196,14 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1) ...@@ -9241,10 +9196,14 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
break; break;
CASE_FLT_FN (BUILT_IN_FMIN): 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): 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: case BUILT_IN_ISGREATER:
return fold_builtin_unordered_cmp (loc, fndecl, return fold_builtin_unordered_cmp (loc, fndecl,
......
...@@ -103,6 +103,8 @@ DEFINE_MATH_FN (CABS) ...@@ -103,6 +103,8 @@ DEFINE_MATH_FN (CABS)
DEFINE_MATH_FN (TRUNC) DEFINE_MATH_FN (TRUNC)
DEFINE_MATH_FN (NEARBYINT) DEFINE_MATH_FN (NEARBYINT)
DEFINE_MATH_FN (SIGNBIT) 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 (FLOOR)
DEFINE_INT_AND_FLOAT_ROUND_FN (CEIL) DEFINE_INT_AND_FLOAT_ROUND_FN (CEIL)
...@@ -1170,9 +1172,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -1170,9 +1172,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(minus (convert @1) (convert @2))))))) (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 (simplify
(minmax @0 @0) (minmax @0 @0)
@0)) @0))
...@@ -1196,7 +1198,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -1196,7 +1198,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& TYPE_MAX_VALUE (type) && TYPE_MAX_VALUE (type)
&& operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST)) && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
@1)) @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. */ /* Simplifications of shift and rotates. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment