In my previous patch enabling some of the built-in functions for _Float<N> and _Float<N>X datatypes, I missed making fminf128 and fmaxf128 generate the minimum and maximum inline code when -ffast-math is used. This patch to match.pd enables the code generation using if-then-else if the machine does not have an appropriate min/max instruction (the power9 hardware does not have min/max instructions for quad floating point).
I have done builds on x86-64, little endian power8, and little endian power9 prototype systems. All builds bootstrapped and had no regressions. Can I check this patch into the trunk? [gcc] 2017-11-09 Michael Meissner <meiss...@linux.vnet.ibm.com> * match.pd: Convert fminf<N>, fminf<N>x, fmax<N>, and fmax<N>x into the min/max operations for _Float<N> and _Float<N>X types. [gcc/testsuite] 2017-11-09 Michael Meissner <meiss...@linux.vnet.ibm.com> * gcc.target/powerpc/float128-minmax.c: New test. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 254473) +++ gcc/match.pd (working copy) @@ -1723,7 +1723,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Simplifications of MIN_EXPR, MAX_EXPR, fmin() and fmax(). */ -(for minmax (min max FMIN FMAX) +(for minmax (min max FMIN FMIN_FN FMAX FMAX_FN) (simplify (minmax @0 @0) @0)) @@ -1801,7 +1801,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)) (minmax @1 (convert @2))))) -(for minmax (FMIN FMAX) +(for minmax (FMIN FMIN_FN FMAX FMAX_FN) /* If either argument is NaN, return the other one. Avoid the transformation if we get (and honor) a signalling NaN. */ (simplify @@ -1819,11 +1819,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (FMIN @0 @1) (min @0 @1)) (simplify + (FMIN_FN @0 @1) + (min @0 @1)) + (simplify (FMAX @0 @1) + (max @0 @1)) + (simplify + (FMAX_FN @0 @1) (max @0 @1))) /* min (-A, -B) -> -max (A, B) */ -(for minmax (min max FMIN FMAX) - maxmin (max min FMAX FMIN) +(for minmax (min max FMIN FMIN_FN FMAX FMAX_FN) + maxmin (max min FMAX FMAX_FN FMIN FMAX_FN) (simplify (minmax (negate:s@2 @0) (negate:s@3 @1)) (if (FLOAT_TYPE_P (TREE_TYPE (@0)) Index: gcc/testsuite/gcc.target/powerpc/float128-minmax.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-minmax.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-minmax.c (revision 0) @@ -0,0 +1,15 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mpower9-vector -O2 -ffast-math" } */ + +#ifndef TYPE +#define TYPE _Float128 +#endif + +/* Test that the fminf128/fmaxf128 functions generate if/then/else and not a + call. */ +TYPE f128_min (TYPE a, TYPE b) { return __builtin_fminf128 (a, b); } +TYPE f128_max (TYPE a, TYPE b) { return __builtin_fmaxf128 (a, b); } + +/* { dg-final { scan-assembler {\mxscmpuqp\M} } } */ +/* { dg-final { scan-assembler-not {\mbl\M} } } */