public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0
@ 2017-09-13 21:46 Michael Meissner
  2017-09-13 22:49 ` Joseph Myers
  2017-09-14 14:54 ` [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0 Segher Boessenkool
  0 siblings, 2 replies; 31+ messages in thread
From: Michael Meissner @ 2017-09-13 21:46 UTC (permalink / raw)
  To: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 2933 bytes --]

This patch adds support on PowerPC ISA 3.0 for the built-in function
__builtin_sqrtf128 generating the XSSQRTQP hardware square root instruction and
the built-in function __builtin_fmaf128 generating XSMADDQP, XSMSUBQP,
XSNMADDQP, and XSNMSUBQP fused multiply-add instructions.

While I was at it, I changed the documentation so that it no longer documents
the 'q' built-in functions (to mirror libquadmath) but instead just documented
the 'f128' functions that matches glibc 2.26 and the technical report that
added the _FloatF128 date.

I changed the tests that used __fabsq to use __fabsf128 instead.

I also added && lp64 to float128-5.c so that it doesn't cause errors when doing
the test for a 32-bit target.  This is due to the fact that if you enable
hardware IEEE 128-bit floating point, you eventually will need TImode
supported, and that is not supported on 32-bit targets.

I did a bootstrap and make check with subversion id 252033 on a little endian
power8 system.  The subversion id 252033 is one of the last svn ids that
bootstrap without additional patches on the PowerPC.  There were no regressions
in this patch, and I verified the 4 new tests were run.  Can I check this patch
into the trunk?

[gcc]
2017-09-13  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/rs6000-builtin.def (BU_FLOAT128_1_HW): New macros
	to support float128 built-in functions that require the ISA 3.0
	hardware.
	(BU_FLOAT128_3_HW): Likewise.
	(SQRTF128): Add support for the IEEE 128-bit square root and fma
	built-in functions.
	(FMAF128): Likewise.
	(FMAQ): Likewise.
	* config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add
	support for built-in functions that need the ISA 3.0 IEEE 128-bit
	floating point instructions.
	(rs6000_invalid_builtin): Likewise.
	(rs6000_builtin_mask_names): Likewise.
	* config/rs6000/rs6000.h (MASK_FLOAT128_HW): Likewise.
	(RS6000_BTM_FLOAT128_HW): Likewise.
	(RS6000_BTM_COMMON): Likewise.
	* config/rs6000/rs6000.md (fma<mode>4_hw): Add a generator
	function.
	* doc/extend.texi (RS/6000 built-in functions): Document the
	'f128' IEEE 128-bit floating point built-in functions.  Don't
	document the older 'q' versions of the functions. Document the
	built-in IEEE 128-bit floating point square root and fused
	multiply-add built-ins.

[gcc/testsuite]
2017-09-13  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/abs128-1.c: Use __builtin_fabsf128 instead of
	__builtin_fabsq.
	* gcc.target/powerpc/float128-5.c: Use __builtin_fabsf128 instead
	of __builtin_fabsq.  Prevent the test from running on 32-bit.
	* gcc.target/powerpc/float128-fma1.c: New test.
	* gcc.target/powerpc/float128-fma2.c: Likewise.
	* gcc.target/powerpc/float128-sqrt1.c: Likewise.
	* gcc.target/powerpc/float128-sqrt2.c: Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch30b --]
[-- Type: text/plain, Size: 12778 bytes --]

Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 252730)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -667,6 +667,23 @@
 		     | RS6000_BTC_UNARY),                               \
 		    CODE_FOR_ ## ICODE)                 /* ICODE */
 
+/* IEEE 128-bit floating-point builtins that need the ISA 3.0 hardware.  */
+#define BU_FLOAT128_1_HW(ENUM, NAME, ATTR, ICODE)                       \
+  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,              /* ENUM */      \
+		    "__builtin_" NAME,                  /* NAME */      \
+		    RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+		    (RS6000_BTC_ ## ATTR                /* ATTR */      \
+		     | RS6000_BTC_UNARY),                               \
+		    CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_FLOAT128_3_HW(ENUM, NAME, ATTR, ICODE)                       \
+  RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM,              /* ENUM */      \
+		    "__builtin_" NAME,                  /* NAME */      \
+		    RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+		    (RS6000_BTC_ ## ATTR                /* ATTR */      \
+		     | RS6000_BTC_TERNARY),                             \
+		    CODE_FOR_ ## ICODE)                 /* ICODE */
+
 /* Miscellaneous builtins for instructions added in ISA 3.0.  These
    instructions don't require either the DFP or VSX options, just the basic
    ISA 3.0 enablement since they operate on general purpose registers.  */
@@ -2328,6 +2345,16 @@ BU_FLOAT128_1 (FABSQ,		"fabsq",       CO
 
 /* 2 argument IEEE 128-bit floating-point functions.  */
 BU_FLOAT128_2 (COPYSIGNQ,	"copysignq",   CONST, copysignkf3)
+
+/* 1 argument IEEE 128-bit floating point functions that require ISA 3.0
+   hardware.  We define both a 'q' version for libquadmath compatibility, and a
+   'f128' for glibc 2.26.  We didn't need this for FABS/COPYSIGN, since the
+   machine independent built-in support already defines the F128 versions,  */
+BU_FLOAT128_1_HW (SQRTF128,	"sqrtf128",	CONST, sqrtkf2)
+
+/* 3 argument IEEE 128-bit floating point functions that require ISA 3.0
+   hardware.  */
+BU_FLOAT128_3_HW (FMAF128,	"fmaf128",	CONST, fmakf4_hw)
 \f
 /* 1 argument crypto functions.  */
 BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox)
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 252730)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -3903,7 +3903,8 @@ rs6000_builtin_mask_calculate (void)
 	  | ((TARGET_DFP)		    ? RS6000_BTM_DFP	   : 0)
 	  | ((TARGET_HARD_FLOAT)	    ? RS6000_BTM_HARD_FLOAT : 0)
 	  | ((TARGET_LONG_DOUBLE_128)	    ? RS6000_BTM_LDBL128   : 0)
-	  | ((TARGET_FLOAT128_TYPE)	    ? RS6000_BTM_FLOAT128  : 0));
+	  | ((TARGET_FLOAT128_TYPE)	    ? RS6000_BTM_FLOAT128  : 0)
+	  | ((TARGET_FLOAT128_HW)	    ? RS6000_BTM_FLOAT128_HW : 0));
 }
 
 /* Implement TARGET_MD_ASM_ADJUST.  All asm statements are considered
@@ -16107,6 +16108,9 @@ rs6000_invalid_builtin (enum rs6000_buil
   else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
     error ("builtin function %qs requires the %qs option", name,
 	   "-mhard-float");
+  else if ((fnmask & RS6000_BTM_FLOAT128_HW) != 0)
+    error ("builtin function %qs requires ISA 3.0 IEEE 128-bit floating point",
+	   name);
   else if ((fnmask & RS6000_BTM_FLOAT128) != 0)
     error ("builtin function %qs requires the %qs option", name, "-mfloat128");
   else
@@ -36227,6 +36231,7 @@ static struct rs6000_opt_mask const rs60
   { "hard-float",	 RS6000_BTM_HARD_FLOAT,	false, false },
   { "long-double-128",	 RS6000_BTM_LDBL128,	false, false },
   { "float128",		 RS6000_BTM_FLOAT128,   false, false },
+  { "float128-hw",	 RS6000_BTM_FLOAT128_HW,false, false },
 };
 
 /* Option variables that we want to support inside attribute((target)) and
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 252730)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -640,6 +640,7 @@ extern int rs6000_vector_align[];
 #define MASK_DLMZB			OPTION_MASK_DLMZB
 #define MASK_EABI			OPTION_MASK_EABI
 #define MASK_FLOAT128_KEYWORD		OPTION_MASK_FLOAT128_KEYWORD
+#define MASK_FLOAT128_HW		OPTION_MASK_FLOAT128_HW
 #define MASK_FPRND			OPTION_MASK_FPRND
 #define MASK_P8_FUSION			OPTION_MASK_P8_FUSION
 #define MASK_HARD_FLOAT			OPTION_MASK_HARD_FLOAT
@@ -2499,6 +2500,7 @@ extern int frame_pointer_needed;
 #define RS6000_BTM_LDBL128	MASK_MULTIPLE	/* 128-bit long double.  */
 #define RS6000_BTM_64BIT	MASK_64BIT	/* 64-bit addressing.  */
 #define RS6000_BTM_FLOAT128	MASK_FLOAT128_KEYWORD /* IEEE 128-bit float.  */
+#define RS6000_BTM_FLOAT128_HW	MASK_FLOAT128_HW /* IEEE 128-bit float h/w.  */
 
 #define RS6000_BTM_COMMON	(RS6000_BTM_ALTIVEC			\
 				 | RS6000_BTM_VSX			\
@@ -2517,7 +2519,8 @@ extern int frame_pointer_needed;
 				 | RS6000_BTM_DFP			\
 				 | RS6000_BTM_HARD_FLOAT		\
 				 | RS6000_BTM_LDBL128			\
-				 | RS6000_BTM_FLOAT128)
+				 | RS6000_BTM_FLOAT128			\
+				 | RS6000_BTM_FLOAT128_HW)
 
 /* Define builtin enum index.  */
 
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 252730)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -14316,7 +14316,7 @@ (define_insn "*nabs<mode>2_hw"
    (set_attr "size" "128")])
 
 ;; Initially don't worry about doing fusion
-(define_insn "*fma<mode>4_hw"
+(define_insn "fma<mode>4_hw"
   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
 	(fma:IEEE128
 	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 252730)
+++ gcc/doc/extend.texi	(working copy)
@@ -15309,34 +15309,50 @@ Additional built-in functions are availa
 family of processors, for efficient use of 128-bit floating point
 (@code{__float128}) values.
 
-The following floating-point built-in functions are available with
-@code{-mfloat128} and Altivec support.  All of them implement the
-function that is part of the name.
-
-@smallexample
-__float128 __builtin_fabsq (__float128)
-__float128 __builtin_copysignq (__float128, __float128)
-@end smallexample
-
-The following built-in functions are available with @code{-mfloat128}
-and Altivec support.
+The following built-in functions are available on Linux 64-bit systems
+with @code{-mfloat128} and Altivec support.
 
 @table @code
-@item __float128 __builtin_infq (void)
+@item __float128 __builtin_fabsf128 (__float128)
+Similar to @code{__builtin_fabs}, except the return and input types
+are @code{__float128}.
+@findex __builtin_fabsf128
+
+@item __float128 __builtin_copysignf128 (__float128, __float128)
+Similar to @code{__builtin_copysign}, except the return and input
+types are @code{__float128}.
+@findex __builtin_copysignf128
+
+@item __float128 __builtin_inff128 (void)
 Similar to @code{__builtin_inf}, except the return type is @code{__float128}.
-@findex __builtin_infq
+@findex __builtin_inff128
 
-@item __float128 __builtin_huge_valq (void)
+@item __float128 __builtin_huge_valf128 (void)
 Similar to @code{__builtin_huge_val}, except the return type is @code{__float128}.
-@findex __builtin_huge_valq
+@findex __builtin_huge_valf128
 
-@item __float128 __builtin_nanq (void)
+@item __float128 __builtin_nanf128 (const char *)
 Similar to @code{__builtin_nan}, except the return type is @code{__float128}.
-@findex __builtin_nanq
+@findex __builtin_nanf128
 
-@item __float128 __builtin_nansq (void)
+@item __float128 __builtin_nansf128 (const char *)
 Similar to @code{__builtin_nans}, except the return type is @code{__float128}.
-@findex __builtin_nansq
+@findex __builtin_nansf128
+@end table
+
+The following built-in functions are available on Linux 64-bit systems
+that use the ISA 3.0 instruction set.
+
+@table @code
+@item __float128 __builtin_sqrtf128 (__float128)
+Similar to @code{__builtin_sqrtf}, except the return and input types
+are @code{__float128}.
+@findex __builtin_sqrtf128
+
+@item __float128 __builtin_fmaf128 (__float128, __float128, __float128)
+Similar to @code{__builtin_fma}, except the return and input types are
+@code{__float128}.
+@findex __builtin_fmaf128
 @end table
 
 The following built-in functions are available for the PowerPC family
Index: gcc/testsuite/gcc.target/powerpc/abs128-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/abs128-1.c	(revision 252730)
+++ gcc/testsuite/gcc.target/powerpc/abs128-1.c	(working copy)
@@ -39,7 +39,7 @@ main (int argc, int *argv[])
   x.nan.mant_high = 0x1234;
   x.nan.mant_low = 0xabcdef;
 
-  z.value = __builtin_fabsq (x.value);
+  z.value = __builtin_fabsf128 (x.value);
 
   if (z.nan.negative != 0
       || z.nan.exponent != 0x22
@@ -48,7 +48,7 @@ main (int argc, int *argv[])
       || z.nan.mant_low != 0xabcdef)
     abort ();
 
-  z.value = __builtin_fabsq (z.value);
+  z.value = __builtin_fabsf128 (z.value);
 
   if (z.nan.negative != 0
       || z.nan.exponent != 0x22
Index: gcc/testsuite/gcc.target/powerpc/float128-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-5.c	(revision 252730)
+++ gcc/testsuite/gcc.target/powerpc/float128-5.c	(working copy)
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
 /* { dg-options "-O2 -mpower9-vector -mno-float128" } */
 
@@ -18,7 +18,7 @@
 __float128
 qabs (__float128 a)
 {
-  return __builtin_fabsq (a);
+  return __builtin_fabsf128 (a);
 }
 
 /* { dg-final { scan-assembler "xsabsqp"  } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-fma1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-fma1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-fma1.c	(working copy)
@@ -0,0 +1,32 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+__float128
+xfma (__float128 a, __float128 b, __float128 c)
+{
+  return __builtin_fmaf128 (a, b, c);
+}
+
+__float128
+xfms (__float128 a, __float128 b, __float128 c)
+{
+  return __builtin_fmaf128 (a, b, -c);
+}
+
+__float128
+xfnma (__float128 a, __float128 b, __float128 c)
+{
+  return -__builtin_fmaf128 (a, b, c);
+}
+
+__float128
+xfnms (__float128 a, __float128 b, __float128 c)
+{
+  return -__builtin_fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler "xsmaddqp"  } } */
+/* { dg-final { scan-assembler "xsmsubqp"  } } */
+/* { dg-final { scan-assembler "xsnmaddqp" } } */
+/* { dg-final { scan-assembler "xsnmsubqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-fma2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(working copy)
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
+
+__float128
+xfma (__float128 a, __float128 b, __float128 c)
+{
+  return __builtin_fmaf128 (a, b, c); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/float128-sqrt1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-sqrt1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-sqrt1.c	(working copy)
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+__float128
+xsqrt (__float128 a)
+{
+  return __builtin_sqrtf128 (a);
+}
+
+/* { dg-final { scan-assembler "xssqrtqp"  } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(working copy)
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
+
+__float128
+xsqrt (__float128 a)
+{
+  return __builtin_sqrtf128 (a); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
+}

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0
  2017-09-13 21:46 [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0 Michael Meissner
@ 2017-09-13 22:49 ` Joseph Myers
  2017-09-14 19:02   ` Michael Meissner
  2017-10-19 22:15   ` [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions Michael Meissner
  2017-09-14 14:54 ` [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0 Segher Boessenkool
  1 sibling, 2 replies; 31+ messages in thread
From: Joseph Myers @ 2017-09-13 22:49 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Wed, 13 Sep 2017, Michael Meissner wrote:

> This patch adds support on PowerPC ISA 3.0 for the built-in function
> __builtin_sqrtf128 generating the XSSQRTQP hardware square root instruction and
> the built-in function __builtin_fmaf128 generating XSMADDQP, XSMSUBQP,
> XSNMADDQP, and XSNMSUBQP fused multiply-add instructions.

Is there a reason for these to be architecture-specific rather than 
generic everywhere _Float128 is supported?  (With the fmaf128 / sqrtf128 
names available as well as the __builtin_* variants of those.)

Full support for _FloatN/_FloatNx variants of all the existing built-in 
functions might be complicated, and run into potential issues with startup 
cost of creating large numbers of extra built-in functions (it's 
desirable, but possibly hard, which is why I excluded it from the initial 
_FloatN / _FloatNx support patches).  But adding just these two functions 
to builtins.def and making them fold / expand appropriately ought to be 
much simpler.  (I realise sqrt goes through internal-fn.def and 
DEF_INTERNAL_FLT_FN expects a particular set of functions for standard 
types, so maybe some duplication would be involved to get the built-in 
function expanded appropriately, i.e. using an insn pattern or a call to 
an external sqrtf128 function according to whether such an insn pattern is 
available.  fma ought not to involve much more than adding an extra case 
where CASE_FLT_FN (BUILT_IN_FMA) is used.)

> While I was at it, I changed the documentation so that it no longer documents
> the 'q' built-in functions (to mirror libquadmath) but instead just documented
> the 'f128' functions that matches glibc 2.26 and the technical report that
> added the _FloatF128 date.

Those *f128 built-in functions (inf / huge_val / nan / nans / fabs / 
copysign) are not target-specific; they exist for all _FloatN / _FloatNx 
types for all targets with such types.  So it doesn't seem appropriate to 
document them in a target-specific section of the manual, beyond a brief 
cross-reference to the documentation of the functions as 
target-independent.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0
  2017-09-13 21:46 [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0 Michael Meissner
  2017-09-13 22:49 ` Joseph Myers
@ 2017-09-14 14:54 ` Segher Boessenkool
  2017-09-14 22:21   ` Michael Meissner
  1 sibling, 1 reply; 31+ messages in thread
From: Segher Boessenkool @ 2017-09-14 14:54 UTC (permalink / raw)
  To: Michael Meissner, GCC Patches, David Edelsohn, Bill Schmidt

On Wed, Sep 13, 2017 at 05:46:00PM -0400, Michael Meissner wrote:
> This patch adds support on PowerPC ISA 3.0 for the built-in function
> __builtin_sqrtf128 generating the XSSQRTQP hardware square root instruction and
> the built-in function __builtin_fmaf128 generating XSMADDQP, XSMSUBQP,
> XSNMADDQP, and XSNMSUBQP fused multiply-add instructions.
> 
> While I was at it, I changed the documentation so that it no longer documents
> the 'q' built-in functions (to mirror libquadmath) but instead just documented
> the 'f128' functions that matches glibc 2.26 and the technical report that
> added the _FloatF128 date.
> 
> I changed the tests that used __fabsq to use __fabsf128 instead.
> 
> I also added && lp64 to float128-5.c so that it doesn't cause errors when doing
> the test for a 32-bit target.  This is due to the fact that if you enable
> hardware IEEE 128-bit floating point, you eventually will need TImode
> supported, and that is not supported on 32-bit targets.
> 
> I did a bootstrap and make check with subversion id 252033 on a little endian
> power8 system.  The subversion id 252033 is one of the last svn ids that
> bootstrap without additional patches on the PowerPC.  There were no regressions
> in this patch, and I verified the 4 new tests were run.  Can I check this patch
> into the trunk?

Yes please.  A few trivial things:

> 	* doc/extend.texi (RS/6000 built-in functions): Document the
> 	'f128' IEEE 128-bit floating point built-in functions.  Don't
> 	document the older 'q' versions of the functions. Document the
> 	built-in IEEE 128-bit floating point square root and fused
> 	multiply-add built-ins.

Dot space space.

> +/* 1 argument IEEE 128-bit floating point functions that require ISA 3.0
> +   hardware.  We define both a 'q' version for libquadmath compatibility, and a
> +   'f128' for glibc 2.26.  We didn't need this for FABS/COPYSIGN, since the
> +   machine independent built-in support already defines the F128 versions,  */

Dot instead of comma?

> --- gcc/testsuite/gcc.target/powerpc/float128-5.c	(revision 252730)
> +++ gcc/testsuite/gcc.target/powerpc/float128-5.c	(working copy)
> @@ -1,4 +1,4 @@
> -/* { dg-do compile { target { powerpc*-*-linux* } } } */
> +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */

Maybe add a comment why this is -m64 only?

Thanks,


Segher

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0
  2017-09-13 22:49 ` Joseph Myers
@ 2017-09-14 19:02   ` Michael Meissner
  2017-10-19 22:15   ` [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions Michael Meissner
  1 sibling, 0 replies; 31+ messages in thread
From: Michael Meissner @ 2017-09-14 19:02 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

On Wed, Sep 13, 2017 at 10:49:43PM +0000, Joseph Myers wrote:
> On Wed, 13 Sep 2017, Michael Meissner wrote:
> 
> > This patch adds support on PowerPC ISA 3.0 for the built-in function
> > __builtin_sqrtf128 generating the XSSQRTQP hardware square root instruction and
> > the built-in function __builtin_fmaf128 generating XSMADDQP, XSMSUBQP,
> > XSNMADDQP, and XSNMSUBQP fused multiply-add instructions.
> 
> Is there a reason for these to be architecture-specific rather than 
> generic everywhere _Float128 is supported?  (With the fmaf128 / sqrtf128 
> names available as well as the __builtin_* variants of those.)

I wanted to get in the PowerPC stuff ASAP, so the library people can start
using it.

I do think for at least some of the built-ins (sqrt, fma, lrint, etc.) it makes
sense, and at some point I was going to look at it.

In the grand scheme of things, it is only a temporary measure, and the real end
goal is to enable switching long double to be float128.  However, that will
take multiple releases to get there.

> Full support for _FloatN/_FloatNx variants of all the existing built-in 
> functions might be complicated, and run into potential issues with startup 
> cost of creating large numbers of extra built-in functions (it's 
> desirable, but possibly hard, which is why I excluded it from the initial 
> _FloatN / _FloatNx support patches).  But adding just these two functions 
> to builtins.def and making them fold / expand appropriately ought to be 
> much simpler.  (I realise sqrt goes through internal-fn.def and 
> DEF_INTERNAL_FLT_FN expects a particular set of functions for standard 
> types, so maybe some duplication would be involved to get the built-in 
> function expanded appropriately, i.e. using an insn pattern or a call to 
> an external sqrtf128 function according to whether such an insn pattern is 
> available.  fma ought not to involve much more than adding an extra case 
> where CASE_FLT_FN (BUILT_IN_FMA) is used.)

Yeah, but I wanted to get the easy stuff in there right now before looking at
the machine independent support.

> > While I was at it, I changed the documentation so that it no longer documents
> > the 'q' built-in functions (to mirror libquadmath) but instead just documented
> > the 'f128' functions that matches glibc 2.26 and the technical report that
> > added the _FloatF128 date.
> 
> Those *f128 built-in functions (inf / huge_val / nan / nans / fabs / 
> copysign) are not target-specific; they exist for all _FloatN / _FloatNx 
> types for all targets with such types.  So it doesn't seem appropriate to 
> document them in a target-specific section of the manual, beyond a brief 
> cross-reference to the documentation of the functions as 
> target-independent.

Right now we just document a few of the 'q' functions that were added before
you added the f128 versions.  I was trying to harmonize things.  Originally, I
was going to make both __builtin_sqrtq and __builtin_sqrtf128, but Segher and
David didn't want that.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0
  2017-09-14 14:54 ` [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0 Segher Boessenkool
@ 2017-09-14 22:21   ` Michael Meissner
  0 siblings, 0 replies; 31+ messages in thread
From: Michael Meissner @ 2017-09-14 22:21 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, GCC Patches, David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 4409 bytes --]

On Thu, Sep 14, 2017 at 09:54:14AM -0500, Segher Boessenkool wrote:
> On Wed, Sep 13, 2017 at 05:46:00PM -0400, Michael Meissner wrote:
> > This patch adds support on PowerPC ISA 3.0 for the built-in function
> > __builtin_sqrtf128 generating the XSSQRTQP hardware square root instruction and
> > the built-in function __builtin_fmaf128 generating XSMADDQP, XSMSUBQP,
> > XSNMADDQP, and XSNMSUBQP fused multiply-add instructions.
> > 
> > While I was at it, I changed the documentation so that it no longer documents
> > the 'q' built-in functions (to mirror libquadmath) but instead just documented
> > the 'f128' functions that matches glibc 2.26 and the technical report that
> > added the _FloatF128 date.
> > 
> > I changed the tests that used __fabsq to use __fabsf128 instead.
> > 
> > I also added && lp64 to float128-5.c so that it doesn't cause errors when doing
> > the test for a 32-bit target.  This is due to the fact that if you enable
> > hardware IEEE 128-bit floating point, you eventually will need TImode
> > supported, and that is not supported on 32-bit targets.
> > 
> > I did a bootstrap and make check with subversion id 252033 on a little endian
> > power8 system.  The subversion id 252033 is one of the last svn ids that
> > bootstrap without additional patches on the PowerPC.  There were no regressions
> > in this patch, and I verified the 4 new tests were run.  Can I check this patch
> > into the trunk?
> 
> Yes please.  A few trivial things:
> 
> > 	* doc/extend.texi (RS/6000 built-in functions): Document the
> > 	'f128' IEEE 128-bit floating point built-in functions.  Don't
> > 	document the older 'q' versions of the functions. Document the
> > 	built-in IEEE 128-bit floating point square root and fused
> > 	multiply-add built-ins.
> 
> Dot space space.
> 
> > +/* 1 argument IEEE 128-bit floating point functions that require ISA 3.0
> > +   hardware.  We define both a 'q' version for libquadmath compatibility, and a
> > +   'f128' for glibc 2.26.  We didn't need this for FABS/COPYSIGN, since the
> > +   machine independent built-in support already defines the F128 versions,  */
> 
> Dot instead of comma?
> 
> > --- gcc/testsuite/gcc.target/powerpc/float128-5.c	(revision 252730)
> > +++ gcc/testsuite/gcc.target/powerpc/float128-5.c	(working copy)
> > @@ -1,4 +1,4 @@
> > -/* { dg-do compile { target { powerpc*-*-linux* } } } */
> > +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
> 
> Maybe add a comment why this is -m64 only?

I removed the changes to the documentation that didn't pertain to the functions
I was adding (we can clean that up some other time), and added a -m64 comment.

I checked this into the trunk:

[gcc]
2017-09-14  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/rs6000-builtin.def (BU_FLOAT128_1_HW): New macros
	to support float128 built-in functions that require the ISA 3.0
	hardware.
	(BU_FLOAT128_3_HW): Likewise.
	(SQRTF128): Add support for the IEEE 128-bit square root and fma
	built-in functions.
	(FMAF128): Likewise.
	(FMAQ): Likewise.
	* config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add
	support for built-in functions that need the ISA 3.0 IEEE 128-bit
	floating point instructions.
	(rs6000_invalid_builtin): Likewise.
	(rs6000_builtin_mask_names): Likewise.
	* config/rs6000/rs6000.h (MASK_FLOAT128_HW): Likewise.
	(RS6000_BTM_FLOAT128_HW): Likewise.
	(RS6000_BTM_COMMON): Likewise.
	* config/rs6000/rs6000.md (fma<mode>4_hw): Add a generator
	function.
	* doc/extend.texi (RS/6000 built-in functions): Document the
	'f128' IEEE 128-bit floating point built-in functions. Don't
	document the older 'q' versions of the functions. Document the
	built-in IEEE 128-bit floating point square root and fused
	multiply-add built-ins.

[gcc/testsuite]
2017-09-14  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/abs128-1.c: Use __builtin_fabsf128 instead of
	__builtin_fabsq.
	* gcc.target/powerpc/float128-5.c: Use __builtin_fabsf128 instead
	of __builtin_fabsq.  Prevent the test from running on 32-bit.
	* gcc.target/powerpc/float128-fma1.c: New test.
	* gcc.target/powerpc/float128-fma2.c: Likewise.
	* gcc.target/powerpc/float128-sqrt1.c: Likewise.
	* gcc.target/powerpc/float128-sqrt2.c: Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch31b --]
[-- Type: text/plain, Size: 8844 bytes --]

Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 252768)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -667,6 +667,23 @@
 		     | RS6000_BTC_UNARY),                               \
 		    CODE_FOR_ ## ICODE)                 /* ICODE */
 
+/* IEEE 128-bit floating-point builtins that need the ISA 3.0 hardware.  */
+#define BU_FLOAT128_1_HW(ENUM, NAME, ATTR, ICODE)                       \
+  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,              /* ENUM */      \
+		    "__builtin_" NAME,                  /* NAME */      \
+		    RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+		    (RS6000_BTC_ ## ATTR                /* ATTR */      \
+		     | RS6000_BTC_UNARY),                               \
+		    CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_FLOAT128_3_HW(ENUM, NAME, ATTR, ICODE)                       \
+  RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM,              /* ENUM */      \
+		    "__builtin_" NAME,                  /* NAME */      \
+		    RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+		    (RS6000_BTC_ ## ATTR                /* ATTR */      \
+		     | RS6000_BTC_TERNARY),                             \
+		    CODE_FOR_ ## ICODE)                 /* ICODE */
+
 /* Miscellaneous builtins for instructions added in ISA 3.0.  These
    instructions don't require either the DFP or VSX options, just the basic
    ISA 3.0 enablement since they operate on general purpose registers.  */
@@ -2323,11 +2340,18 @@ BU_P9_OVERLOAD_2 (CMPRB,	"byte_in_range"
 BU_P9_OVERLOAD_2 (CMPRB2,	"byte_in_either_range")
 BU_P9_OVERLOAD_2 (CMPEQB,	"byte_in_set")
 
-/* 1 argument IEEE 128-bit floating-point functions.  */
+/* 1 and 2 argument IEEE 128-bit floating-point functions.  These functions use
+   the older 'q' suffix from libquadmath.  The standard built-in functions
+   support fabsf128 and copysignf128, but older code used these 'q' versions,
+   so keep them around.  */
 BU_FLOAT128_1 (FABSQ,		"fabsq",       CONST, abskf2)
-
-/* 2 argument IEEE 128-bit floating-point functions.  */
 BU_FLOAT128_2 (COPYSIGNQ,	"copysignq",   CONST, copysignkf3)
+
+/* 1 and 3 argument IEEE 128-bit floating point functions that require ISA 3.0
+   hardware.  These functions use the new 'f128' suffix.  Eventually these
+   should be folded into the common built-in function handling. */
+BU_FLOAT128_1_HW (SQRTF128,	"sqrtf128",	CONST, sqrtkf2)
+BU_FLOAT128_3_HW (FMAF128,	"fmaf128",	CONST, fmakf4_hw)
 \f
 /* 1 argument crypto functions.  */
 BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox)
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 252768)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -3903,7 +3903,8 @@ rs6000_builtin_mask_calculate (void)
 	  | ((TARGET_DFP)		    ? RS6000_BTM_DFP	   : 0)
 	  | ((TARGET_HARD_FLOAT)	    ? RS6000_BTM_HARD_FLOAT : 0)
 	  | ((TARGET_LONG_DOUBLE_128)	    ? RS6000_BTM_LDBL128   : 0)
-	  | ((TARGET_FLOAT128_TYPE)	    ? RS6000_BTM_FLOAT128  : 0));
+	  | ((TARGET_FLOAT128_TYPE)	    ? RS6000_BTM_FLOAT128  : 0)
+	  | ((TARGET_FLOAT128_HW)	    ? RS6000_BTM_FLOAT128_HW : 0));
 }
 
 /* Implement TARGET_MD_ASM_ADJUST.  All asm statements are considered
@@ -16107,6 +16108,9 @@ rs6000_invalid_builtin (enum rs6000_buil
   else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
     error ("builtin function %qs requires the %qs option", name,
 	   "-mhard-float");
+  else if ((fnmask & RS6000_BTM_FLOAT128_HW) != 0)
+    error ("builtin function %qs requires ISA 3.0 IEEE 128-bit floating point",
+	   name);
   else if ((fnmask & RS6000_BTM_FLOAT128) != 0)
     error ("builtin function %qs requires the %qs option", name, "-mfloat128");
   else
@@ -36227,6 +36231,7 @@ static struct rs6000_opt_mask const rs60
   { "hard-float",	 RS6000_BTM_HARD_FLOAT,	false, false },
   { "long-double-128",	 RS6000_BTM_LDBL128,	false, false },
   { "float128",		 RS6000_BTM_FLOAT128,   false, false },
+  { "float128-hw",	 RS6000_BTM_FLOAT128_HW,false, false },
 };
 
 /* Option variables that we want to support inside attribute((target)) and
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 252768)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -640,6 +640,7 @@ extern int rs6000_vector_align[];
 #define MASK_DLMZB			OPTION_MASK_DLMZB
 #define MASK_EABI			OPTION_MASK_EABI
 #define MASK_FLOAT128_KEYWORD		OPTION_MASK_FLOAT128_KEYWORD
+#define MASK_FLOAT128_HW		OPTION_MASK_FLOAT128_HW
 #define MASK_FPRND			OPTION_MASK_FPRND
 #define MASK_P8_FUSION			OPTION_MASK_P8_FUSION
 #define MASK_HARD_FLOAT			OPTION_MASK_HARD_FLOAT
@@ -2499,6 +2500,7 @@ extern int frame_pointer_needed;
 #define RS6000_BTM_LDBL128	MASK_MULTIPLE	/* 128-bit long double.  */
 #define RS6000_BTM_64BIT	MASK_64BIT	/* 64-bit addressing.  */
 #define RS6000_BTM_FLOAT128	MASK_FLOAT128_KEYWORD /* IEEE 128-bit float.  */
+#define RS6000_BTM_FLOAT128_HW	MASK_FLOAT128_HW /* IEEE 128-bit float h/w.  */
 
 #define RS6000_BTM_COMMON	(RS6000_BTM_ALTIVEC			\
 				 | RS6000_BTM_VSX			\
@@ -2517,7 +2519,8 @@ extern int frame_pointer_needed;
 				 | RS6000_BTM_DFP			\
 				 | RS6000_BTM_HARD_FLOAT		\
 				 | RS6000_BTM_LDBL128			\
-				 | RS6000_BTM_FLOAT128)
+				 | RS6000_BTM_FLOAT128			\
+				 | RS6000_BTM_FLOAT128_HW)
 
 /* Define builtin enum index.  */
 
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 252768)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -14316,7 +14316,7 @@ (define_insn "*nabs<mode>2_hw"
    (set_attr "size" "128")])
 
 ;; Initially don't worry about doing fusion
-(define_insn "*fma<mode>4_hw"
+(define_insn "fma<mode>4_hw"
   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
 	(fma:IEEE128
 	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 252768)
+++ gcc/doc/extend.texi	(working copy)
@@ -15339,6 +15339,21 @@ Similar to @code{__builtin_nans}, except
 @findex __builtin_nansq
 @end table
 
+The following built-in functions are available on Linux 64-bit systems
+that use the ISA 3.0 instruction set.
+
+@table @code
+@item __float128 __builtin_sqrtf128 (__float128)
+Similar to @code{__builtin_sqrtf}, except the return and input types
+are @code{__float128}.
+@findex __builtin_sqrtf128
+
+@item __float128 __builtin_fmaf128 (__float128, __float128, __float128)
+Similar to @code{__builtin_fma}, except the return and input types are
+@code{__float128}.
+@findex __builtin_fmaf128
+@end table
+
 The following built-in functions are available for the PowerPC family
 of processors, starting with ISA 2.05 or later (@option{-mcpu=power6}
 or @option{-mcmpb}):
Index: gcc/testsuite/gcc.target/powerpc/abs128-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/abs128-1.c	(revision 252768)
+++ gcc/testsuite/gcc.target/powerpc/abs128-1.c	(working copy)
@@ -39,7 +39,7 @@ main (int argc, int *argv[])
   x.nan.mant_high = 0x1234;
   x.nan.mant_low = 0xabcdef;
 
-  z.value = __builtin_fabsq (x.value);
+  z.value = __builtin_fabsf128 (x.value);
 
   if (z.nan.negative != 0
       || z.nan.exponent != 0x22
@@ -48,7 +48,7 @@ main (int argc, int *argv[])
       || z.nan.mant_low != 0xabcdef)
     abort ();
 
-  z.value = __builtin_fabsq (z.value);
+  z.value = __builtin_fabsf128 (z.value);
 
   if (z.nan.negative != 0
       || z.nan.exponent != 0x22
Index: gcc/testsuite/gcc.target/powerpc/float128-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-5.c	(revision 252768)
+++ gcc/testsuite/gcc.target/powerpc/float128-5.c	(working copy)
@@ -1,9 +1,11 @@
-/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
 /* { dg-options "-O2 -mpower9-vector -mno-float128" } */
 
 /* Test that we can use #pragma GCC target to enable -mfloat128 and generate
-   code on ISA 3.0 for the float128 built-in functions.  */
+   code on ISA 3.0 for the float128 built-in functions.  Lp64 is required
+   because we need TImode to be available to enable __float128 using hardware
+   instructions.  */
 
 #ifdef __FLOAT128__
 #error "-mno-float128 should disable initially defining __FLOAT128__"
@@ -18,7 +20,7 @@
 __float128
 qabs (__float128 a)
 {
-  return __builtin_fabsq (a);
+  return __builtin_fabsf128 (a);
 }
 
 /* { dg-final { scan-assembler "xsabsqp"  } } */

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-09-13 22:49 ` Joseph Myers
  2017-09-14 19:02   ` Michael Meissner
@ 2017-10-19 22:15   ` Michael Meissner
  2017-10-19 23:00     ` Joseph Myers
  1 sibling, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-19 22:15 UTC (permalink / raw)
  To: Joseph Myers, GCC Patches, Segher Boessenkool, David Edelsohn,
	Bill Schmidt
  Cc: Michael Meissner

[-- Attachment #1: Type: text/plain, Size: 8512 bytes --]

On Wed, Sep 13, 2017 at 10:49:43PM +0000, Joseph Myers wrote:
> On Wed, 13 Sep 2017, Michael Meissner wrote:
> 
> > This patch adds support on PowerPC ISA 3.0 for the built-in function
> > __builtin_sqrtf128 generating the XSSQRTQP hardware square root instruction and
> > the built-in function __builtin_fmaf128 generating XSMADDQP, XSMSUBQP,
> > XSNMADDQP, and XSNMSUBQP fused multiply-add instructions.
> 
> Is there a reason for these to be architecture-specific rather than 
> generic everywhere _Float128 is supported?  (With the fmaf128 / sqrtf128 
> names available as well as the __builtin_* variants of those.)

The basic reason was I hadn't yet discovered all of the places that need to be
modified to add generic _Float128 math functions.

> Full support for _FloatN/_FloatNx variants of all the existing built-in 
> functions might be complicated, and run into potential issues with startup 
> cost of creating large numbers of extra built-in functions (it's 
> desirable, but possibly hard, which is why I excluded it from the initial 
> _FloatN / _FloatNx support patches).  But adding just these two functions 
> to builtins.def and making them fold / expand appropriately ought to be 
> much simpler.  (I realise sqrt goes through internal-fn.def and 
> DEF_INTERNAL_FLT_FN expects a particular set of functions for standard 
> types, so maybe some duplication would be involved to get the built-in 
> function expanded appropriately, i.e. using an insn pattern or a call to 
> an external sqrtf128 function according to whether such an insn pattern is 
> available.  fma ought not to involve much more than adding an extra case 
> where CASE_FLT_FN (BUILT_IN_FMA) is used.)

I have now gone through and added the proper support for _Float128 sqrt, fma,
fmin, and fmax.  I have added the framework so that other functions as needed
can be added over time.

> > While I was at it, I changed the documentation so that it no longer documents
> > the 'q' built-in functions (to mirror libquadmath) but instead just documented
> > the 'f128' functions that matches glibc 2.26 and the technical report that
> > added the _FloatF128 date.
> 
> Those *f128 built-in functions (inf / huge_val / nan / nans / fabs / 
> copysign) are not target-specific; they exist for all _FloatN / _FloatNx 
> types for all targets with such types.  So it doesn't seem appropriate to 
> document them in a target-specific section of the manual, beyond a brief 
> cross-reference to the documentation of the functions as 
> target-independent.

Highlights of the patch:

    1)	I switched to use DEF_EXT_LIB_BUILTIN to declare the _Float<N> and
	_Float<N>X functions.  This allows treating __builtin_sqrtf128 the same
	as sqrtf128.

    2)	Add support in gencfn-macros.c to build the appropriate CASE_CFN_* and
	operators in cfn-operators.pd that can be used as needed.

    3)	I did not enable _Float128 support for all math built-ins, but just the
	built-in functions I am currently need to support in (just like
	copysign and fabs were previously done).  I expect over time there
	might be some more needed to be added to the list.  I added fmin and
	fmax to the machine independent built-ins, but I will submit a patch
	later to enable them in the PowerPC.

    4)	I went through and added support for copysign, fma, fmin, and fmax
	functions in the same places the current float/double/long double
	functions are handled.

    5)	I removed the PowerPC sqrtf128 and fmaf128 built-ins, since these are
	now handled by machine independent code.  In doing so, I deleted two
	tests that did not allow the built-ins where the software emulator is
	used.  The GLIBC 2.26 as shipped with the Advance Toolchain 11.0-1
	contain these functions.

    6)	In the previous version of the patch, I put in a special warning for
	fmaf128 (that it might not be present if the h/w instructions weren't
	available).  When I wrote that patch, the initial release of Advance
	Toolchain 11.0-0 did not include a fmaf128 function.  It now includes
	the function, so I don't need the warning.

I have checked this patch on the following systems with bootstrap and make
check for gcc/g++/gfortran/lto:

    1)	Little endian power8 system using --with-cpu=power8
    2)	Big endian power7 system (both 64/32-bit) using --with-cpu=power7
    3)	Little endian power9 prototype system using --with-cpu=power9
    4)	A Fedora 21 x86_64 system

Can I check these patches into the trunk?

[gcc]
2017-10-19  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* builtins.c (CASE_MATHRN_FLOATN): New helper macro to support
	math functions that have _Float<N> and _Float<N>X variants.
	(mathfn_built_in_2): Add support for copysign, fma, fmax, fmin,
	and sqrt having _Float<N> and _Float<N>X variants.
	(DEF_INTERNAL_FLT_FLOATN_FN): New helper macro to support for math
	functions with _Float<N> and _Float<N>X variants.
	(expand_builtin_mathfn_ternary): Add fma _Float<N> and _Float<N>X
	support.
	(expand_builtin): Likewise.
	(fold_builtin_3): Likewise.
	* fold-const.c (tree_call_nonnegative_warnv_p): Add support for
	sqrt, fmax, fmin, and copysign with _Float<N> and _Float<N>X
	variants.
	(integer_valued_real_call_p): Likewise.
	* builtin-types.def (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16): New
	function signatures for fma _Float<N> and _Float<N>X variants.
	(BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32): Likewise.
	(BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64): Likewise.
	(BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128): Likewise.
	(BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X): Likewise.
	(BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X): Likewise.
	(BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X): Likewise.
	* builtins.def (DEF_GCC_FLOATN_NX_BUILTINS): Use
	DEF_EXT_LIB_BUILTIN instead of DEF_GCC_BUILTIN, so that
	sqrtf128 is normally processed to be __builtin_sqrtf128.
	(BUILT_IN_FMA): Define _Float<N> and _Float<N>X variants.
	(BUILT_IN_FMAX): Likewise.
	(BUILT_IN_FMIN): Likewise.
	(BUILT_IN_SQRT): Likewise.
	* tree-call-cdce.c (can_test_argument_range): Add support for sqrt
	_Float<N> and _Float<N>X variants.
	(edom_only_function): Likewise.
	(get_no_error_domain): Likewise.
	* tree-ssa-math-opts.c (gimple_call_combined_fn): Likewise.
	* fold-const-call.c (fold_const_call_ss): Likewise.
	(fold_const_call_sss): Add support for copysign, fmin, and fmax
	_Float<N> and _Float<N>X variants.
	(fold_const_call_ssss): Add support for fma _Float<N> and
	_Float<N>X variants.
	* internal-fn.def (DEF_INTERNAL_FLT_FLOATN_FN): New helper macro
	for math functions that have _Float<N> and _Float<N>X variants.
	(SQRT): Add support for sqrt, copysign, fmin and fmax _Float<N>
	and _Float<N>X variants.
	(COPYSIGN): Likewise.
	(FMIN): Likewise.
	(FMAX): Likewise.
	* gencfn-macros.c (print_case_cfn): Add support for math functions
	that have _Float<N> and _Float<N>X variants.
	(print_define_operator_list): Likewise.
	(fltfn_suffixes): Likewise.
	(main): Likewise.
	* tree-ssa-reassoc.c (attempt_builtin_copysign): Add support for
	copysign with _Float<N> and _Float<N>X variants.
	* gimple-ssa-backprop.c (backprop::process_builtin_call_use): Add
	support for copysign and fma with _Float<N> and _Float<N>X
	variants.
	* config/rs6000/rs6000-builtin.def (SQRTF128): Delete rs6000
	sqrtf128 and fmaf128 builtins, as this is handled by machine
	independent code.
	(FMAF128): Likewise.

[gcc/c-family]
2017-10-19  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-cppbuiltin.c (mode_has_fma): Add support for PowerPC fmakf3
	for float128 fma when long double is not __float128.
	(c_cpp_builtins): Define __FP_FAST_FMAF<N> and __FP_FAST_FMA<N>X
	if the _Float<N> and _Float<N>X variants for fma exist.

[gcc/c]
2017-10-19  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-decl.c (header_for_builtin_fn): Add support for fma with
	_Float<N> and _Float<N>X variants.

[gcc/testsuite]
2017-10-19  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/float128-fma2.c: Delete, test is no longer
	relavant now that machine independent code handles sqrt and fma
	_Float<N> and _Float<N>X variants.
	* gcc.target/powerpc/float128-sqrt2.c: Likewise.
	* gcc.target/powerpc/float128-hw.c: Add more tests for FMA
	variants.  Test code generated to convert __float128 to float.
	* gcc.target/powerpc/float128-hw2.c: New test for machine
	independent handling of copysignf128, sqrtf128, and fmaf128.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch40b --]
[-- Type: text/plain, Size: 29705 bytes --]

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/builtins.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -1816,14 +1816,26 @@ expand_builtin_classify_type (tree exp)
   return GEN_INT (no_type_class);
 }
 
-/* This helper macro, meant to be used in mathfn_built_in below,
-   determines which among a set of three builtin math functions is
-   appropriate for a given type mode.  The `F' and `L' cases are
-   automatically generated from the `double' case.  */
+/* This helper macro, meant to be used in mathfn_built_in below, determines
+   which among a set of builtin math functions is appropriate for a given type
+   mode.  The `F' (float) and `L' (long double) are automatically generated
+   from the 'double' case.  If a function supports the _Float<N> and _Float<N>X
+   types, there are additional types that are considered with 'F32', 'F64',
+   'F128', etc. suffixes.  */
 #define CASE_MATHFN(MATHFN) \
   CASE_CFN_##MATHFN: \
   fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
   fcodel = BUILT_IN_##MATHFN##L ; break;
+/* Similar to the above, but also add support for the _Float<N> and _Float<N>X
+   types.  */
+#define CASE_MATHFN_FLOATN(MATHFN) \
+  CASE_CFN_##MATHFN: \
+  fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
+  fcodel = BUILT_IN_##MATHFN##L ; fcodef16 = BUILT_IN_##MATHFN##F16 ; \
+  fcodef32 = BUILT_IN_##MATHFN##F32; fcodef64 = BUILT_IN_##MATHFN##F64 ; \
+  fcodef128 = BUILT_IN_##MATHFN##F128 ; fcodef32x = BUILT_IN_##MATHFN##F32X ; \
+  fcodef64x = BUILT_IN_##MATHFN##F64X ; fcodef128x = BUILT_IN_##MATHFN##F128X ;\
+  break;
 /* Similar to above, but appends _R after any F/L suffix.  */
 #define CASE_MATHFN_REENT(MATHFN) \
   case CFN_BUILT_IN_##MATHFN##_R: \
@@ -1840,7 +1852,15 @@ expand_builtin_classify_type (tree exp)
 static built_in_function
 mathfn_built_in_2 (tree type, combined_fn fn)
 {
+  tree mtype;
   built_in_function fcode, fcodef, fcodel;
+  built_in_function fcodef16 = END_BUILTINS;
+  built_in_function fcodef32 = END_BUILTINS;
+  built_in_function fcodef64 = END_BUILTINS;
+  built_in_function fcodef128 = END_BUILTINS;
+  built_in_function fcodef32x = END_BUILTINS;
+  built_in_function fcodef64x = END_BUILTINS;
+  built_in_function fcodef128x = END_BUILTINS;
 
   switch (fn)
     {
@@ -1854,7 +1874,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (CBRT)
     CASE_MATHFN (CEIL)
     CASE_MATHFN (CEXPI)
-    CASE_MATHFN (COPYSIGN)
+    CASE_MATHFN_FLOATN (COPYSIGN)
     CASE_MATHFN (COS)
     CASE_MATHFN (COSH)
     CASE_MATHFN (DREM)
@@ -1867,9 +1887,9 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (FABS)
     CASE_MATHFN (FDIM)
     CASE_MATHFN (FLOOR)
-    CASE_MATHFN (FMA)
-    CASE_MATHFN (FMAX)
-    CASE_MATHFN (FMIN)
+    CASE_MATHFN_FLOATN (FMA)
+    CASE_MATHFN_FLOATN (FMAX)
+    CASE_MATHFN_FLOATN (FMIN)
     CASE_MATHFN (FMOD)
     CASE_MATHFN (FREXP)
     CASE_MATHFN (GAMMA)
@@ -1923,7 +1943,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (SIN)
     CASE_MATHFN (SINCOS)
     CASE_MATHFN (SINH)
-    CASE_MATHFN (SQRT)
+    CASE_MATHFN_FLOATN (SQRT)
     CASE_MATHFN (TAN)
     CASE_MATHFN (TANH)
     CASE_MATHFN (TGAMMA)
@@ -1936,12 +1956,27 @@ mathfn_built_in_2 (tree type, combined_f
       return END_BUILTINS;
     }
 
-  if (TYPE_MAIN_VARIANT (type) == double_type_node)
+  mtype = TYPE_MAIN_VARIANT (type);
+  if (mtype == double_type_node)
     return fcode;
-  else if (TYPE_MAIN_VARIANT (type) == float_type_node)
+  else if (mtype == float_type_node)
     return fcodef;
-  else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
+  else if (mtype == long_double_type_node)
     return fcodel;
+  else if (mtype == float16_type_node)
+    return fcodef16;
+  else if (mtype == float32_type_node)
+    return fcodef32;
+  else if (mtype == float64_type_node)
+    return fcodef64;
+  else if (mtype == float128_type_node)
+    return fcodef128;
+  else if (mtype == float32x_type_node)
+    return fcodef32x;
+  else if (mtype == float64x_type_node)
+    return fcodef64x;
+  else if (mtype == float128x_type_node)
+    return fcodef128x;
   else
     return END_BUILTINS;
 }
@@ -1995,6 +2030,9 @@ associated_internal_fn (tree fndecl)
     {
 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME;
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+    CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME; \
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_##NAME): return IFN_##NAME;
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_INT_FN (BUILT_IN_##NAME): return IFN_##NAME;
 #include "internal-fn.def"
@@ -2068,6 +2106,7 @@ expand_builtin_mathfn_ternary (tree exp,
   switch (DECL_FUNCTION_CODE (fndecl))
     {
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       builtin_optab = fma_optab; break;
     default:
       gcc_unreachable ();
@@ -6559,6 +6598,7 @@ expand_builtin (tree exp, rtx target, rt
       break;
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       target = expand_builtin_mathfn_ternary (exp, target, subtarget);
       if (target)
 	return target;
@@ -8989,6 +9029,7 @@ fold_builtin_3 (location_t loc, tree fnd
       return fold_builtin_sincos (loc, arg0, arg1, arg2);
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       return fold_builtin_fma (loc, arg0, arg1, arg2, type);
 
     CASE_FLT_FN (BUILT_IN_REMQUO):
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/fold-const.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -12761,6 +12761,7 @@ tree_call_nonnegative_warnv_p (tree type
       return true;
 
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       /* sqrt(-0.0) is -0.0.  */
       if (!HONOR_SIGNED_ZEROS (element_mode (type)))
 	return true;
@@ -12805,14 +12806,17 @@ tree_call_nonnegative_warnv_p (tree type
       return RECURSE (arg0);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       /* True if the 1st OR 2nd arguments are nonnegative.  */
       return RECURSE (arg0) || RECURSE (arg1);
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       /* True if the 1st AND 2nd arguments are nonnegative.  */
       return RECURSE (arg0) && RECURSE (arg1);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* True if the 2nd argument is nonnegative.  */
       return RECURSE (arg1);
 
@@ -13311,7 +13315,9 @@ integer_valued_real_call_p (combined_fn
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return RECURSE (arg0) && RECURSE (arg1);
 
     default:
Index: gcc/builtin-types.def
===================================================================
--- gcc/builtin-types.def	(.../trunk/gcc)	(revision 253857)
+++ gcc/builtin-types.def	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -544,6 +544,20 @@ DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE
 		     BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
 DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
 		     BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16,
+		     BT_FLOAT16, BT_FLOAT16, BT_FLOAT16, BT_FLOAT16)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32,
+		     BT_FLOAT32, BT_FLOAT32, BT_FLOAT32, BT_FLOAT32)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64,
+		     BT_FLOAT64, BT_FLOAT64, BT_FLOAT64, BT_FLOAT64)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128,
+		     BT_FLOAT128, BT_FLOAT128, BT_FLOAT128, BT_FLOAT128)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X,
+		     BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X,
+		     BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X,
+		     BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
 DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_INTPTR,
 		     BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_INT_PTR)
 DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(.../trunk/gcc)	(revision 253857)
+++ gcc/builtins.def	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -92,13 +92,13 @@ along with GCC; see the file COPYING3.
    value for the type.  */
 #undef DEF_GCC_FLOATN_NX_BUILTINS
 #define DEF_GCC_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)	\
-  DEF_GCC_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
-  DEF_GCC_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
-  DEF_GCC_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
-  DEF_GCC_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS) \
-  DEF_GCC_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS) \
-  DEF_GCC_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS) \
-  DEF_GCC_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), ATTRS)
+  DEF_EXT_LIB_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), ATTRS)
 
 /* A library builtin (like __builtin_strchr) is a builtin equivalent
    of an ANSI/ISO standard library function.  In addition to the
@@ -382,12 +382,21 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL,
 DEF_C99_BUILTIN        (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+#define FMA_TYPE(F) BT_FN_##F##_##F##_##F##_##F
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_FMA, "fma", FMA_TYPE, ATTR_MATHFN_FPROUNDING)
+#undef FMA_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMAX_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_FMAX, "fmax", FMAX_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMAX_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMIN_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_FMIN, "fmin", FMIN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMIN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
@@ -564,6 +573,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "
 DEF_LIB_BUILTIN        (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#define SQRT_TYPE(F) BT_FN_##F##_##F
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_SQRT, "sqrt", SQRT_TYPE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#undef SQRT_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_LIB_BUILTIN        (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
Index: gcc/tree-call-cdce.c
===================================================================
--- gcc/tree-call-cdce.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/tree-call-cdce.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -314,6 +314,7 @@ can_test_argument_range (gcall *call)
     CASE_FLT_FN (BUILT_IN_POW10):
     /* Sqrt.  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return check_builtin_call (call);
     /* Special one: two argument pow.  */
     case BUILT_IN_POW:
@@ -342,6 +343,7 @@ edom_only_function (gcall *call)
     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
     CASE_FLT_FN (BUILT_IN_SIN):
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
     CASE_FLT_FN (BUILT_IN_FMOD):
     CASE_FLT_FN (BUILT_IN_REMAINDER):
       return true;
@@ -703,6 +705,7 @@ get_no_error_domain (enum built_in_funct
                          308, true, false);
     /* sqrt: [0, +inf)  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return get_domain (0, true, true,
                          0, false, false);
     default:
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/tree-ssa-math-opts.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -515,6 +515,7 @@ internal_fn_reciprocal (gcall *call)
   switch (gimple_call_combined_fn (call))
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       ifn = IFN_RSQRT;
       break;
 
Index: gcc/fold-const-call.c
===================================================================
--- gcc/fold-const-call.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/fold-const-call.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -596,6 +596,7 @@ fold_const_call_ss (real_value *result,
   switch (fn)
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       return (real_compare (GE_EXPR, arg, &dconst0)
 	      && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
 
@@ -1179,14 +1180,17 @@ fold_const_call_sss (real_value *result,
       return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       *result = *arg0;
       real_copysign (result, arg1);
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
 
     CASE_CFN_POW:
@@ -1473,6 +1477,7 @@ fold_const_call_ssss (real_value *result
   switch (fn)
     {
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
 
     default:
Index: gcc/internal-fn.def
===================================================================
--- gcc/internal-fn.def	(.../trunk/gcc)	(revision 253857)
+++ gcc/internal-fn.def	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -80,6 +80,11 @@ along with GCC; see the file COPYING3.
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
 #endif
 
+#ifndef DEF_INTERNAL_FLT_FLOATN_FN
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+  DEF_INTERNAL_FLT_FN (NAME, FLAGS, OPTAB, TYPE)
+#endif
+
 #ifndef DEF_INTERNAL_INT_FN
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
@@ -109,7 +114,7 @@ DEF_INTERNAL_FLT_FN (LOG2, ECF_CONST, lo
 DEF_INTERNAL_FLT_FN (LOGB, ECF_CONST, logb, unary)
 DEF_INTERNAL_FLT_FN (SIGNIFICAND, ECF_CONST, significand, unary)
 DEF_INTERNAL_FLT_FN (SIN, ECF_CONST, sin, unary)
-DEF_INTERNAL_FLT_FN (SQRT, ECF_CONST, sqrt, unary)
+DEF_INTERNAL_FLT_FLOATN_FN (SQRT, ECF_CONST, sqrt, unary)
 DEF_INTERNAL_FLT_FN (TAN, ECF_CONST, tan, unary)
 
 /* FP rounding.  */
@@ -122,13 +127,13 @@ DEF_INTERNAL_FLT_FN (TRUNC, ECF_CONST, b
 
 /* Binary math functions.  */
 DEF_INTERNAL_FLT_FN (ATAN2, ECF_CONST, atan2, binary)
-DEF_INTERNAL_FLT_FN (COPYSIGN, ECF_CONST, copysign, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (COPYSIGN, ECF_CONST, copysign, binary)
 DEF_INTERNAL_FLT_FN (FMOD, ECF_CONST, fmod, binary)
 DEF_INTERNAL_FLT_FN (POW, ECF_CONST, pow, binary)
 DEF_INTERNAL_FLT_FN (REMAINDER, ECF_CONST, remainder, binary)
 DEF_INTERNAL_FLT_FN (SCALB, ECF_CONST, scalb, binary)
-DEF_INTERNAL_FLT_FN (FMIN, ECF_CONST, fmin, binary)
-DEF_INTERNAL_FLT_FN (FMAX, ECF_CONST, fmax, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMIN, ECF_CONST, fmin, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMAX, ECF_CONST, fmax, binary)
 DEF_INTERNAL_OPTAB_FN (XORSIGN, ECF_CONST, xorsign, binary)
 
 /* FP scales.  */
@@ -230,5 +235,6 @@ DEF_INTERNAL_FN (DIVMOD, ECF_CONST | ECF
 
 #undef DEF_INTERNAL_INT_FN
 #undef DEF_INTERNAL_FLT_FN
+#undef DEF_INTERNAL_FLT_FLOATN_FN
 #undef DEF_INTERNAL_OPTAB_FN
 #undef DEF_INTERNAL_FN
Index: gcc/gencfn-macros.c
===================================================================
--- gcc/gencfn-macros.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/gencfn-macros.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -98,11 +98,12 @@ is_group (string_set *builtins, const ch
 
 static void
 print_case_cfn (const char *name, bool internal_p,
-		const char *const *suffixes)
+		const char *const *suffixes, bool floatn_p)
 {
-  printf ("#define CASE_CFN_%s", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("#define CASE_CFN_%s%s", name, floatn);
   if (internal_p)
-    printf (" \\\n  case CFN_%s", name);
+    printf (" \\\n  case CFN_%s%s", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("%s \\\n  case CFN_BUILT_IN_%s%s",
 	    internal_p || i > 0 ? ":" : "", name, suffixes[i]);
@@ -115,9 +116,10 @@ print_case_cfn (const char *name, bool i
 
 static void
 print_define_operator_list (const char *name, bool internal_p,
-			    const char *const *suffixes)
+			    const char *const *suffixes, bool floatn_p)
 {
-  printf ("(define_operator_list %s\n", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("(define_operator_list %s%s\n", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("    BUILT_IN_%s%s\n", name, suffixes[i]);
   if (internal_p)
@@ -148,6 +150,8 @@ const char *const internal_fn_int_names[
 };
 
 static const char *const flt_suffixes[] = { "F", "", "L", NULL };
+static const char *const fltfn_suffixes[] = { "F16", "F32", "F128", "F32X",
+					      "F64X", "F128X", NULL };
 static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
 
 static const char *const *const suffix_lists[] = {
@@ -200,15 +204,33 @@ main (int argc, char **argv)
 	{
 	  const char *root = name + 9;
 	  for (unsigned int j = 0; suffix_lists[j]; ++j)
-	    if (is_group (&builtins, root, suffix_lists[j]))
-	      {
-		bool internal_p = internal_fns.contains (root);
-		if (type == 'c')
-		  print_case_cfn (root, internal_p, suffix_lists[j]);
-		else
-		  print_define_operator_list (root, internal_p,
-					      suffix_lists[j]);
-	      }
+	    {
+	      const char *const *const suffix = suffix_lists[j];
+
+	      if (is_group (&builtins, root, suffix))
+		{
+		  bool internal_p = internal_fns.contains (root);
+
+		  if (type == 'c')
+		    print_case_cfn (root, internal_p, suffix, false);
+		  else
+		    print_define_operator_list (root, internal_p,
+						suffix, false);
+
+		      /* Support the _Float<N> and _Float<N>X math functions if
+			 they exist.  We put these out as a separate CFN macro,
+			 so code can add support or not as needed.  */
+		  if (suffix == flt_suffixes
+		      && is_group (&builtins, root, fltfn_suffixes))
+		    {
+		      if (type == 'c')
+			print_case_cfn (root, false, fltfn_suffixes, true);
+		      else
+			print_define_operator_list (root, false, fltfn_suffixes,
+						    true);
+		    }
+		}
+	    }
 	}
     }
 
Index: gcc/tree-ssa-reassoc.c
===================================================================
--- gcc/tree-ssa-reassoc.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/tree-ssa-reassoc.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -5625,6 +5625,7 @@ attempt_builtin_copysign (vec<operand_en
 	      switch (gimple_call_combined_fn (old_call))
 		{
 		CASE_CFN_COPYSIGN:
+		CASE_CFN_COPYSIGN_FN:
 		  arg0 = gimple_call_arg (old_call, 0);
 		  arg1 = gimple_call_arg (old_call, 1);
 		  /* The first argument of copysign must be a constant,
Index: gcc/gimple-ssa-backprop.c
===================================================================
--- gcc/gimple-ssa-backprop.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/gimple-ssa-backprop.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -354,6 +354,7 @@ backprop::process_builtin_call_use (gcal
       break;
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* The sign of the first input is ignored.  */
       if (rhs != gimple_call_arg (call, 1))
 	info->flags.ignore_sign = true;
@@ -373,6 +374,7 @@ backprop::process_builtin_call_use (gcal
       }
 
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       /* In X * X + Y, where Y is distinct from X, the sign of X doesn't
 	 matter.  */
       if (gimple_call_arg (call, 0) == rhs
@@ -689,6 +691,7 @@ strip_sign_op_1 (tree rhs)
     switch (gimple_call_combined_fn (call))
       {
       CASE_CFN_COPYSIGN:
+      CASE_CFN_COPYSIGN_FN:
 	return gimple_call_arg (call, 0);
 
       default:
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(.../trunk/gcc)	(revision 253857)
+++ gcc/config/rs6000/rs6000-builtin.def	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -2374,17 +2374,13 @@ BU_FLOAT128_1 (FABSQ,		"fabsq",       CO
 BU_FLOAT128_2 (COPYSIGNQ,	"copysignq",   CONST, copysignkf3)
 
 /* 1, 2, and 3 argument IEEE 128-bit floating point functions that require ISA
-   3.0 hardware.  These functions use the new 'f128' suffix.  Eventually the
-   standard functions should be folded into the common built-in function
-   handling. */
-BU_FLOAT128_1_HW (SQRTF128,	 "sqrtf128",		   CONST, sqrtkf2)
+   3.0 hardware.  These functions use the new 'f128' suffix.  */
 BU_FLOAT128_1_HW (SQRTF128_ODD,	 "sqrtf128_round_to_odd",  CONST, sqrtkf2_odd)
 BU_FLOAT128_1_HW (TRUNCF128_ODD, "truncf128_round_to_odd", CONST, trunckfdf2_odd)
 BU_FLOAT128_2_HW (ADDF128_ODD,	 "addf128_round_to_odd",   CONST, addkf3_odd)
 BU_FLOAT128_2_HW (SUBF128_ODD,	 "subf128_round_to_odd",   CONST, subkf3_odd)
 BU_FLOAT128_2_HW (MULF128_ODD,	 "mulf128_round_to_odd",   CONST, mulkf3_odd)
 BU_FLOAT128_2_HW (DIVF128_ODD,	 "divf128_round_to_odd",   CONST, divkf3_odd)
-BU_FLOAT128_3_HW (FMAF128,	 "fmaf128",		   CONST, fmakf4_hw)
 BU_FLOAT128_3_HW (FMAF128_ODD,	 "fmaf128_round_to_odd",   CONST, fmakf4_odd)
 \f
 /* 1 argument crypto functions.  */
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/c-family/c-cppbuiltin.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -82,6 +82,11 @@ mode_has_fma (machine_mode mode)
       return !!HAVE_fmadf4;
 #endif
 
+#ifdef HAVE_fmakf4	/* PowerPC if long double != __float128.  */
+    case E_KFmode:
+      return !!HAVE_fmakf4;
+#endif
+
 #ifdef HAVE_fmaxf4
     case E_XFmode:
       return !!HAVE_fmaxf4;
@@ -1119,7 +1124,7 @@ c_cpp_builtins (cpp_reader *pfile)
 	       floatn_nx_types[i].extended ? "X" : "");
       sprintf (csuffix, "F%d%s", floatn_nx_types[i].n,
 	       floatn_nx_types[i].extended ? "x" : "");
-      builtin_define_float_constants (prefix, csuffix, "%s", NULL,
+      builtin_define_float_constants (prefix, csuffix, "%s", csuffix,
 				      FLOATN_NX_TYPE_NODE (i));
     }
 
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/c/c-decl.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -3171,6 +3171,7 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_FDIM):
     CASE_FLT_FN (BUILT_IN_FLOOR):
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
     CASE_FLT_FN (BUILT_IN_FMAX):
     CASE_FLT_FN (BUILT_IN_FMIN):
     CASE_FLT_FN (BUILT_IN_FMOD):
Index: gcc/testsuite/gcc.target/powerpc/float128-fma2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(.../branches/ibm/ieee/gcc)	(nonexistent)
@@ -1,9 +0,0 @@
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-/* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
-
-__float128
-xfma (__float128 a, __float128 b, __float128 c)
-{
-  return __builtin_fmaf128 (a, b, c); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
-}
Index: gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(.../branches/ibm/ieee/gcc)	(nonexistent)
@@ -1,9 +0,0 @@
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-/* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
-
-__float128
-xsqrt (__float128 a)
-{
-  return __builtin_sqrtf128 (a); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
-}
Index: gcc/testsuite/gcc.target/powerpc/float128-hw.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw.c	(.../trunk/gcc)	(revision 253857)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw.c	(.../branches/ibm/ieee/gcc)	(working copy)
@@ -7,11 +7,20 @@ __float128 f128_sub (__float128 a, __flo
 __float128 f128_mul (__float128 a, __float128 b) { return a*b; }
 __float128 f128_div (__float128 a, __float128 b) { return a/b; }
 __float128 f128_fma (__float128 a, __float128 b, __float128 c) { return (a*b)+c; }
+__float128 f128_fms (__float128 a, __float128 b, __float128 c) { return (a*b)-c; }
+__float128 f128_nfma (__float128 a, __float128 b, __float128 c) { return -((a*b)+c); }
+__float128 f128_nfms (__float128 a, __float128 b, __float128 c) { return -((a*b)-c); }
 long f128_cmove (__float128 a, __float128 b, long c, long d) { return (a == b) ? c : d; }
+float f128_to_flt (__float128 a) { return (float)a; }
+
+/* { dg-final { scan-assembler {\mxsaddqp\M}   } } */
+/* { dg-final { scan-assembler {\mxssubqp\M}   } } */
+/* { dg-final { scan-assembler {\mxsmulqp\M}   } } */
+/* { dg-final { scan-assembler {\mxsdivqp\M}   } } */
+/* { dg-final { scan-assembler {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler {\mxscmpuqp\M}  } } */
+/* { dg-final { scan-assembler {\mxscvqpdpo\M} } } */
 
-/* { dg-final { scan-assembler "xsaddqp"  } } */
-/* { dg-final { scan-assembler "xssubqp"  } } */
-/* { dg-final { scan-assembler "xsmulqp"  } } */
-/* { dg-final { scan-assembler "xsdivqp"  } } */
-/* { dg-final { scan-assembler "xsmaddqp" } } */
-/* { dg-final { scan-assembler "xscmpuqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-hw2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(.../trunk/gcc)	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(.../branches/ibm/ieee/gcc)	(revision 253908)
@@ -0,0 +1,56 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math" } */
+
+/* Test to make sure the compiler handles the standard _Float128 functions that
+   have hardware support in ISA 3.0/power9.  */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+extern _Float128 sqrtf128 (_Float128);
+extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return copysignf128 (a, b);
+}
+
+_Float128
+do_sqrt (_Float128 a)
+{
+  return sqrtf128 (a);
+}
+
+_Float128
+do_fma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, c);
+}
+
+_Float128
+do_fms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, -c);
+}
+
+_Float128
+do_nfma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, c);
+}
+
+_Float128
+do_nfms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler     {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler     {\mxssqrtqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler     {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M}        } } */

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-19 23:00     ` Joseph Myers
@ 2017-10-19 23:00       ` Michael Meissner
  2017-10-19 23:08         ` Joseph Myers
  2017-10-24 22:40       ` [PATCH, version 3], " Michael Meissner
  1 sibling, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-19 23:00 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

On Thu, Oct 19, 2017 at 10:15:44PM +0000, Joseph Myers wrote:
> On Thu, 19 Oct 2017, Michael Meissner wrote:
> 
> >     1)	I switched to use DEF_EXT_LIB_BUILTIN to declare the _Float<N> and
> > 	_Float<N>X functions.  This allows treating __builtin_sqrtf128 the same
> > 	as sqrtf128.
> 
> It's not correct to do that unconditionally for all the existing 
> DEF_GCC_FLOATN_NX_BUILTINS functions.  There should not be a public 
> huge_valf128 function any more than a public huge_val function, just 
> __builtin_huge_valf128.
> 
> Rather, you should add a new DEF_EXT_LIB_FLOATN_NX_BUILTINS.  It should be 
> used by the new functions, and by the existing copysign / fabs / nan 
> functions.  It should not be used by the existing huge_val / inf / nans 
> functions.

Ok.  Would an initial patch to go back to using DEF_GCC_BUILTIN (which means
people would need to use __builtin_sqrtf128 and __builtin_fmaf128) be
acceptable, while I delve into the appropriate incantations to get it to work
as desired be ok?

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-19 22:15   ` [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions Michael Meissner
@ 2017-10-19 23:00     ` Joseph Myers
  2017-10-19 23:00       ` Michael Meissner
  2017-10-24 22:40       ` [PATCH, version 3], " Michael Meissner
  0 siblings, 2 replies; 31+ messages in thread
From: Joseph Myers @ 2017-10-19 23:00 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Thu, 19 Oct 2017, Michael Meissner wrote:

>     1)	I switched to use DEF_EXT_LIB_BUILTIN to declare the _Float<N> and
> 	_Float<N>X functions.  This allows treating __builtin_sqrtf128 the same
> 	as sqrtf128.

It's not correct to do that unconditionally for all the existing 
DEF_GCC_FLOATN_NX_BUILTINS functions.  There should not be a public 
huge_valf128 function any more than a public huge_val function, just 
__builtin_huge_valf128.

Rather, you should add a new DEF_EXT_LIB_FLOATN_NX_BUILTINS.  It should be 
used by the new functions, and by the existing copysign / fabs / nan 
functions.  It should not be used by the existing huge_val / inf / nans 
functions.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-19 23:00       ` Michael Meissner
@ 2017-10-19 23:08         ` Joseph Myers
  0 siblings, 0 replies; 31+ messages in thread
From: Joseph Myers @ 2017-10-19 23:08 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Fri, 20 Oct 2017, Michael Meissner wrote:

> On Thu, Oct 19, 2017 at 10:15:44PM +0000, Joseph Myers wrote:
> > On Thu, 19 Oct 2017, Michael Meissner wrote:
> > 
> > >     1)	I switched to use DEF_EXT_LIB_BUILTIN to declare the _Float<N> and
> > > 	_Float<N>X functions.  This allows treating __builtin_sqrtf128 the same
> > > 	as sqrtf128.
> > 
> > It's not correct to do that unconditionally for all the existing 
> > DEF_GCC_FLOATN_NX_BUILTINS functions.  There should not be a public 
> > huge_valf128 function any more than a public huge_val function, just 
> > __builtin_huge_valf128.
> > 
> > Rather, you should add a new DEF_EXT_LIB_FLOATN_NX_BUILTINS.  It should be 
> > used by the new functions, and by the existing copysign / fabs / nan 
> > functions.  It should not be used by the existing huge_val / inf / nans 
> > functions.
> 
> Ok.  Would an initial patch to go back to using DEF_GCC_BUILTIN (which means
> people would need to use __builtin_sqrtf128 and __builtin_fmaf128) be
> acceptable, while I delve into the appropriate incantations to get it to work
> as desired be ok?

My argument was that *if* you provide __FP_FAST_FMAF128 (etc.), that 
should relate to an fmaf128 (etc.) built-in function.  If you don't define 
__FP_FAST_*, doing everything with DEF_GCC_BUILTIN would be reasonable as 
a starting point (with a view to moving selected functions to 
DEF_EXT_LIB_BUILTIN and defining __FP_FAST_* in a subsequent patch, and 
subject to calls still falling back to call the right external functions, 
e.g. sqrtf128 to deal with the errno-setting case of __builtin_sqrtf128).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 3], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-19 23:00     ` Joseph Myers
  2017-10-19 23:00       ` Michael Meissner
@ 2017-10-24 22:40       ` Michael Meissner
  2017-10-24 23:13         ` Joseph Myers
  1 sibling, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-24 22:40 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 6274 bytes --]

On Thu, Oct 19, 2017 at 10:15:44PM +0000, Joseph Myers wrote:
> On Thu, 19 Oct 2017, Michael Meissner wrote:
> 
> >     1)	I switched to use DEF_EXT_LIB_BUILTIN to declare the _Float<N> and
> > 	_Float<N>X functions.  This allows treating __builtin_sqrtf128 the same
> > 	as sqrtf128.
> 
> It's not correct to do that unconditionally for all the existing 
> DEF_GCC_FLOATN_NX_BUILTINS functions.  There should not be a public 
> huge_valf128 function any more than a public huge_val function, just 
> __builtin_huge_valf128.
> 
> Rather, you should add a new DEF_EXT_LIB_FLOATN_NX_BUILTINS.  It should be 
> used by the new functions, and by the existing copysign / fabs / nan 
> functions.  It should not be used by the existing huge_val / inf / nans 
> functions.

This patch adds a new switch (-fimplicit-math-floatn) that when enabled, it
will add implicit declarations for copysign, fabs, fma, fmax, fmin, nan, and
sqrt _Float<N> and _Float<N>X variants.  Like the previous patch, it adds fma,
fmax, fmin, and sqrt builtins to the machine independent built-in support, and
removed the PowerPC specific __builtin_{sqrt,fma}f128 functions.

I have bootstrapped this patch on a little endian power8 system and an x86-64
system.  There were no regressions in either system.  I added powerpc specific
tests for -f{,no-}implicit-math-floatn.  Can I check this patch into the trunk?

[gcc]
2017-10-24  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* builtins.c (CASE_MATHFN_FLOATN): New helper macro to add cases
	for math functions that have _Float<N> and _Float<N>X variants.
	(mathfn_built_in_2): Add support for math functions that have
	_Float<N> and _Float<N>X variants.
	(DEF_INTERNAL_FLT_FLOATN_FN): New helper macro.
	(expand_builtin_mathfn_ternary): Add support for fma with
	_Float<N> and _Float<N>X variants.
	(expand_builtin): Likewise.
	(fold_builtin_3): Likewise.
	* builtins.def (DEF_FLOATFN_BUILTIN_2): New macros.  If
	-fimplicit-math-floatn is on, treat the _Float<N> and _Float<N>X
	variants like DEF_EXT_LIB_BUILTINs where both <foo> and
	__builtin_<foo> are implicitly declared.  If
	-fimplicit-math-floatn is off, treat the variants like
	DEF_GCC_BUILTIN where only the __builtin_<foo> is implicitly
	declared.
	(DEF_FLOATFN_BUILTINS): Likewise.
	(BUILT_IN_COPYSIGN _Float<N> and _Float<N>X variants) Replace
	DEF_GCC_FLOATN_NX_BUILTINS with DEF_FLOATFN_BUILTINS.  Add fma,
	fmax, fmin, sqrt versions.  Do not replace huge_val, inf, and
	nans.
	(BUILT_IN_FABS _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMA _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMAX _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMIN _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_NAN _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_SQRT _Float<N> and _Float<N>X variants): Likewise.
	* builtin-types.def (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16): New
	function signatures for fma _Float<N> and _Float<N>X variants.
	(BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32): Likewise.
	(BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64): Likewise.
	(BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128): Likewise.
	(BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X): Likewise.
	(BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X): Likewise.
	(BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X): Likewise.
	* gencfn-macros.c (print_case_cfn): Add support for math functions
	that have _Float<N> and _Float<N>X variants.
	(print_define_operator_list): Likewise.
	(fltfn_suffixes): Likewise.
	(main): Likewise.
	* internal-fn.def (DEF_INTERNAL_FLT_FLOATN_FN): New helper macro
	for math functions that have _Float<N> and _Float<N>X variants.
	(SQRT): Add support for sqrt, copysign, fmin and fmax _Float<N>
	and _Float<N>X variants.
	(COPYSIGN): Likewise.
	(FMIN): Likewise.
	(FMAX): Likewise.
	* fold-const.c (tree_call_nonnegative_warnv_p): Add support for
	copysign, fma, fmax, fmin, and sqrt _Float<N> and _Float<N>X
	variants.
	(integer_valued_read_call_p): Likewise.
	* fold-const-call.c (fold_const_call_ss): Likewise.
	(fold_const_call_sss): Add support for copysign, fmin, and fmax
	_Float<N> and _Float<N>X variants.
	(fold_const_call_ssss): Add support for fma _Float<N> and
	_Float<N>X variants.
	* gimple-ssa-backprop.c (backprop::process_builtin_call_use): Add
	support for copysign and fma _Float<N> and _Float<N>X variants.
	(backprop::process_builtin_call_use): Likewise.
	* tree-call-cdce.c (can_test_argument_range); Add support for
	sqrt _Float<N> and _Float<N>X variants.
	(edom_only_function): Likewise.
	(get_no_error_domain): Likewise.
	* tree-ssa-math-opts.c (internal_fn_reciprocal): Likewise.
	* tree-ssa-reassoc.c (attempt_builtin_copysign): Add support for
	copysign _Float<N> and _Float<N>X variants.
	* config/rs6000/rs6000-builtin.def (SQRTF128): Delete, this is now
	handled by machine independent code.
	(FMAF128): Likewise.
	* doc/invoke.texi (C Dialect Options): Document
	-fimplicit-math-floatn.

[gcc/c]
2017-10-24  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-decl.c (header_for_builtin_fn): Add support for copysign, fma,
	fmax, fmin, and sqrt _Float<N> and _Float<N>X variants.

[gcc/c-family]
2017-10-24  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-cppbuiltin.c (mode_has_fma): Add support for PowerPC KFmode.
	(c_cpp_builtins): If -fimplicit-math-floatn and the machine has a
	fast fma _Float<N> and _Float<N>X variant, define __FP_FAST_FMA<N>
	and __FP_FAST_FMA<N>X.
	* c.opt (-fimplicit-math-floatn): New switch to enable making
	_Float<N> and _Float<N>X variant math functions implicitly
	declared without the __builtin_ prefix.

[gcc/testsuite]
2017-10-24  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/float128-hw.c: Add support for all 4 FMA
	variants.  Check conversion from __float128 to float uses truncate
	with round to odd.  Use {\m...\M} in the tests.
	* gcc.target/powerpc/float128-hw2.c: New test for
	-fimplicit-math-floatn.
	* gcc.target/powerpc/float128-hw3.c: New test for
	-fno-implicit-math-floatn.
	* gcc.target/powerpc/float128-fma2.c: Delete, test is no longer
	valid.
	* gcc.target/powerpc/float128-sqrt2.c: Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch43b --]
[-- Type: text/plain, Size: 36784 bytes --]

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 254054)
+++ gcc/builtins.c	(working copy)
@@ -1816,14 +1816,26 @@ expand_builtin_classify_type (tree exp)
   return GEN_INT (no_type_class);
 }
 
-/* This helper macro, meant to be used in mathfn_built_in below,
-   determines which among a set of three builtin math functions is
-   appropriate for a given type mode.  The `F' and `L' cases are
-   automatically generated from the `double' case.  */
+/* This helper macro, meant to be used in mathfn_built_in below, determines
+   which among a set of builtin math functions is appropriate for a given type
+   mode.  The `F' (float) and `L' (long double) are automatically generated
+   from the 'double' case.  If a function supports the _Float<N> and _Float<N>X
+   types, there are additional types that are considered with 'F32', 'F64',
+   'F128', etc. suffixes.  */
 #define CASE_MATHFN(MATHFN) \
   CASE_CFN_##MATHFN: \
   fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
   fcodel = BUILT_IN_##MATHFN##L ; break;
+/* Similar to the above, but also add support for the _Float<N> and _Float<N>X
+   types.  */
+#define CASE_MATHFN_FLOATN(MATHFN) \
+  CASE_CFN_##MATHFN: \
+  fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
+  fcodel = BUILT_IN_##MATHFN##L ; fcodef16 = BUILT_IN_##MATHFN##F16 ; \
+  fcodef32 = BUILT_IN_##MATHFN##F32; fcodef64 = BUILT_IN_##MATHFN##F64 ; \
+  fcodef128 = BUILT_IN_##MATHFN##F128 ; fcodef32x = BUILT_IN_##MATHFN##F32X ; \
+  fcodef64x = BUILT_IN_##MATHFN##F64X ; fcodef128x = BUILT_IN_##MATHFN##F128X ;\
+  break;
 /* Similar to above, but appends _R after any F/L suffix.  */
 #define CASE_MATHFN_REENT(MATHFN) \
   case CFN_BUILT_IN_##MATHFN##_R: \
@@ -1840,7 +1852,15 @@ expand_builtin_classify_type (tree exp)
 static built_in_function
 mathfn_built_in_2 (tree type, combined_fn fn)
 {
+  tree mtype;
   built_in_function fcode, fcodef, fcodel;
+  built_in_function fcodef16 = END_BUILTINS;
+  built_in_function fcodef32 = END_BUILTINS;
+  built_in_function fcodef64 = END_BUILTINS;
+  built_in_function fcodef128 = END_BUILTINS;
+  built_in_function fcodef32x = END_BUILTINS;
+  built_in_function fcodef64x = END_BUILTINS;
+  built_in_function fcodef128x = END_BUILTINS;
 
   switch (fn)
     {
@@ -1854,7 +1874,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (CBRT)
     CASE_MATHFN (CEIL)
     CASE_MATHFN (CEXPI)
-    CASE_MATHFN (COPYSIGN)
+    CASE_MATHFN_FLOATN (COPYSIGN)
     CASE_MATHFN (COS)
     CASE_MATHFN (COSH)
     CASE_MATHFN (DREM)
@@ -1867,9 +1887,9 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (FABS)
     CASE_MATHFN (FDIM)
     CASE_MATHFN (FLOOR)
-    CASE_MATHFN (FMA)
-    CASE_MATHFN (FMAX)
-    CASE_MATHFN (FMIN)
+    CASE_MATHFN_FLOATN (FMA)
+    CASE_MATHFN_FLOATN (FMAX)
+    CASE_MATHFN_FLOATN (FMIN)
     CASE_MATHFN (FMOD)
     CASE_MATHFN (FREXP)
     CASE_MATHFN (GAMMA)
@@ -1923,7 +1943,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (SIN)
     CASE_MATHFN (SINCOS)
     CASE_MATHFN (SINH)
-    CASE_MATHFN (SQRT)
+    CASE_MATHFN_FLOATN (SQRT)
     CASE_MATHFN (TAN)
     CASE_MATHFN (TANH)
     CASE_MATHFN (TGAMMA)
@@ -1936,12 +1956,27 @@ mathfn_built_in_2 (tree type, combined_f
       return END_BUILTINS;
     }
 
-  if (TYPE_MAIN_VARIANT (type) == double_type_node)
+  mtype = TYPE_MAIN_VARIANT (type);
+  if (mtype == double_type_node)
     return fcode;
-  else if (TYPE_MAIN_VARIANT (type) == float_type_node)
+  else if (mtype == float_type_node)
     return fcodef;
-  else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
+  else if (mtype == long_double_type_node)
     return fcodel;
+  else if (mtype == float16_type_node)
+    return fcodef16;
+  else if (mtype == float32_type_node)
+    return fcodef32;
+  else if (mtype == float64_type_node)
+    return fcodef64;
+  else if (mtype == float128_type_node)
+    return fcodef128;
+  else if (mtype == float32x_type_node)
+    return fcodef32x;
+  else if (mtype == float64x_type_node)
+    return fcodef64x;
+  else if (mtype == float128x_type_node)
+    return fcodef128x;
   else
     return END_BUILTINS;
 }
@@ -1995,6 +2030,9 @@ associated_internal_fn (tree fndecl)
     {
 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME;
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+    CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME; \
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_##NAME): return IFN_##NAME;
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_INT_FN (BUILT_IN_##NAME): return IFN_##NAME;
 #include "internal-fn.def"
@@ -2068,6 +2106,7 @@ expand_builtin_mathfn_ternary (tree exp,
   switch (DECL_FUNCTION_CODE (fndecl))
     {
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       builtin_optab = fma_optab; break;
     default:
       gcc_unreachable ();
@@ -6567,6 +6606,7 @@ expand_builtin (tree exp, rtx target, rt
       break;
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       target = expand_builtin_mathfn_ternary (exp, target, subtarget);
       if (target)
 	return target;
@@ -8996,6 +9036,7 @@ fold_builtin_3 (location_t loc, tree fnd
       return fold_builtin_sincos (loc, arg0, arg1, arg2);
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       return fold_builtin_fma (loc, arg0, arg1, arg2, type);
 
     CASE_FLT_FN (BUILT_IN_REMQUO):
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(revision 254054)
+++ gcc/builtins.def	(working copy)
@@ -100,6 +100,33 @@ along with GCC; see the file COPYING3.
   DEF_GCC_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS) \
   DEF_GCC_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), ATTRS)
 
+/* A set of GCC builtins for _FloatN and _FloatNx types.  TYPE_MACRO is called
+   with an argument such as FLOAT32 to produce the enum value for the type.
+   Unlike DEF_GCC_FLOATN_NX_BUILTINS, these definitions use the
+   -fimplicit-math-floatn option to determine whether to implicitly declare the
+   function without the __builtin_ prefix or not in addition to defining the
+   function with the __builtin_prefix.  */
+#undef DEF_FLOATN_BUILTIN_2
+#define DEF_FLOATN_BUILTIN_2(ENUM, NAME, TYPE, ATTRS)			\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE,		\
+	       flag_implicit_math_floatn ? TYPE : BT_LAST,		\
+	       !!flag_implicit_math_floatn, !!flag_implicit_math_floatn, \
+	       false, ATTRS, true, true)
+
+#undef DEF_FLOATN_BUILTINS
+#define DEF_FLOATN_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)		\
+  DEF_FLOATN_BUILTIN_2 (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
+  DEF_FLOATN_BUILTIN_2 (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
+  DEF_FLOATN_BUILTIN_2 (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
+  DEF_FLOATN_BUILTIN_2 (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), \
+			ATTRS)						\
+  DEF_FLOATN_BUILTIN_2 (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), \
+			ATTRS)						\
+  DEF_FLOATN_BUILTIN_2 (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), \
+			ATTRS)						\
+  DEF_FLOATN_BUILTIN_2 (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), \
+			ATTRS)
+
 /* A library builtin (like __builtin_strchr) is a builtin equivalent
    of an ANSI/ISO standard library function.  In addition to the
    `__builtin' version, we will create an ordinary version (e.g,
@@ -324,7 +351,7 @@ DEF_C99_BUILTIN        (BUILT_IN_COPYSIG
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define COPYSIGN_TYPE(F) BT_FN_##F##_##F##_##F
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_FLOATN_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef COPYSIGN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
@@ -357,7 +384,7 @@ DEF_LIB_BUILTIN        (BUILT_IN_FABS, "
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define FABS_TYPE(F) BT_FN_##F##_##F
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_FLOATN_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef FABS_TYPE
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
@@ -382,12 +409,21 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL,
 DEF_C99_BUILTIN        (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+#define FMA_TYPE(F) BT_FN_##F##_##F##_##F##_##F
+DEF_FLOATN_BUILTINS (BUILT_IN_FMA, "fma", FMA_TYPE, ATTR_MATHFN_FPROUNDING)
+#undef FMA_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMAX_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_FLOATN_BUILTINS (BUILT_IN_FMAX, "fmax", FMAX_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMAX_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMIN_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_FLOATN_BUILTINS (BUILT_IN_FMIN, "fmin", FMIN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMIN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
@@ -495,7 +531,7 @@ DEF_C99_BUILTIN        (BUILT_IN_NAN, "n
 DEF_C99_BUILTIN        (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_C99_BUILTIN        (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 #define NAN_TYPE(F) BT_FN_##F##_CONST_STRING
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_NAN, "nan", NAN_TYPE, ATTR_CONST_NOTHROW_NONNULL)
+DEF_FLOATN_BUILTINS (BUILT_IN_NAN, "nan", NAN_TYPE, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
@@ -564,6 +600,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "
 DEF_LIB_BUILTIN        (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#define SQRT_TYPE(F) BT_FN_##F##_##F
+DEF_FLOATN_BUILTINS (BUILT_IN_SQRT, "sqrt", SQRT_TYPE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#undef SQRT_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_LIB_BUILTIN        (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
Index: gcc/builtin-types.def
===================================================================
--- gcc/builtin-types.def	(revision 254054)
+++ gcc/builtin-types.def	(working copy)
@@ -544,6 +544,20 @@ DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE
 		     BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
 DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
 		     BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16,
+		     BT_FLOAT16, BT_FLOAT16, BT_FLOAT16, BT_FLOAT16)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32,
+		     BT_FLOAT32, BT_FLOAT32, BT_FLOAT32, BT_FLOAT32)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64,
+		     BT_FLOAT64, BT_FLOAT64, BT_FLOAT64, BT_FLOAT64)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128,
+		     BT_FLOAT128, BT_FLOAT128, BT_FLOAT128, BT_FLOAT128)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X,
+		     BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X,
+		     BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X,
+		     BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
 DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_INTPTR,
 		     BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_INT_PTR)
 DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
Index: gcc/gencfn-macros.c
===================================================================
--- gcc/gencfn-macros.c	(revision 254054)
+++ gcc/gencfn-macros.c	(working copy)
@@ -98,11 +98,12 @@ is_group (string_set *builtins, const ch
 
 static void
 print_case_cfn (const char *name, bool internal_p,
-		const char *const *suffixes)
+		const char *const *suffixes, bool floatn_p)
 {
-  printf ("#define CASE_CFN_%s", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("#define CASE_CFN_%s%s", name, floatn);
   if (internal_p)
-    printf (" \\\n  case CFN_%s", name);
+    printf (" \\\n  case CFN_%s%s", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("%s \\\n  case CFN_BUILT_IN_%s%s",
 	    internal_p || i > 0 ? ":" : "", name, suffixes[i]);
@@ -115,9 +116,10 @@ print_case_cfn (const char *name, bool i
 
 static void
 print_define_operator_list (const char *name, bool internal_p,
-			    const char *const *suffixes)
+			    const char *const *suffixes, bool floatn_p)
 {
-  printf ("(define_operator_list %s\n", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("(define_operator_list %s%s\n", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("    BUILT_IN_%s%s\n", name, suffixes[i]);
   if (internal_p)
@@ -148,6 +150,8 @@ const char *const internal_fn_int_names[
 };
 
 static const char *const flt_suffixes[] = { "F", "", "L", NULL };
+static const char *const fltfn_suffixes[] = { "F16", "F32", "F128", "F32X",
+					      "F64X", "F128X", NULL };
 static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
 
 static const char *const *const suffix_lists[] = {
@@ -200,15 +204,33 @@ main (int argc, char **argv)
 	{
 	  const char *root = name + 9;
 	  for (unsigned int j = 0; suffix_lists[j]; ++j)
-	    if (is_group (&builtins, root, suffix_lists[j]))
-	      {
-		bool internal_p = internal_fns.contains (root);
-		if (type == 'c')
-		  print_case_cfn (root, internal_p, suffix_lists[j]);
-		else
-		  print_define_operator_list (root, internal_p,
-					      suffix_lists[j]);
-	      }
+	    {
+	      const char *const *const suffix = suffix_lists[j];
+
+	      if (is_group (&builtins, root, suffix))
+		{
+		  bool internal_p = internal_fns.contains (root);
+
+		  if (type == 'c')
+		    print_case_cfn (root, internal_p, suffix, false);
+		  else
+		    print_define_operator_list (root, internal_p,
+						suffix, false);
+
+		      /* Support the _Float<N> and _Float<N>X math functions if
+			 they exist.  We put these out as a separate CFN macro,
+			 so code can add support or not as needed.  */
+		  if (suffix == flt_suffixes
+		      && is_group (&builtins, root, fltfn_suffixes))
+		    {
+		      if (type == 'c')
+			print_case_cfn (root, false, fltfn_suffixes, true);
+		      else
+			print_define_operator_list (root, false, fltfn_suffixes,
+						    true);
+		    }
+		}
+	    }
 	}
     }
 
Index: gcc/internal-fn.def
===================================================================
--- gcc/internal-fn.def	(revision 254054)
+++ gcc/internal-fn.def	(working copy)
@@ -80,6 +80,11 @@ along with GCC; see the file COPYING3.
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
 #endif
 
+#ifndef DEF_INTERNAL_FLT_FLOATN_FN
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+  DEF_INTERNAL_FLT_FN (NAME, FLAGS, OPTAB, TYPE)
+#endif
+
 #ifndef DEF_INTERNAL_INT_FN
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
@@ -109,7 +114,7 @@ DEF_INTERNAL_FLT_FN (LOG2, ECF_CONST, lo
 DEF_INTERNAL_FLT_FN (LOGB, ECF_CONST, logb, unary)
 DEF_INTERNAL_FLT_FN (SIGNIFICAND, ECF_CONST, significand, unary)
 DEF_INTERNAL_FLT_FN (SIN, ECF_CONST, sin, unary)
-DEF_INTERNAL_FLT_FN (SQRT, ECF_CONST, sqrt, unary)
+DEF_INTERNAL_FLT_FLOATN_FN (SQRT, ECF_CONST, sqrt, unary)
 DEF_INTERNAL_FLT_FN (TAN, ECF_CONST, tan, unary)
 
 /* FP rounding.  */
@@ -122,13 +127,13 @@ DEF_INTERNAL_FLT_FN (TRUNC, ECF_CONST, b
 
 /* Binary math functions.  */
 DEF_INTERNAL_FLT_FN (ATAN2, ECF_CONST, atan2, binary)
-DEF_INTERNAL_FLT_FN (COPYSIGN, ECF_CONST, copysign, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (COPYSIGN, ECF_CONST, copysign, binary)
 DEF_INTERNAL_FLT_FN (FMOD, ECF_CONST, fmod, binary)
 DEF_INTERNAL_FLT_FN (POW, ECF_CONST, pow, binary)
 DEF_INTERNAL_FLT_FN (REMAINDER, ECF_CONST, remainder, binary)
 DEF_INTERNAL_FLT_FN (SCALB, ECF_CONST, scalb, binary)
-DEF_INTERNAL_FLT_FN (FMIN, ECF_CONST, fmin, binary)
-DEF_INTERNAL_FLT_FN (FMAX, ECF_CONST, fmax, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMIN, ECF_CONST, fmin, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMAX, ECF_CONST, fmax, binary)
 DEF_INTERNAL_OPTAB_FN (XORSIGN, ECF_CONST, xorsign, binary)
 
 /* FP scales.  */
@@ -230,5 +235,6 @@ DEF_INTERNAL_FN (DIVMOD, ECF_CONST | ECF
 
 #undef DEF_INTERNAL_INT_FN
 #undef DEF_INTERNAL_FLT_FN
+#undef DEF_INTERNAL_FLT_FLOATN_FN
 #undef DEF_INTERNAL_OPTAB_FN
 #undef DEF_INTERNAL_FN
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 254054)
+++ gcc/fold-const.c	(working copy)
@@ -12761,6 +12761,7 @@ tree_call_nonnegative_warnv_p (tree type
       return true;
 
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       /* sqrt(-0.0) is -0.0.  */
       if (!HONOR_SIGNED_ZEROS (element_mode (type)))
 	return true;
@@ -12805,14 +12806,17 @@ tree_call_nonnegative_warnv_p (tree type
       return RECURSE (arg0);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       /* True if the 1st OR 2nd arguments are nonnegative.  */
       return RECURSE (arg0) || RECURSE (arg1);
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       /* True if the 1st AND 2nd arguments are nonnegative.  */
       return RECURSE (arg0) && RECURSE (arg1);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* True if the 2nd argument is nonnegative.  */
       return RECURSE (arg1);
 
@@ -13311,7 +13315,9 @@ integer_valued_real_call_p (combined_fn
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return RECURSE (arg0) && RECURSE (arg1);
 
     default:
Index: gcc/fold-const-call.c
===================================================================
--- gcc/fold-const-call.c	(revision 254054)
+++ gcc/fold-const-call.c	(working copy)
@@ -596,6 +596,7 @@ fold_const_call_ss (real_value *result,
   switch (fn)
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       return (real_compare (GE_EXPR, arg, &dconst0)
 	      && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
 
@@ -1179,14 +1180,17 @@ fold_const_call_sss (real_value *result,
       return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       *result = *arg0;
       real_copysign (result, arg1);
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
 
     CASE_CFN_POW:
@@ -1473,6 +1477,7 @@ fold_const_call_ssss (real_value *result
   switch (fn)
     {
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
 
     default:
Index: gcc/gimple-ssa-backprop.c
===================================================================
--- gcc/gimple-ssa-backprop.c	(revision 254054)
+++ gcc/gimple-ssa-backprop.c	(working copy)
@@ -354,6 +354,7 @@ backprop::process_builtin_call_use (gcal
       break;
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* The sign of the first input is ignored.  */
       if (rhs != gimple_call_arg (call, 1))
 	info->flags.ignore_sign = true;
@@ -373,6 +374,7 @@ backprop::process_builtin_call_use (gcal
       }
 
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       /* In X * X + Y, where Y is distinct from X, the sign of X doesn't
 	 matter.  */
       if (gimple_call_arg (call, 0) == rhs
@@ -689,6 +691,7 @@ strip_sign_op_1 (tree rhs)
     switch (gimple_call_combined_fn (call))
       {
       CASE_CFN_COPYSIGN:
+      CASE_CFN_COPYSIGN_FN:
 	return gimple_call_arg (call, 0);
 
       default:
Index: gcc/tree-call-cdce.c
===================================================================
--- gcc/tree-call-cdce.c	(revision 254054)
+++ gcc/tree-call-cdce.c	(working copy)
@@ -314,6 +314,7 @@ can_test_argument_range (gcall *call)
     CASE_FLT_FN (BUILT_IN_POW10):
     /* Sqrt.  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return check_builtin_call (call);
     /* Special one: two argument pow.  */
     case BUILT_IN_POW:
@@ -342,6 +343,7 @@ edom_only_function (gcall *call)
     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
     CASE_FLT_FN (BUILT_IN_SIN):
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
     CASE_FLT_FN (BUILT_IN_FMOD):
     CASE_FLT_FN (BUILT_IN_REMAINDER):
       return true;
@@ -703,6 +705,7 @@ get_no_error_domain (enum built_in_funct
                          308, true, false);
     /* sqrt: [0, +inf)  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return get_domain (0, true, true,
                          0, false, false);
     default:
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(revision 254054)
+++ gcc/tree-ssa-math-opts.c	(working copy)
@@ -515,6 +515,7 @@ internal_fn_reciprocal (gcall *call)
   switch (gimple_call_combined_fn (call))
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       ifn = IFN_RSQRT;
       break;
 
Index: gcc/tree-ssa-reassoc.c
===================================================================
--- gcc/tree-ssa-reassoc.c	(revision 254054)
+++ gcc/tree-ssa-reassoc.c	(working copy)
@@ -5625,6 +5625,7 @@ attempt_builtin_copysign (vec<operand_en
 	      switch (gimple_call_combined_fn (old_call))
 		{
 		CASE_CFN_COPYSIGN:
+		CASE_CFN_COPYSIGN_FN:
 		  arg0 = gimple_call_arg (old_call, 0);
 		  arg1 = gimple_call_arg (old_call, 1);
 		  /* The first argument of copysign must be a constant,
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 254054)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -2374,17 +2374,13 @@ BU_FLOAT128_1 (FABSQ,		"fabsq",       CO
 BU_FLOAT128_2 (COPYSIGNQ,	"copysignq",   CONST, copysignkf3)
 
 /* 1, 2, and 3 argument IEEE 128-bit floating point functions that require ISA
-   3.0 hardware.  These functions use the new 'f128' suffix.  Eventually the
-   standard functions should be folded into the common built-in function
-   handling. */
-BU_FLOAT128_1_HW (SQRTF128,	 "sqrtf128",		   CONST, sqrtkf2)
+   3.0 hardware.  These functions use the new 'f128' suffix.  */
 BU_FLOAT128_1_HW (SQRTF128_ODD,	 "sqrtf128_round_to_odd",  CONST, sqrtkf2_odd)
 BU_FLOAT128_1_HW (TRUNCF128_ODD, "truncf128_round_to_odd", CONST, trunckfdf2_odd)
 BU_FLOAT128_2_HW (ADDF128_ODD,	 "addf128_round_to_odd",   CONST, addkf3_odd)
 BU_FLOAT128_2_HW (SUBF128_ODD,	 "subf128_round_to_odd",   CONST, subkf3_odd)
 BU_FLOAT128_2_HW (MULF128_ODD,	 "mulf128_round_to_odd",   CONST, mulkf3_odd)
 BU_FLOAT128_2_HW (DIVF128_ODD,	 "divf128_round_to_odd",   CONST, divkf3_odd)
-BU_FLOAT128_3_HW (FMAF128,	 "fmaf128",		   CONST, fmakf4_hw)
 BU_FLOAT128_3_HW (FMAF128_ODD,	 "fmaf128_round_to_odd",   CONST, fmakf4_odd)
 \f
 /* 1 argument crypto functions.  */
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 254054)
+++ gcc/doc/invoke.texi	(working copy)
@@ -181,7 +181,8 @@ in the following sections.
 -fpermitted-flt-eval-methods=@var{standard} @gol
 -aux-info @var{filename}  -fallow-parameterless-variadic-functions @gol
 -fno-asm  -fno-builtin  -fno-builtin-@var{function}  -fgimple@gol
--fhosted  -ffreestanding  -fopenacc  -fopenmp  -fopenmp-simd @gol
+-fhosted  -ffreestanding  -fimplicit-math-floatn -fopenacc  @gol
+-fopenmp  -fopenmp-simd @gol
 -fms-extensions  -fplan9-extensions  -fsso-struct=@var{endianness} @gol
 -fallow-single-precision  -fcond-mismatch  -flax-vector-conversions @gol
 -fsigned-bitfields  -fsigned-char @gol
@@ -2046,6 +2047,17 @@ This is equivalent to @option{-fno-hoste
 @xref{Standards,,Language Standards Supported by GCC}, for details of
 freestanding and hosted environments.
 
+@item -fimplicit-math-floatn
+@opindex fimplicit-math-floatn
+@cindex Implicit _Float<N> and _Float<N>X math functions
+Declare some of the built-in math functions that use the _Float<N> and
+_Float<N>X types that are from the ISO/IEC TS 18661-3:2015 technical
+note implicitly.  The default for @option{-fimplicit-math-floatn} is
+off.
+
+@xref{Floating Types}, for details of the ISO/IEC TS
+18661-3:2015 _Float<N> and _Float<N>X types.
+
 @item -fopenacc
 @opindex fopenacc
 @cindex OpenACC accelerator programming
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 254054)
+++ gcc/c/c-decl.c	(working copy)
@@ -3160,6 +3160,7 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_CBRT):
     CASE_FLT_FN (BUILT_IN_CEIL):
     CASE_FLT_FN (BUILT_IN_COPYSIGN):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
     CASE_FLT_FN (BUILT_IN_COS):
     CASE_FLT_FN (BUILT_IN_COSH):
     CASE_FLT_FN (BUILT_IN_ERF):
@@ -3168,11 +3169,15 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_EXP2):
     CASE_FLT_FN (BUILT_IN_EXPM1):
     CASE_FLT_FN (BUILT_IN_FABS):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
     CASE_FLT_FN (BUILT_IN_FDIM):
     CASE_FLT_FN (BUILT_IN_FLOOR):
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
     CASE_FLT_FN (BUILT_IN_FMAX):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMAX):
     CASE_FLT_FN (BUILT_IN_FMIN):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMIN):
     CASE_FLT_FN (BUILT_IN_FMOD):
     CASE_FLT_FN (BUILT_IN_FREXP):
     CASE_FLT_FN (BUILT_IN_HYPOT):
@@ -3204,6 +3209,7 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_SINH):
     CASE_FLT_FN (BUILT_IN_SINCOS):
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
     CASE_FLT_FN (BUILT_IN_TAN):
     CASE_FLT_FN (BUILT_IN_TANH):
     CASE_FLT_FN (BUILT_IN_TGAMMA):
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c	(revision 254054)
+++ gcc/c-family/c-cppbuiltin.c	(working copy)
@@ -82,6 +82,11 @@ mode_has_fma (machine_mode mode)
       return !!HAVE_fmadf4;
 #endif
 
+#ifdef HAVE_fmakf4	/* PowerPC if long double != __float128.  */
+    case E_KFmode:
+      return !!HAVE_fmakf4;
+#endif
+
 #ifdef HAVE_fmaxf4
     case E_XFmode:
       return !!HAVE_fmaxf4;
@@ -1119,7 +1124,8 @@ c_cpp_builtins (cpp_reader *pfile)
 	       floatn_nx_types[i].extended ? "X" : "");
       sprintf (csuffix, "F%d%s", floatn_nx_types[i].n,
 	       floatn_nx_types[i].extended ? "x" : "");
-      builtin_define_float_constants (prefix, csuffix, "%s", NULL,
+      const char *csuffix2 = flag_implicit_math_floatn ? csuffix : NULL;
+      builtin_define_float_constants (prefix, csuffix, "%s", csuffix2,
 				      FLOATN_NX_TYPE_NODE (i));
     }
 
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 254054)
+++ gcc/c-family/c.opt	(working copy)
@@ -1468,6 +1468,14 @@ fimplicit-inline-templates
 C++ ObjC++ Var(flag_implicit_inline_templates) Init(1)
 Emit implicit instantiations of inline templates.
 
+; Even though the _Float<N> and _Float<N>X are C only, allow
+; -fimplicit-math-floatn for C++ since the two targets (X86-64 and PowerPC)
+; that support IEEE 128-bit floating point also support a __float128 keyword
+; that can be used in C++.
+fimplicit-math-floatn
+C ObjC C++ ObjC++ Var(flag_implicit_math_floatn) Init(0)
+Emit implicit _Float<N> and _Float<N>X math built-in functions.
+
 fimplicit-templates
 C++ ObjC++ Var(flag_implicit_templates) Init(1)
 Emit implicit instantiations of templates.
Index: gcc/testsuite/gcc.target/powerpc/float128-hw.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw.c	(revision 254054)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw.c	(working copy)
@@ -7,11 +7,20 @@ __float128 f128_sub (__float128 a, __flo
 __float128 f128_mul (__float128 a, __float128 b) { return a*b; }
 __float128 f128_div (__float128 a, __float128 b) { return a/b; }
 __float128 f128_fma (__float128 a, __float128 b, __float128 c) { return (a*b)+c; }
+__float128 f128_fms (__float128 a, __float128 b, __float128 c) { return (a*b)-c; }
+__float128 f128_nfma (__float128 a, __float128 b, __float128 c) { return -((a*b)+c); }
+__float128 f128_nfms (__float128 a, __float128 b, __float128 c) { return -((a*b)-c); }
 long f128_cmove (__float128 a, __float128 b, long c, long d) { return (a == b) ? c : d; }
+float f128_to_flt (__float128 a) { return (float)a; }
+
+/* { dg-final { scan-assembler {\mxsaddqp\M}   } } */
+/* { dg-final { scan-assembler {\mxssubqp\M}   } } */
+/* { dg-final { scan-assembler {\mxsmulqp\M}   } } */
+/* { dg-final { scan-assembler {\mxsdivqp\M}   } } */
+/* { dg-final { scan-assembler {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler {\mxscmpuqp\M}  } } */
+/* { dg-final { scan-assembler {\mxscvqpdpo\M} } } */
 
-/* { dg-final { scan-assembler "xsaddqp"  } } */
-/* { dg-final { scan-assembler "xssubqp"  } } */
-/* { dg-final { scan-assembler "xsmulqp"  } } */
-/* { dg-final { scan-assembler "xsdivqp"  } } */
-/* { dg-final { scan-assembler "xsmaddqp" } } */
-/* { dg-final { scan-assembler "xscmpuqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-hw2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(working copy)
@@ -0,0 +1,56 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math -fimplicit-math-floatn" } */
+
+/* Test to make sure the compiler handles the standard _Float128 functions that
+   have hardware support in ISA 3.0/power9.  */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+extern _Float128 sqrtf128 (_Float128);
+extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return copysignf128 (a, b);
+}
+
+_Float128
+do_sqrt (_Float128 a)
+{
+  return sqrtf128 (a);
+}
+
+_Float128
+do_fma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, c);
+}
+
+_Float128
+do_fms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, -c);
+}
+
+_Float128
+do_nfma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, c);
+}
+
+_Float128
+do_nfms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler     {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler     {\mxssqrtqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler     {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M}        } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-hw3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw3.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw3.c	(working copy)
@@ -0,0 +1,55 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math -fno-implicit-math-floatn" } */
+
+/* Test to make sure the compiler calls the external function instead of doing
+   the built-in processing for _Float128 functions that have hardware support
+   in ISA 3.0/power9 if the option -fimplicit-math-floatn is not used.  */
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+extern _Float128 sqrtf128 (_Float128);
+extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return copysignf128 (a, b);
+}
+
+_Float128
+do_sqrt (_Float128 a)
+{
+  return sqrtf128 (a);
+}
+
+_Float128
+do_fma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, c);
+}
+
+_Float128
+do_fms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, -c);
+}
+
+_Float128
+do_nfma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, c);
+}
+
+_Float128
+do_nfms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler-not   {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler-not   {\mxssqrtqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler-not   {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler-times {\mbl\M} 6      } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-fma2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(revision 254054)
+++ gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(nonexistent)
@@ -1,9 +0,0 @@
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-/* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
-
-__float128
-xfma (__float128 a, __float128 b, __float128 c)
-{
-  return __builtin_fmaf128 (a, b, c); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
-}
Index: gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(revision 254054)
+++ gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(nonexistent)
@@ -1,9 +0,0 @@
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-/* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
-
-__float128
-xsqrt (__float128 a)
-{
-  return __builtin_sqrtf128 (a); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
-}

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 3], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-24 22:40       ` [PATCH, version 3], " Michael Meissner
@ 2017-10-24 23:13         ` Joseph Myers
  2017-10-24 23:58           ` Michael Meissner
  2017-10-25 19:25           ` [PATCH, version 4], " Michael Meissner
  0 siblings, 2 replies; 31+ messages in thread
From: Joseph Myers @ 2017-10-24 23:13 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Tue, 24 Oct 2017, Michael Meissner wrote:

> This patch adds a new switch (-fimplicit-math-floatn) that when enabled, it
> will add implicit declarations for copysign, fabs, fma, fmax, fmin, nan, and
> sqrt _Float<N> and _Float<N>X variants.  Like the previous patch, it adds fma,
> fmax, fmin, and sqrt builtins to the machine independent built-in support, and
> removed the PowerPC specific __builtin_{sqrt,fma}f128 functions.

I don't see why this new option is needed.  My expectation would be to use 
DEF_EXT_LIB_BUILTIN, as discussed before (i.e. declare the non-__builtin_* 
variants by default, but not if flag_iso).

That they should be declared by default is clear, in line with the normal 
principle of enabling GNU extensions by default.  That they should not be 
declared with existing -std=c11 etc. options is also clear.  Sometimes 
there may be a use for an option to enable particular features of a TS 
(e.g. -fpermitted-flt-eval-methods=ts-18661-3, 
-fno-fp-int-builtin-inexact), I just don't see the requirement for it in 
this particular case.  Of course, if in future TS 18661-3 gets added to 
C2x, such built-in functions could be enabled for -std=c2x, subject to any 
questions of the circumstances under which their names are reserved if the 
relevant feature test macros are not defined.

(There are various issues with the documentation of the new option as 
well.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 3], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-24 23:13         ` Joseph Myers
@ 2017-10-24 23:58           ` Michael Meissner
  2017-10-25 19:25           ` [PATCH, version 4], " Michael Meissner
  1 sibling, 0 replies; 31+ messages in thread
From: Michael Meissner @ 2017-10-24 23:58 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

On Tue, Oct 24, 2017 at 11:08:15PM +0000, Joseph Myers wrote:
> On Tue, 24 Oct 2017, Michael Meissner wrote:
> 
> > This patch adds a new switch (-fimplicit-math-floatn) that when enabled, it
> > will add implicit declarations for copysign, fabs, fma, fmax, fmin, nan, and
> > sqrt _Float<N> and _Float<N>X variants.  Like the previous patch, it adds fma,
> > fmax, fmin, and sqrt builtins to the machine independent built-in support, and
> > removed the PowerPC specific __builtin_{sqrt,fma}f128 functions.
> 
> I don't see why this new option is needed.  My expectation would be to use 
> DEF_EXT_LIB_BUILTIN, as discussed before (i.e. declare the non-__builtin_* 
> variants by default, but not if flag_iso).
> 
> That they should be declared by default is clear, in line with the normal 
> principle of enabling GNU extensions by default.  That they should not be 
> declared with existing -std=c11 etc. options is also clear.  Sometimes 
> there may be a use for an option to enable particular features of a TS 
> (e.g. -fpermitted-flt-eval-methods=ts-18661-3, 
> -fno-fp-int-builtin-inexact), I just don't see the requirement for it in 
> this particular case.  Of course, if in future TS 18661-3 gets added to 
> C2x, such built-in functions could be enabled for -std=c2x, subject to any 
> questions of the circumstances under which their names are reserved if the 
> relevant feature test macros are not defined.
> 
> (There are various issues with the documentation of the new option as 
> well.)

Ok, I misunderstood your previous comment.  I thought you were saying not to
export the normal functions (not huge_val, nan, inf) by default on the off
chance that somebody could declare a sqrtf128 function that did something
else.

I would prefer not to have the switch, but I wanted some way for fmaf128 and
sqrtf128 to automatically use the instructions.  I'll switch it to
DEF_EXT_LIB_BUILTIN, and delete the option.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 4], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-24 23:13         ` Joseph Myers
  2017-10-24 23:58           ` Michael Meissner
@ 2017-10-25 19:25           ` Michael Meissner
  2017-10-25 20:01             ` Michael Meissner
  2017-10-25 20:11             ` Joseph Myers
  1 sibling, 2 replies; 31+ messages in thread
From: Michael Meissner @ 2017-10-25 19:25 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 6465 bytes --]

On Tue, Oct 24, 2017 at 11:08:15PM +0000, Joseph Myers wrote:
> On Tue, 24 Oct 2017, Michael Meissner wrote:
> 
> > This patch adds a new switch (-fimplicit-math-floatn) that when enabled, it
> > will add implicit declarations for copysign, fabs, fma, fmax, fmin, nan, and
> > sqrt _Float<N> and _Float<N>X variants.  Like the previous patch, it adds fma,
> > fmax, fmin, and sqrt builtins to the machine independent built-in support, and
> > removed the PowerPC specific __builtin_{sqrt,fma}f128 functions.
> 
> I don't see why this new option is needed.  My expectation would be to use 
> DEF_EXT_LIB_BUILTIN, as discussed before (i.e. declare the non-__builtin_* 
> variants by default, but not if flag_iso).
> 
> That they should be declared by default is clear, in line with the normal 
> principle of enabling GNU extensions by default.  That they should not be 
> declared with existing -std=c11 etc. options is also clear.  Sometimes 
> there may be a use for an option to enable particular features of a TS 
> (e.g. -fpermitted-flt-eval-methods=ts-18661-3, 
> -fno-fp-int-builtin-inexact), I just don't see the requirement for it in 
> this particular case.  Of course, if in future TS 18661-3 gets added to 
> C2x, such built-in functions could be enabled for -std=c2x, subject to any 
> questions of the circumstances under which their names are reserved if the 
> relevant feature test macros are not defined.

This patch removes the -fimplicit-math-floatn switch that I put in the previous
patch.  It makes copysign, fabs, fma, fmax, fmin, nan, and sqrt have implicit
_Float<N> and _Float<N>X variants unless we are in strict ANSI/ISO mode.
Huge_val, inf, and nans do not get implicit functions created.

I have checked this on a little endian power8 system and an x86-64 system.
There were no regressions.  Can I check this into the trunk?

[gcc]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* builtins.c (CASE_MATHFN_FLOATN): New helper macro to add cases
	for math functions that have _Float<N> and _Float<N>X variants.
	(mathfn_built_in_2): Add support for math functions that have
	_Float<N> and _Float<N>X variants.
	(DEF_INTERNAL_FLT_FLOATN_FN): New helper macro.
	(expand_builtin_mathfn_ternary): Add support for fma with
	_Float<N> and _Float<N>X variants.
	(expand_builtin): Likewise.
	(fold_builtin_3): Likewise.
	* builtins.def (DEF_EXT_LIB_FLOATN_NX_BUILTINS): New macro to
	create math function _Float<N> and _Float<N>X variants as external
	library builtins.
	(BUILT_IN_COPYSIGN _Float<N> and _Float<N>X variants) Use
	DEF_EXT_LIB_FLOATN_NX_BUILTINS to make built-in functions using
	the __builtin_ prefix and if not strict ansi, without the prefix.
	(BUILT_IN_FABS _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMA _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMAX _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMIN _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_NAN _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_SQRT _Float<N> and _Float<N>X variants): Likewise.
	* builtin-types.def (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16): New
	function signatures for fma _Float<N> and _Float<N>X variants.
	(BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32): Likewise.
	(BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64): Likewise.
	(BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128): Likewise.
	(BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X): Likewise.
	(BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X): Likewise.
	(BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X): Likewise.
	* fold-const.c (tree_call_nonnegative_warnv_p): Add support for
	copysign, fma, fmax, fmin, and sqrt _Float<N> and _Float<N>X
	variants.
	(integer_valued_read_call_p): Likewise.
	* fold-const-call.c (fold_const_call_ss): Likewise.
	(fold_const_call_sss): Add support for copysign, fmin, and fmax
	_Float<N> and _Float<N>X variants.
	(fold_const_call_ssss): Add support for fma _Float<N> and
	_Float<N>X variants.
	* gencfn-macros.c (print_case_cfn): Add support for math functions
	that have _Float<N> and _Float<N>X variants.
	(print_define_operator_list): Likewise.
	(fltfn_suffixes): Likewise.
	(main): Likewise.
	* gimple-ssa-backprop.c (backprop::process_builtin_call_use): Add
	support for copysign and fma _Float<N> and _Float<N>X variants.
	(backprop::process_builtin_call_use): Likewise.
	* internal-fn.def (DEF_INTERNAL_FLT_FLOATN_FN): New helper macro
	for math functions that have _Float<N> and _Float<N>X variants.
	(SQRT): Add support for sqrt, copysign, fmin and fmax _Float<N>
	and _Float<N>X variants.
	(COPYSIGN): Likewise.
	(FMIN): Likewise.
	(FMAX): Likewise.
	* tree-call-cdce.c (can_test_argument_range); Add support for
	sqrt _Float<N> and _Float<N>X variants.
	(edom_only_function): Likewise.
	(get_no_error_domain): Likewise.
	* tree-ssa-math-opts.c (internal_fn_reciprocal): Likewise.
	* tree-ssa-reassoc.c (attempt_builtin_copysign): Add support for
	copysign _Float<N> and _Float<N>X variants.
	* config/rs6000/rs6000-builtin.def (SQRTF128): Delete, this is now
	handled by machine independent code.
	(FMAF128): Likewise.

[gcc/c]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-decl.c (header_for_builtin_fn): Add support for copysign, fma,
	fmax, fmin, and sqrt _Float<N> and _Float<N>X variants.

[gcc/c-family]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-cppbuiltin.c (mode_has_fma): Add support for PowerPC KFmode.
	(c_cpp_builtins): If -fimplicit-math-floatn and the machine has a
	fast fma _Float<N> and _Float<N>X variant, define __FP_FAST_FMA<N>
	and __FP_FAST_FMA<N>X.
	* c.opt (-fimplicit-math-floatn): New switch to enable making
	_Float<N> and _Float<N>X variant math functions implicitly
	declared without the __builtin_ prefix.

[gcc/testsuite]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/float128-hw.c: Add support for all 4 FMA
	variants.  Check various conversions to/from float128.  Check
	negation.  Use {\m...\M} in the tests.
	* gcc.target/powerpc/float128-hw2.c: New test for implicit
	_Float128 math functions.
	* gcc.target/powerpc/float128-hw3.c: New test for strict ansi mode
	not implicitly adding the _Float128 math functions.
	* gcc.target/powerpc/float128-fma2.c: Delete, test is no longer
	valid.
	* gcc.target/powerpc/float128-sqrt2.c: Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch45b --]
[-- Type: text/plain, Size: 35012 bytes --]

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 254054)
+++ gcc/builtins.c	(working copy)
@@ -1816,14 +1816,26 @@ expand_builtin_classify_type (tree exp)
   return GEN_INT (no_type_class);
 }
 
-/* This helper macro, meant to be used in mathfn_built_in below,
-   determines which among a set of three builtin math functions is
-   appropriate for a given type mode.  The `F' and `L' cases are
-   automatically generated from the `double' case.  */
+/* This helper macro, meant to be used in mathfn_built_in below, determines
+   which among a set of builtin math functions is appropriate for a given type
+   mode.  The `F' (float) and `L' (long double) are automatically generated
+   from the 'double' case.  If a function supports the _Float<N> and _Float<N>X
+   types, there are additional types that are considered with 'F32', 'F64',
+   'F128', etc. suffixes.  */
 #define CASE_MATHFN(MATHFN) \
   CASE_CFN_##MATHFN: \
   fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
   fcodel = BUILT_IN_##MATHFN##L ; break;
+/* Similar to the above, but also add support for the _Float<N> and _Float<N>X
+   types.  */
+#define CASE_MATHFN_FLOATN(MATHFN) \
+  CASE_CFN_##MATHFN: \
+  fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
+  fcodel = BUILT_IN_##MATHFN##L ; fcodef16 = BUILT_IN_##MATHFN##F16 ; \
+  fcodef32 = BUILT_IN_##MATHFN##F32; fcodef64 = BUILT_IN_##MATHFN##F64 ; \
+  fcodef128 = BUILT_IN_##MATHFN##F128 ; fcodef32x = BUILT_IN_##MATHFN##F32X ; \
+  fcodef64x = BUILT_IN_##MATHFN##F64X ; fcodef128x = BUILT_IN_##MATHFN##F128X ;\
+  break;
 /* Similar to above, but appends _R after any F/L suffix.  */
 #define CASE_MATHFN_REENT(MATHFN) \
   case CFN_BUILT_IN_##MATHFN##_R: \
@@ -1840,7 +1852,15 @@ expand_builtin_classify_type (tree exp)
 static built_in_function
 mathfn_built_in_2 (tree type, combined_fn fn)
 {
+  tree mtype;
   built_in_function fcode, fcodef, fcodel;
+  built_in_function fcodef16 = END_BUILTINS;
+  built_in_function fcodef32 = END_BUILTINS;
+  built_in_function fcodef64 = END_BUILTINS;
+  built_in_function fcodef128 = END_BUILTINS;
+  built_in_function fcodef32x = END_BUILTINS;
+  built_in_function fcodef64x = END_BUILTINS;
+  built_in_function fcodef128x = END_BUILTINS;
 
   switch (fn)
     {
@@ -1854,7 +1874,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (CBRT)
     CASE_MATHFN (CEIL)
     CASE_MATHFN (CEXPI)
-    CASE_MATHFN (COPYSIGN)
+    CASE_MATHFN_FLOATN (COPYSIGN)
     CASE_MATHFN (COS)
     CASE_MATHFN (COSH)
     CASE_MATHFN (DREM)
@@ -1867,9 +1887,9 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (FABS)
     CASE_MATHFN (FDIM)
     CASE_MATHFN (FLOOR)
-    CASE_MATHFN (FMA)
-    CASE_MATHFN (FMAX)
-    CASE_MATHFN (FMIN)
+    CASE_MATHFN_FLOATN (FMA)
+    CASE_MATHFN_FLOATN (FMAX)
+    CASE_MATHFN_FLOATN (FMIN)
     CASE_MATHFN (FMOD)
     CASE_MATHFN (FREXP)
     CASE_MATHFN (GAMMA)
@@ -1923,7 +1943,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (SIN)
     CASE_MATHFN (SINCOS)
     CASE_MATHFN (SINH)
-    CASE_MATHFN (SQRT)
+    CASE_MATHFN_FLOATN (SQRT)
     CASE_MATHFN (TAN)
     CASE_MATHFN (TANH)
     CASE_MATHFN (TGAMMA)
@@ -1936,12 +1956,27 @@ mathfn_built_in_2 (tree type, combined_f
       return END_BUILTINS;
     }
 
-  if (TYPE_MAIN_VARIANT (type) == double_type_node)
+  mtype = TYPE_MAIN_VARIANT (type);
+  if (mtype == double_type_node)
     return fcode;
-  else if (TYPE_MAIN_VARIANT (type) == float_type_node)
+  else if (mtype == float_type_node)
     return fcodef;
-  else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
+  else if (mtype == long_double_type_node)
     return fcodel;
+  else if (mtype == float16_type_node)
+    return fcodef16;
+  else if (mtype == float32_type_node)
+    return fcodef32;
+  else if (mtype == float64_type_node)
+    return fcodef64;
+  else if (mtype == float128_type_node)
+    return fcodef128;
+  else if (mtype == float32x_type_node)
+    return fcodef32x;
+  else if (mtype == float64x_type_node)
+    return fcodef64x;
+  else if (mtype == float128x_type_node)
+    return fcodef128x;
   else
     return END_BUILTINS;
 }
@@ -1995,6 +2030,9 @@ associated_internal_fn (tree fndecl)
     {
 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME;
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+    CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME; \
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_##NAME): return IFN_##NAME;
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_INT_FN (BUILT_IN_##NAME): return IFN_##NAME;
 #include "internal-fn.def"
@@ -2068,6 +2106,7 @@ expand_builtin_mathfn_ternary (tree exp,
   switch (DECL_FUNCTION_CODE (fndecl))
     {
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       builtin_optab = fma_optab; break;
     default:
       gcc_unreachable ();
@@ -6567,6 +6606,7 @@ expand_builtin (tree exp, rtx target, rt
       break;
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       target = expand_builtin_mathfn_ternary (exp, target, subtarget);
       if (target)
 	return target;
@@ -8996,6 +9036,7 @@ fold_builtin_3 (location_t loc, tree fnd
       return fold_builtin_sincos (loc, arg0, arg1, arg2);
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       return fold_builtin_fma (loc, arg0, arg1, arg2, type);
 
     CASE_FLT_FN (BUILT_IN_REMQUO):
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(revision 254054)
+++ gcc/builtins.def	(working copy)
@@ -128,6 +128,21 @@ along with GCC; see the file COPYING3.
   DEF_BUILTIN_CHKP (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE,	\
 		    TYPE, true, true, true, ATTRS, false, true)
 
+/* A set of GCC builtins for _FloatN and _FloatNx types.  TYPE_MACRO is called
+   with an argument such as FLOAT32 to produce the enum value for the type.  If
+   we are being fully conformant we ignore the version of these builtins that
+   does not being with __builtin_.  */
+#undef DEF_EXT_LIB_FLOATN_NX_BUILTINS
+#define DEF_EXT_LIB_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)		\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS)\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS)\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS)\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), \
+			ATTRS)
+
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C94 or above.  */
 #undef DEF_C94_BUILTIN
@@ -324,7 +339,7 @@ DEF_C99_BUILTIN        (BUILT_IN_COPYSIG
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define COPYSIGN_TYPE(F) BT_FN_##F##_##F##_##F
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef COPYSIGN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
@@ -357,7 +372,7 @@ DEF_LIB_BUILTIN        (BUILT_IN_FABS, "
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define FABS_TYPE(F) BT_FN_##F##_##F
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef FABS_TYPE
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
@@ -382,12 +397,21 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL,
 DEF_C99_BUILTIN        (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+#define FMA_TYPE(F) BT_FN_##F##_##F##_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FMA, "fma", FMA_TYPE, ATTR_MATHFN_FPROUNDING)
+#undef FMA_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMAX_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FMAX, "fmax", FMAX_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMAX_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMIN_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FMIN, "fmin", FMIN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMIN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
@@ -495,7 +519,7 @@ DEF_C99_BUILTIN        (BUILT_IN_NAN, "n
 DEF_C99_BUILTIN        (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_C99_BUILTIN        (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 #define NAN_TYPE(F) BT_FN_##F##_CONST_STRING
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_NAN, "nan", NAN_TYPE, ATTR_CONST_NOTHROW_NONNULL)
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_NAN, "nan", NAN_TYPE, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
@@ -564,6 +588,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "
 DEF_LIB_BUILTIN        (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#define SQRT_TYPE(F) BT_FN_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_SQRT, "sqrt", SQRT_TYPE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#undef SQRT_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_LIB_BUILTIN        (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
Index: gcc/builtin-types.def
===================================================================
--- gcc/builtin-types.def	(revision 254054)
+++ gcc/builtin-types.def	(working copy)
@@ -544,6 +544,20 @@ DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE
 		     BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
 DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
 		     BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16,
+		     BT_FLOAT16, BT_FLOAT16, BT_FLOAT16, BT_FLOAT16)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32,
+		     BT_FLOAT32, BT_FLOAT32, BT_FLOAT32, BT_FLOAT32)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64,
+		     BT_FLOAT64, BT_FLOAT64, BT_FLOAT64, BT_FLOAT64)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128,
+		     BT_FLOAT128, BT_FLOAT128, BT_FLOAT128, BT_FLOAT128)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X,
+		     BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X,
+		     BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X,
+		     BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
 DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_INTPTR,
 		     BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_INT_PTR)
 DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 254054)
+++ gcc/fold-const.c	(working copy)
@@ -12761,6 +12761,7 @@ tree_call_nonnegative_warnv_p (tree type
       return true;
 
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       /* sqrt(-0.0) is -0.0.  */
       if (!HONOR_SIGNED_ZEROS (element_mode (type)))
 	return true;
@@ -12805,14 +12806,17 @@ tree_call_nonnegative_warnv_p (tree type
       return RECURSE (arg0);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       /* True if the 1st OR 2nd arguments are nonnegative.  */
       return RECURSE (arg0) || RECURSE (arg1);
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       /* True if the 1st AND 2nd arguments are nonnegative.  */
       return RECURSE (arg0) && RECURSE (arg1);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* True if the 2nd argument is nonnegative.  */
       return RECURSE (arg1);
 
@@ -13311,7 +13315,9 @@ integer_valued_real_call_p (combined_fn
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return RECURSE (arg0) && RECURSE (arg1);
 
     default:
Index: gcc/fold-const-call.c
===================================================================
--- gcc/fold-const-call.c	(revision 254054)
+++ gcc/fold-const-call.c	(working copy)
@@ -596,6 +596,7 @@ fold_const_call_ss (real_value *result,
   switch (fn)
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       return (real_compare (GE_EXPR, arg, &dconst0)
 	      && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
 
@@ -1179,14 +1180,17 @@ fold_const_call_sss (real_value *result,
       return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       *result = *arg0;
       real_copysign (result, arg1);
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
 
     CASE_CFN_POW:
@@ -1473,6 +1477,7 @@ fold_const_call_ssss (real_value *result
   switch (fn)
     {
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
 
     default:
Index: gcc/gencfn-macros.c
===================================================================
--- gcc/gencfn-macros.c	(revision 254054)
+++ gcc/gencfn-macros.c	(working copy)
@@ -98,11 +98,12 @@ is_group (string_set *builtins, const ch
 
 static void
 print_case_cfn (const char *name, bool internal_p,
-		const char *const *suffixes)
+		const char *const *suffixes, bool floatn_p)
 {
-  printf ("#define CASE_CFN_%s", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("#define CASE_CFN_%s%s", name, floatn);
   if (internal_p)
-    printf (" \\\n  case CFN_%s", name);
+    printf (" \\\n  case CFN_%s%s", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("%s \\\n  case CFN_BUILT_IN_%s%s",
 	    internal_p || i > 0 ? ":" : "", name, suffixes[i]);
@@ -115,9 +116,10 @@ print_case_cfn (const char *name, bool i
 
 static void
 print_define_operator_list (const char *name, bool internal_p,
-			    const char *const *suffixes)
+			    const char *const *suffixes, bool floatn_p)
 {
-  printf ("(define_operator_list %s\n", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("(define_operator_list %s%s\n", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("    BUILT_IN_%s%s\n", name, suffixes[i]);
   if (internal_p)
@@ -148,6 +150,8 @@ const char *const internal_fn_int_names[
 };
 
 static const char *const flt_suffixes[] = { "F", "", "L", NULL };
+static const char *const fltfn_suffixes[] = { "F16", "F32", "F128", "F32X",
+					      "F64X", "F128X", NULL };
 static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
 
 static const char *const *const suffix_lists[] = {
@@ -200,15 +204,33 @@ main (int argc, char **argv)
 	{
 	  const char *root = name + 9;
 	  for (unsigned int j = 0; suffix_lists[j]; ++j)
-	    if (is_group (&builtins, root, suffix_lists[j]))
-	      {
-		bool internal_p = internal_fns.contains (root);
-		if (type == 'c')
-		  print_case_cfn (root, internal_p, suffix_lists[j]);
-		else
-		  print_define_operator_list (root, internal_p,
-					      suffix_lists[j]);
-	      }
+	    {
+	      const char *const *const suffix = suffix_lists[j];
+
+	      if (is_group (&builtins, root, suffix))
+		{
+		  bool internal_p = internal_fns.contains (root);
+
+		  if (type == 'c')
+		    print_case_cfn (root, internal_p, suffix, false);
+		  else
+		    print_define_operator_list (root, internal_p,
+						suffix, false);
+
+		      /* Support the _Float<N> and _Float<N>X math functions if
+			 they exist.  We put these out as a separate CFN macro,
+			 so code can add support or not as needed.  */
+		  if (suffix == flt_suffixes
+		      && is_group (&builtins, root, fltfn_suffixes))
+		    {
+		      if (type == 'c')
+			print_case_cfn (root, false, fltfn_suffixes, true);
+		      else
+			print_define_operator_list (root, false, fltfn_suffixes,
+						    true);
+		    }
+		}
+	    }
 	}
     }
 
Index: gcc/gimple-ssa-backprop.c
===================================================================
--- gcc/gimple-ssa-backprop.c	(revision 254054)
+++ gcc/gimple-ssa-backprop.c	(working copy)
@@ -354,6 +354,7 @@ backprop::process_builtin_call_use (gcal
       break;
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* The sign of the first input is ignored.  */
       if (rhs != gimple_call_arg (call, 1))
 	info->flags.ignore_sign = true;
@@ -373,6 +374,7 @@ backprop::process_builtin_call_use (gcal
       }
 
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       /* In X * X + Y, where Y is distinct from X, the sign of X doesn't
 	 matter.  */
       if (gimple_call_arg (call, 0) == rhs
@@ -689,6 +691,7 @@ strip_sign_op_1 (tree rhs)
     switch (gimple_call_combined_fn (call))
       {
       CASE_CFN_COPYSIGN:
+      CASE_CFN_COPYSIGN_FN:
 	return gimple_call_arg (call, 0);
 
       default:
Index: gcc/internal-fn.def
===================================================================
--- gcc/internal-fn.def	(revision 254054)
+++ gcc/internal-fn.def	(working copy)
@@ -80,6 +80,11 @@ along with GCC; see the file COPYING3.
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
 #endif
 
+#ifndef DEF_INTERNAL_FLT_FLOATN_FN
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+  DEF_INTERNAL_FLT_FN (NAME, FLAGS, OPTAB, TYPE)
+#endif
+
 #ifndef DEF_INTERNAL_INT_FN
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
@@ -109,7 +114,7 @@ DEF_INTERNAL_FLT_FN (LOG2, ECF_CONST, lo
 DEF_INTERNAL_FLT_FN (LOGB, ECF_CONST, logb, unary)
 DEF_INTERNAL_FLT_FN (SIGNIFICAND, ECF_CONST, significand, unary)
 DEF_INTERNAL_FLT_FN (SIN, ECF_CONST, sin, unary)
-DEF_INTERNAL_FLT_FN (SQRT, ECF_CONST, sqrt, unary)
+DEF_INTERNAL_FLT_FLOATN_FN (SQRT, ECF_CONST, sqrt, unary)
 DEF_INTERNAL_FLT_FN (TAN, ECF_CONST, tan, unary)
 
 /* FP rounding.  */
@@ -122,13 +127,13 @@ DEF_INTERNAL_FLT_FN (TRUNC, ECF_CONST, b
 
 /* Binary math functions.  */
 DEF_INTERNAL_FLT_FN (ATAN2, ECF_CONST, atan2, binary)
-DEF_INTERNAL_FLT_FN (COPYSIGN, ECF_CONST, copysign, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (COPYSIGN, ECF_CONST, copysign, binary)
 DEF_INTERNAL_FLT_FN (FMOD, ECF_CONST, fmod, binary)
 DEF_INTERNAL_FLT_FN (POW, ECF_CONST, pow, binary)
 DEF_INTERNAL_FLT_FN (REMAINDER, ECF_CONST, remainder, binary)
 DEF_INTERNAL_FLT_FN (SCALB, ECF_CONST, scalb, binary)
-DEF_INTERNAL_FLT_FN (FMIN, ECF_CONST, fmin, binary)
-DEF_INTERNAL_FLT_FN (FMAX, ECF_CONST, fmax, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMIN, ECF_CONST, fmin, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMAX, ECF_CONST, fmax, binary)
 DEF_INTERNAL_OPTAB_FN (XORSIGN, ECF_CONST, xorsign, binary)
 
 /* FP scales.  */
@@ -230,5 +235,6 @@ DEF_INTERNAL_FN (DIVMOD, ECF_CONST | ECF
 
 #undef DEF_INTERNAL_INT_FN
 #undef DEF_INTERNAL_FLT_FN
+#undef DEF_INTERNAL_FLT_FLOATN_FN
 #undef DEF_INTERNAL_OPTAB_FN
 #undef DEF_INTERNAL_FN
Index: gcc/tree-call-cdce.c
===================================================================
--- gcc/tree-call-cdce.c	(revision 254054)
+++ gcc/tree-call-cdce.c	(working copy)
@@ -314,6 +314,7 @@ can_test_argument_range (gcall *call)
     CASE_FLT_FN (BUILT_IN_POW10):
     /* Sqrt.  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return check_builtin_call (call);
     /* Special one: two argument pow.  */
     case BUILT_IN_POW:
@@ -342,6 +343,7 @@ edom_only_function (gcall *call)
     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
     CASE_FLT_FN (BUILT_IN_SIN):
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
     CASE_FLT_FN (BUILT_IN_FMOD):
     CASE_FLT_FN (BUILT_IN_REMAINDER):
       return true;
@@ -703,6 +705,7 @@ get_no_error_domain (enum built_in_funct
                          308, true, false);
     /* sqrt: [0, +inf)  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return get_domain (0, true, true,
                          0, false, false);
     default:
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(revision 254054)
+++ gcc/tree-ssa-math-opts.c	(working copy)
@@ -515,6 +515,7 @@ internal_fn_reciprocal (gcall *call)
   switch (gimple_call_combined_fn (call))
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       ifn = IFN_RSQRT;
       break;
 
Index: gcc/tree-ssa-reassoc.c
===================================================================
--- gcc/tree-ssa-reassoc.c	(revision 254054)
+++ gcc/tree-ssa-reassoc.c	(working copy)
@@ -5625,6 +5625,7 @@ attempt_builtin_copysign (vec<operand_en
 	      switch (gimple_call_combined_fn (old_call))
 		{
 		CASE_CFN_COPYSIGN:
+		CASE_CFN_COPYSIGN_FN:
 		  arg0 = gimple_call_arg (old_call, 0);
 		  arg1 = gimple_call_arg (old_call, 1);
 		  /* The first argument of copysign must be a constant,
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 254054)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -2374,17 +2374,13 @@ BU_FLOAT128_1 (FABSQ,		"fabsq",       CO
 BU_FLOAT128_2 (COPYSIGNQ,	"copysignq",   CONST, copysignkf3)
 
 /* 1, 2, and 3 argument IEEE 128-bit floating point functions that require ISA
-   3.0 hardware.  These functions use the new 'f128' suffix.  Eventually the
-   standard functions should be folded into the common built-in function
-   handling. */
-BU_FLOAT128_1_HW (SQRTF128,	 "sqrtf128",		   CONST, sqrtkf2)
+   3.0 hardware.  These functions use the new 'f128' suffix.  */
 BU_FLOAT128_1_HW (SQRTF128_ODD,	 "sqrtf128_round_to_odd",  CONST, sqrtkf2_odd)
 BU_FLOAT128_1_HW (TRUNCF128_ODD, "truncf128_round_to_odd", CONST, trunckfdf2_odd)
 BU_FLOAT128_2_HW (ADDF128_ODD,	 "addf128_round_to_odd",   CONST, addkf3_odd)
 BU_FLOAT128_2_HW (SUBF128_ODD,	 "subf128_round_to_odd",   CONST, subkf3_odd)
 BU_FLOAT128_2_HW (MULF128_ODD,	 "mulf128_round_to_odd",   CONST, mulkf3_odd)
 BU_FLOAT128_2_HW (DIVF128_ODD,	 "divf128_round_to_odd",   CONST, divkf3_odd)
-BU_FLOAT128_3_HW (FMAF128,	 "fmaf128",		   CONST, fmakf4_hw)
 BU_FLOAT128_3_HW (FMAF128_ODD,	 "fmaf128_round_to_odd",   CONST, fmakf4_odd)
 \f
 /* 1 argument crypto functions.  */
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 254054)
+++ gcc/c/c-decl.c	(working copy)
@@ -3160,6 +3160,7 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_CBRT):
     CASE_FLT_FN (BUILT_IN_CEIL):
     CASE_FLT_FN (BUILT_IN_COPYSIGN):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
     CASE_FLT_FN (BUILT_IN_COS):
     CASE_FLT_FN (BUILT_IN_COSH):
     CASE_FLT_FN (BUILT_IN_ERF):
@@ -3168,11 +3169,15 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_EXP2):
     CASE_FLT_FN (BUILT_IN_EXPM1):
     CASE_FLT_FN (BUILT_IN_FABS):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
     CASE_FLT_FN (BUILT_IN_FDIM):
     CASE_FLT_FN (BUILT_IN_FLOOR):
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
     CASE_FLT_FN (BUILT_IN_FMAX):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMAX):
     CASE_FLT_FN (BUILT_IN_FMIN):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMIN):
     CASE_FLT_FN (BUILT_IN_FMOD):
     CASE_FLT_FN (BUILT_IN_FREXP):
     CASE_FLT_FN (BUILT_IN_HYPOT):
@@ -3204,6 +3209,7 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_SINH):
     CASE_FLT_FN (BUILT_IN_SINCOS):
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
     CASE_FLT_FN (BUILT_IN_TAN):
     CASE_FLT_FN (BUILT_IN_TANH):
     CASE_FLT_FN (BUILT_IN_TGAMMA):
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c	(revision 254054)
+++ gcc/c-family/c-cppbuiltin.c	(working copy)
@@ -82,6 +82,11 @@ mode_has_fma (machine_mode mode)
       return !!HAVE_fmadf4;
 #endif
 
+#ifdef HAVE_fmakf4	/* PowerPC if long double != __float128.  */
+    case E_KFmode:
+      return !!HAVE_fmakf4;
+#endif
+
 #ifdef HAVE_fmaxf4
     case E_XFmode:
       return !!HAVE_fmaxf4;
@@ -1119,7 +1124,9 @@ c_cpp_builtins (cpp_reader *pfile)
 	       floatn_nx_types[i].extended ? "X" : "");
       sprintf (csuffix, "F%d%s", floatn_nx_types[i].n,
 	       floatn_nx_types[i].extended ? "x" : "");
-      builtin_define_float_constants (prefix, csuffix, "%s", NULL,
+      const char *csuffix2 = ((flag_no_builtin || flag_no_nonansi_builtin)
+			      ? NULL : csuffix);
+      builtin_define_float_constants (prefix, csuffix, "%s", csuffix2,
 				      FLOATN_NX_TYPE_NODE (i));
     }
 
Index: gcc/testsuite/gcc.target/powerpc/float128-hw2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(working copy)
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math -std=gnu11" } */
+
+/* Test to make sure the compiler handles the standard _Float128 functions that
+   have hardware support in ISA 3.0/power9.  */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+
+#ifndef __FP_FAST_FMAF128
+#error "__FP_FAST_FMAF128 should be defined."
+#endif
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+extern _Float128 sqrtf128 (_Float128);
+extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return copysignf128 (a, b);
+}
+
+_Float128
+do_sqrt (_Float128 a)
+{
+  return sqrtf128 (a);
+}
+
+_Float128
+do_fma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, c);
+}
+
+_Float128
+do_fms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, -c);
+}
+
+_Float128
+do_nfma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, c);
+}
+
+_Float128
+do_nfms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler     {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler     {\mxssqrtqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler     {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M}        } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-hw3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw3.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw3.c	(working copy)
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math -std=c11" } */
+
+/* Test to make sure the compiler calls the external function instead of doing
+   the built-in processing for _Float128 functions that have hardware support
+   in ISA 3.0/power9 if are in strict standards mode, where the <func>f128 name
+   is not a synonym for __builtin_<func>f128.  */
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+extern _Float128 sqrtf128 (_Float128);
+extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+
+#ifdef __FP_FAST_FMAF128
+#error "__FP_FAST_FMAF128 should not be defined."
+#endif
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return copysignf128 (a, b);
+}
+
+_Float128
+do_sqrt (_Float128 a)
+{
+  return sqrtf128 (a);
+}
+
+_Float128
+do_fma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, c);
+}
+
+_Float128
+do_fms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, -c);
+}
+
+_Float128
+do_nfma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, c);
+}
+
+_Float128
+do_nfms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler-not   {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler-not   {\mxssqrtqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler-not   {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler-times {\mbl\M} 6      } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-hw.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw.c	(revision 254054)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw.c	(working copy)
@@ -2,16 +2,58 @@
 /* { dg-require-effective-target powerpc_p9vector_ok } */
 /* { dg-options "-mpower9-vector -O2" } */
 
-__float128 f128_add (__float128 a, __float128 b) { return a+b; }
-__float128 f128_sub (__float128 a, __float128 b) { return a-b; }
-__float128 f128_mul (__float128 a, __float128 b) { return a*b; }
-__float128 f128_div (__float128 a, __float128 b) { return a/b; }
-__float128 f128_fma (__float128 a, __float128 b, __float128 c) { return (a*b)+c; }
-long f128_cmove (__float128 a, __float128 b, long c, long d) { return (a == b) ? c : d; }
-
-/* { dg-final { scan-assembler "xsaddqp"  } } */
-/* { dg-final { scan-assembler "xssubqp"  } } */
-/* { dg-final { scan-assembler "xsmulqp"  } } */
-/* { dg-final { scan-assembler "xsdivqp"  } } */
-/* { dg-final { scan-assembler "xsmaddqp" } } */
-/* { dg-final { scan-assembler "xscmpuqp" } } */
+#ifndef TYPE
+#define TYPE _Float128
+#endif
+
+/* Test the code generation of the various _Float128 operations.  */
+TYPE f128_add (TYPE a, TYPE b) { return a+b; }
+TYPE f128_sub (TYPE a, TYPE b) { return a-b; }
+TYPE f128_mul (TYPE a, TYPE b) { return a*b; }
+TYPE f128_div (TYPE a, TYPE b) { return a/b; }
+TYPE f128_fma (TYPE a, TYPE b, TYPE c) { return (a*b)+c; }
+TYPE f128_fms (TYPE a, TYPE b, TYPE c) { return (a*b)-c; }
+TYPE f128_nfma (TYPE a, TYPE b, TYPE c) { return -((a*b)+c); }
+TYPE f128_nfms (TYPE a, TYPE b, TYPE c) { return -((a*b)-c); }
+TYPE f128_neg (TYPE a) { return -a; }
+
+long f128_cmove (TYPE a, TYPE b, long c, long d) { return (a == b) ? c : d; }
+
+double f128_to_double (TYPE a) { return (double)a; }
+float f128_to_float (TYPE a) { return (float)a; }
+long f128_to_long (TYPE a) { return (long)a; }
+unsigned long f128_to_ulong (TYPE a) { return (unsigned long)a; }
+int f128_to_int (TYPE a) { return (int)a; }
+unsigned int f128_to_uint (TYPE a) { return (unsigned int)a; }
+
+TYPE double_to_f128 (double a) { return (TYPE)a; }
+TYPE float_to_f128 (float a) { return (TYPE)a; }
+TYPE long_to_f128 (long a) { return (TYPE)a; }
+TYPE ulong_to_f128 (unsigned long a) { return (TYPE)a; }
+TYPE int_to_f128 (int a) { return (TYPE)a; }
+TYPE uint_to_f128 (unsigned int a) { return (TYPE)a; }
+
+/* { dg-final { scan-assembler     {\mmfvsrd\M}    } } */
+/* { dg-final { scan-assembler     {\mmfvsrwz\M}   } } */
+/* { dg-final { scan-assembler     {\mmtvsrd\M}    } } */
+/* { dg-final { scan-assembler     {\mmtvsrwa\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxscmpuqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvdpqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpdp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpdpo\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpsdz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpswz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpudz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpuwz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvsdqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvudqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxsdivqp\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxsmulqp\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxsnegqp\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler 	   {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler 	   {\mxssubqp\M}   } } */
+/* { dg-final { scan-assembler-not {\mbl\M}        } } */
+

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 4], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-25 19:25           ` [PATCH, version 4], " Michael Meissner
@ 2017-10-25 20:01             ` Michael Meissner
  2017-10-25 20:11             ` Joseph Myers
  1 sibling, 0 replies; 31+ messages in thread
From: Michael Meissner @ 2017-10-25 20:01 UTC (permalink / raw)
  To: Michael Meissner, Joseph Myers, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

Whoops, I missed deleting c.opt from the ChangeLog file.  I did update the
builtins.def text, and c-cppbuiltins.c, but I didn't delete c.opt.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 4], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-25 19:25           ` [PATCH, version 4], " Michael Meissner
  2017-10-25 20:01             ` Michael Meissner
@ 2017-10-25 20:11             ` Joseph Myers
  2017-10-25 20:31               ` Michael Meissner
  1 sibling, 1 reply; 31+ messages in thread
From: Joseph Myers @ 2017-10-25 20:11 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Wed, 25 Oct 2017, Michael Meissner wrote:

> +static const char *const fltfn_suffixes[] = { "F16", "F32", "F128", "F32X",
> +                                             "F64X", "F128X", NULL };

I'd expect this to include F64.  If there's some reason that's 
inappropriate and the omission is deliberate, it needs a detailed comment 
explaining the omission.

I don't think that, given the availability of fmaf128 etc. built-in 
functions with appropriate options, whether __FP_FAST_* are defined should 
actually depend on whether the user has passed options to disable those 
functions (after all, it doesn't for the existing fma / fmaf / fmal, and 
individual built-in functions can be disabled with -fno-builtin-<function> 
so the logic you have wouldn't work to detect whether the built-in 
function is disabled anyway).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 4], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-25 20:11             ` Joseph Myers
@ 2017-10-25 20:31               ` Michael Meissner
  2017-10-25 20:50                 ` Joseph Myers
  0 siblings, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-25 20:31 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

On Wed, Oct 25, 2017 at 08:10:45PM +0000, Joseph Myers wrote:
> On Wed, 25 Oct 2017, Michael Meissner wrote:
> 
> > +static const char *const fltfn_suffixes[] = { "F16", "F32", "F128", "F32X",
> > +                                             "F64X", "F128X", NULL };
> 
> I'd expect this to include F64.  If there's some reason that's 
> inappropriate and the omission is deliberate, it needs a detailed comment 
> explaining the omission.

Thanks for catching this.  I missed F64.

> I don't think that, given the availability of fmaf128 etc. built-in 
> functions with appropriate options, whether __FP_FAST_* are defined should 
> actually depend on whether the user has passed options to disable those 
> functions (after all, it doesn't for the existing fma / fmaf / fmal, and 
> individual built-in functions can be disabled with -fno-builtin-<function> 
> so the logic you have wouldn't work to detect whether the built-in 
> function is disabled anyway).

Ok, I will add a check to see if the functions are disabled.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 4], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-25 20:31               ` Michael Meissner
@ 2017-10-25 20:50                 ` Joseph Myers
  2017-10-25 23:37                   ` [PATCH, version 5], " Michael Meissner
  0 siblings, 1 reply; 31+ messages in thread
From: Joseph Myers @ 2017-10-25 20:50 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Wed, 25 Oct 2017, Michael Meissner wrote:

> > I don't think that, given the availability of fmaf128 etc. built-in 
> > functions with appropriate options, whether __FP_FAST_* are defined should 
> > actually depend on whether the user has passed options to disable those 
> > functions (after all, it doesn't for the existing fma / fmaf / fmal, and 
> > individual built-in functions can be disabled with -fno-builtin-<function> 
> > so the logic you have wouldn't work to detect whether the built-in 
> > function is disabled anyway).
> 
> Ok, I will add a check to see if the functions are disabled.

My suggestion is to *remove* the checks in this patch for built-in 
functions being enabled.  That is, to have logic for __FP_FAST_* for these 
functions exactly the same as for __FP_FAST_FMA, which still gets defined 
with -std=c90 even though that disables fma as a built-in function while 
leaving __builtin_fma.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-25 20:50                 ` Joseph Myers
@ 2017-10-25 23:37                   ` Michael Meissner
  2017-10-25 23:56                     ` Joseph Myers
  0 siblings, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-25 23:37 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 5876 bytes --]

On Wed, Oct 25, 2017 at 08:31:33PM +0000, Joseph Myers wrote:
> On Wed, 25 Oct 2017, Michael Meissner wrote:
> 
> > > I don't think that, given the availability of fmaf128 etc. built-in 
> > > functions with appropriate options, whether __FP_FAST_* are defined should 
> > > actually depend on whether the user has passed options to disable those 
> > > functions (after all, it doesn't for the existing fma / fmaf / fmal, and 
> > > individual built-in functions can be disabled with -fno-builtin-<function> 
> > > so the logic you have wouldn't work to detect whether the built-in 
> > > function is disabled anyway).
> > 
> > Ok, I will add a check to see if the functions are disabled.
> 
> My suggestion is to *remove* the checks in this patch for built-in 
> functions being enabled.  That is, to have logic for __FP_FAST_* for these 
> functions exactly the same as for __FP_FAST_FMA, which still gets defined 
> with -std=c90 even though that disables fma as a built-in function while 
> leaving __builtin_fma.

Here is version 5 of the patch.  I added the missing "F64" to gencfn-macros.c.
I made defining __FP_FAST_FMA<N> __FP_FAST_FMA<N>X not dependent on whether the
built-in functions are enabled.  I adjusted the test float128-hw3.c to remove
the check that __FP_FAST_FMAF128 not being defined.

I have done bootstrap builds on a little endian power8 system and a x86-64
system.  There were no regressions.  Can I check this into the trunk?

[gcc]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* builtins.c (CASE_MATHFN_FLOATN): New helper macro to add cases
	for math functions that have _Float<N> and _Float<N>X variants.
	(mathfn_built_in_2): Add support for math functions that have
	_Float<N> and _Float<N>X variants.
	(DEF_INTERNAL_FLT_FLOATN_FN): New helper macro.
	(expand_builtin_mathfn_ternary): Add support for fma with
	_Float<N> and _Float<N>X variants.
	(expand_builtin): Likewise.
	(fold_builtin_3): Likewise.
	* builtins.def (DEF_EXT_LIB_FLOATN_NX_BUILTINS): New macro to
	create math function _Float<N> and _Float<N>X variants as external
	library builtins.
	(BUILT_IN_COPYSIGN _Float<N> and _Float<N>X variants) Use
	DEF_EXT_LIB_FLOATN_NX_BUILTINS to make built-in functions using
	the __builtin_ prefix and if not strict ansi, without the prefix.
	(BUILT_IN_FABS _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMA _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMAX _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_FMIN _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_NAN _Float<N> and _Float<N>X variants): Likewise.
	(BUILT_IN_SQRT _Float<N> and _Float<N>X variants): Likewise.
	* builtin-types.def (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16): New
	function signatures for fma _Float<N> and _Float<N>X variants.
	(BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32): Likewise.
	(BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64): Likewise.
	(BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128): Likewise.
	(BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X): Likewise.
	(BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X): Likewise.
	(BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X): Likewise.
	* gencfn-macros.c (print_case_cfn): Add support for math functions
	that have _Float<N> and _Float<N>X variants.
	(print_define_operator_list): Likewise.
	(fltfn_suffixes): Likewise.
	(main): Likewise.
	* internal-fn.def (DEF_INTERNAL_FLT_FLOATN_FN): New helper macro
	for math functions that have _Float<N> and _Float<N>X variants.
	(SQRT): Add support for sqrt, copysign, fmin and fmax _Float<N>
	and _Float<N>X variants.
	(COPYSIGN): Likewise.
	(FMIN): Likewise.
	(FMAX): Likewise.
	* fold-const.c (tree_call_nonnegative_warnv_p): Add support for
	copysign, fma, fmax, fmin, and sqrt _Float<N> and _Float<N>X
	variants.
	(integer_valued_read_call_p): Likewise.
	* fold-const-call.c (fold_const_call_ss): Likewise.
	(fold_const_call_sss): Add support for copysign, fmin, and fmax
	_Float<N> and _Float<N>X variants.
	(fold_const_call_ssss): Add support for fma _Float<N> and
	_Float<N>X variants.
	* gimple-ssa-backprop.c (backprop::process_builtin_call_use): Add
	support for copysign and fma _Float<N> and _Float<N>X variants.
	(backprop::process_builtin_call_use): Likewise.
	* tree-call-cdce.c (can_test_argument_range); Add support for
	sqrt _Float<N> and _Float<N>X variants.
	(edom_only_function): Likewise.
	(get_no_error_domain): Likewise.
	* tree-ssa-math-opts.c (internal_fn_reciprocal): Likewise.
	* tree-ssa-reassoc.c (attempt_builtin_copysign): Add support for
	copysign _Float<N> and _Float<N>X variants.
	* config/rs6000/rs6000-builtin.def (SQRTF128): Delete, this is now
	handled by machine independent code.
	(FMAF128): Likewise.

[gcc/c]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-decl.c (header_for_builtin_fn): Add support for copysign, fma,
	fmax, fmin, and sqrt _Float<N> and _Float<N>X variants.

[gcc/c-family]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-cppbuiltin.c (mode_has_fma): Add support for PowerPC KFmode.
	(c_cpp_builtins): If a machine has a fast fma _Float<N> and
	_Float<N>X variant, define __FP_FAST_FMA<N> and/or
	__FP_FAST_FMA<N>X.

[gcc/testsuite]
2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/float128-hw.c: Add support for all 4 FMA
	variants.  Check various conversions to/from float128.  Check
	negation.  Use {\m...\M} in the tests.
	* gcc.target/powerpc/float128-hw2.c: New test for implicit
	_Float128 math functions.
	* gcc.target/powerpc/float128-hw3.c: New test for strict ansi mode
	not implicitly adding the _Float128 math functions.
	* gcc.target/powerpc/float128-fma2.c: Delete, test is no longer
	valid.
	* gcc.target/powerpc/float128-sqrt2.c: Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch47b --]
[-- Type: text/plain, Size: 36027 bytes --]

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 254054)
+++ gcc/builtins.c	(working copy)
@@ -1816,14 +1816,26 @@ expand_builtin_classify_type (tree exp)
   return GEN_INT (no_type_class);
 }
 
-/* This helper macro, meant to be used in mathfn_built_in below,
-   determines which among a set of three builtin math functions is
-   appropriate for a given type mode.  The `F' and `L' cases are
-   automatically generated from the `double' case.  */
+/* This helper macro, meant to be used in mathfn_built_in below, determines
+   which among a set of builtin math functions is appropriate for a given type
+   mode.  The `F' (float) and `L' (long double) are automatically generated
+   from the 'double' case.  If a function supports the _Float<N> and _Float<N>X
+   types, there are additional types that are considered with 'F32', 'F64',
+   'F128', etc. suffixes.  */
 #define CASE_MATHFN(MATHFN) \
   CASE_CFN_##MATHFN: \
   fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
   fcodel = BUILT_IN_##MATHFN##L ; break;
+/* Similar to the above, but also add support for the _Float<N> and _Float<N>X
+   types.  */
+#define CASE_MATHFN_FLOATN(MATHFN) \
+  CASE_CFN_##MATHFN: \
+  fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
+  fcodel = BUILT_IN_##MATHFN##L ; fcodef16 = BUILT_IN_##MATHFN##F16 ; \
+  fcodef32 = BUILT_IN_##MATHFN##F32; fcodef64 = BUILT_IN_##MATHFN##F64 ; \
+  fcodef128 = BUILT_IN_##MATHFN##F128 ; fcodef32x = BUILT_IN_##MATHFN##F32X ; \
+  fcodef64x = BUILT_IN_##MATHFN##F64X ; fcodef128x = BUILT_IN_##MATHFN##F128X ;\
+  break;
 /* Similar to above, but appends _R after any F/L suffix.  */
 #define CASE_MATHFN_REENT(MATHFN) \
   case CFN_BUILT_IN_##MATHFN##_R: \
@@ -1840,7 +1852,15 @@ expand_builtin_classify_type (tree exp)
 static built_in_function
 mathfn_built_in_2 (tree type, combined_fn fn)
 {
+  tree mtype;
   built_in_function fcode, fcodef, fcodel;
+  built_in_function fcodef16 = END_BUILTINS;
+  built_in_function fcodef32 = END_BUILTINS;
+  built_in_function fcodef64 = END_BUILTINS;
+  built_in_function fcodef128 = END_BUILTINS;
+  built_in_function fcodef32x = END_BUILTINS;
+  built_in_function fcodef64x = END_BUILTINS;
+  built_in_function fcodef128x = END_BUILTINS;
 
   switch (fn)
     {
@@ -1854,7 +1874,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (CBRT)
     CASE_MATHFN (CEIL)
     CASE_MATHFN (CEXPI)
-    CASE_MATHFN (COPYSIGN)
+    CASE_MATHFN_FLOATN (COPYSIGN)
     CASE_MATHFN (COS)
     CASE_MATHFN (COSH)
     CASE_MATHFN (DREM)
@@ -1867,9 +1887,9 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (FABS)
     CASE_MATHFN (FDIM)
     CASE_MATHFN (FLOOR)
-    CASE_MATHFN (FMA)
-    CASE_MATHFN (FMAX)
-    CASE_MATHFN (FMIN)
+    CASE_MATHFN_FLOATN (FMA)
+    CASE_MATHFN_FLOATN (FMAX)
+    CASE_MATHFN_FLOATN (FMIN)
     CASE_MATHFN (FMOD)
     CASE_MATHFN (FREXP)
     CASE_MATHFN (GAMMA)
@@ -1923,7 +1943,7 @@ mathfn_built_in_2 (tree type, combined_f
     CASE_MATHFN (SIN)
     CASE_MATHFN (SINCOS)
     CASE_MATHFN (SINH)
-    CASE_MATHFN (SQRT)
+    CASE_MATHFN_FLOATN (SQRT)
     CASE_MATHFN (TAN)
     CASE_MATHFN (TANH)
     CASE_MATHFN (TGAMMA)
@@ -1936,12 +1956,27 @@ mathfn_built_in_2 (tree type, combined_f
       return END_BUILTINS;
     }
 
-  if (TYPE_MAIN_VARIANT (type) == double_type_node)
+  mtype = TYPE_MAIN_VARIANT (type);
+  if (mtype == double_type_node)
     return fcode;
-  else if (TYPE_MAIN_VARIANT (type) == float_type_node)
+  else if (mtype == float_type_node)
     return fcodef;
-  else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
+  else if (mtype == long_double_type_node)
     return fcodel;
+  else if (mtype == float16_type_node)
+    return fcodef16;
+  else if (mtype == float32_type_node)
+    return fcodef32;
+  else if (mtype == float64_type_node)
+    return fcodef64;
+  else if (mtype == float128_type_node)
+    return fcodef128;
+  else if (mtype == float32x_type_node)
+    return fcodef32x;
+  else if (mtype == float64x_type_node)
+    return fcodef64x;
+  else if (mtype == float128x_type_node)
+    return fcodef128x;
   else
     return END_BUILTINS;
 }
@@ -1995,6 +2030,9 @@ associated_internal_fn (tree fndecl)
     {
 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME;
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+    CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME; \
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_##NAME): return IFN_##NAME;
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
     CASE_INT_FN (BUILT_IN_##NAME): return IFN_##NAME;
 #include "internal-fn.def"
@@ -2068,6 +2106,7 @@ expand_builtin_mathfn_ternary (tree exp,
   switch (DECL_FUNCTION_CODE (fndecl))
     {
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       builtin_optab = fma_optab; break;
     default:
       gcc_unreachable ();
@@ -6567,6 +6606,7 @@ expand_builtin (tree exp, rtx target, rt
       break;
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       target = expand_builtin_mathfn_ternary (exp, target, subtarget);
       if (target)
 	return target;
@@ -8996,6 +9036,7 @@ fold_builtin_3 (location_t loc, tree fnd
       return fold_builtin_sincos (loc, arg0, arg1, arg2);
 
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
       return fold_builtin_fma (loc, arg0, arg1, arg2, type);
 
     CASE_FLT_FN (BUILT_IN_REMQUO):
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(revision 254054)
+++ gcc/builtins.def	(working copy)
@@ -128,6 +128,21 @@ along with GCC; see the file COPYING3.
   DEF_BUILTIN_CHKP (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE,	\
 		    TYPE, true, true, true, ATTRS, false, true)
 
+/* A set of GCC builtins for _FloatN and _FloatNx types.  TYPE_MACRO is called
+   with an argument such as FLOAT32 to produce the enum value for the type.  If
+   we are being fully conformant we ignore the version of these builtins that
+   does not being with __builtin_.  */
+#undef DEF_EXT_LIB_FLOATN_NX_BUILTINS
+#define DEF_EXT_LIB_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)		\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
+  DEF_EXT_LIB_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS)\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS)\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS)\
+  DEF_EXT_LIB_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), \
+			ATTRS)
+
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C94 or above.  */
 #undef DEF_C94_BUILTIN
@@ -324,7 +339,7 @@ DEF_C99_BUILTIN        (BUILT_IN_COPYSIG
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define COPYSIGN_TYPE(F) BT_FN_##F##_##F##_##F
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef COPYSIGN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
@@ -357,7 +372,7 @@ DEF_LIB_BUILTIN        (BUILT_IN_FABS, "
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define FABS_TYPE(F) BT_FN_##F##_##F
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef FABS_TYPE
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
@@ -382,12 +397,21 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL,
 DEF_C99_BUILTIN        (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+#define FMA_TYPE(F) BT_FN_##F##_##F##_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FMA, "fma", FMA_TYPE, ATTR_MATHFN_FPROUNDING)
+#undef FMA_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMAX_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FMAX, "fmax", FMAX_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMAX_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FMIN_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FMIN, "fmin", FMIN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FMIN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
@@ -495,7 +519,7 @@ DEF_C99_BUILTIN        (BUILT_IN_NAN, "n
 DEF_C99_BUILTIN        (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_C99_BUILTIN        (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 #define NAN_TYPE(F) BT_FN_##F##_CONST_STRING
-DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_NAN, "nan", NAN_TYPE, ATTR_CONST_NOTHROW_NONNULL)
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_NAN, "nan", NAN_TYPE, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
@@ -564,6 +588,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "
 DEF_LIB_BUILTIN        (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#define SQRT_TYPE(F) BT_FN_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_SQRT, "sqrt", SQRT_TYPE, ATTR_MATHFN_FPROUNDING_ERRNO)
+#undef SQRT_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_LIB_BUILTIN        (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
Index: gcc/builtin-types.def
===================================================================
--- gcc/builtin-types.def	(revision 254054)
+++ gcc/builtin-types.def	(working copy)
@@ -544,6 +544,20 @@ DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE
 		     BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
 DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
 		     BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT16_FLOAT16_FLOAT16_FLOAT16,
+		     BT_FLOAT16, BT_FLOAT16, BT_FLOAT16, BT_FLOAT16)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32_FLOAT32_FLOAT32_FLOAT32,
+		     BT_FLOAT32, BT_FLOAT32, BT_FLOAT32, BT_FLOAT32)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64_FLOAT64_FLOAT64_FLOAT64,
+		     BT_FLOAT64, BT_FLOAT64, BT_FLOAT64, BT_FLOAT64)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128_FLOAT128_FLOAT128_FLOAT128,
+		     BT_FLOAT128, BT_FLOAT128, BT_FLOAT128, BT_FLOAT128)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT32X_FLOAT32X_FLOAT32X_FLOAT32X,
+		     BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT64X_FLOAT64X_FLOAT64X_FLOAT64X,
+		     BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT128X_FLOAT128X_FLOAT128X_FLOAT128X,
+		     BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
 DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_INTPTR,
 		     BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_INT_PTR)
 DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
Index: gcc/gencfn-macros.c
===================================================================
--- gcc/gencfn-macros.c	(revision 254054)
+++ gcc/gencfn-macros.c	(working copy)
@@ -98,11 +98,12 @@ is_group (string_set *builtins, const ch
 
 static void
 print_case_cfn (const char *name, bool internal_p,
-		const char *const *suffixes)
+		const char *const *suffixes, bool floatn_p)
 {
-  printf ("#define CASE_CFN_%s", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("#define CASE_CFN_%s%s", name, floatn);
   if (internal_p)
-    printf (" \\\n  case CFN_%s", name);
+    printf (" \\\n  case CFN_%s%s", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("%s \\\n  case CFN_BUILT_IN_%s%s",
 	    internal_p || i > 0 ? ":" : "", name, suffixes[i]);
@@ -115,9 +116,10 @@ print_case_cfn (const char *name, bool i
 
 static void
 print_define_operator_list (const char *name, bool internal_p,
-			    const char *const *suffixes)
+			    const char *const *suffixes, bool floatn_p)
 {
-  printf ("(define_operator_list %s\n", name);
+  const char *floatn = (floatn_p) ? "_FN" : "";
+  printf ("(define_operator_list %s%s\n", name, floatn);
   for (unsigned int i = 0; suffixes[i]; ++i)
     printf ("    BUILT_IN_%s%s\n", name, suffixes[i]);
   if (internal_p)
@@ -148,6 +150,8 @@ const char *const internal_fn_int_names[
 };
 
 static const char *const flt_suffixes[] = { "F", "", "L", NULL };
+static const char *const fltfn_suffixes[] = { "F16", "F32", "F64", "F128",
+					      "F32X", "F64X", "F128X", NULL };
 static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
 
 static const char *const *const suffix_lists[] = {
@@ -200,15 +204,33 @@ main (int argc, char **argv)
 	{
 	  const char *root = name + 9;
 	  for (unsigned int j = 0; suffix_lists[j]; ++j)
-	    if (is_group (&builtins, root, suffix_lists[j]))
-	      {
-		bool internal_p = internal_fns.contains (root);
-		if (type == 'c')
-		  print_case_cfn (root, internal_p, suffix_lists[j]);
-		else
-		  print_define_operator_list (root, internal_p,
-					      suffix_lists[j]);
-	      }
+	    {
+	      const char *const *const suffix = suffix_lists[j];
+
+	      if (is_group (&builtins, root, suffix))
+		{
+		  bool internal_p = internal_fns.contains (root);
+
+		  if (type == 'c')
+		    print_case_cfn (root, internal_p, suffix, false);
+		  else
+		    print_define_operator_list (root, internal_p,
+						suffix, false);
+
+		      /* Support the _Float<N> and _Float<N>X math functions if
+			 they exist.  We put these out as a separate CFN macro,
+			 so code can add support or not as needed.  */
+		  if (suffix == flt_suffixes
+		      && is_group (&builtins, root, fltfn_suffixes))
+		    {
+		      if (type == 'c')
+			print_case_cfn (root, false, fltfn_suffixes, true);
+		      else
+			print_define_operator_list (root, false, fltfn_suffixes,
+						    true);
+		    }
+		}
+	    }
 	}
     }
 
Index: gcc/internal-fn.def
===================================================================
--- gcc/internal-fn.def	(revision 254054)
+++ gcc/internal-fn.def	(working copy)
@@ -80,6 +80,11 @@ along with GCC; see the file COPYING3.
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
 #endif
 
+#ifndef DEF_INTERNAL_FLT_FLOATN_FN
+#define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \
+  DEF_INTERNAL_FLT_FN (NAME, FLAGS, OPTAB, TYPE)
+#endif
+
 #ifndef DEF_INTERNAL_INT_FN
 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
@@ -109,7 +114,7 @@ DEF_INTERNAL_FLT_FN (LOG2, ECF_CONST, lo
 DEF_INTERNAL_FLT_FN (LOGB, ECF_CONST, logb, unary)
 DEF_INTERNAL_FLT_FN (SIGNIFICAND, ECF_CONST, significand, unary)
 DEF_INTERNAL_FLT_FN (SIN, ECF_CONST, sin, unary)
-DEF_INTERNAL_FLT_FN (SQRT, ECF_CONST, sqrt, unary)
+DEF_INTERNAL_FLT_FLOATN_FN (SQRT, ECF_CONST, sqrt, unary)
 DEF_INTERNAL_FLT_FN (TAN, ECF_CONST, tan, unary)
 
 /* FP rounding.  */
@@ -122,13 +127,13 @@ DEF_INTERNAL_FLT_FN (TRUNC, ECF_CONST, b
 
 /* Binary math functions.  */
 DEF_INTERNAL_FLT_FN (ATAN2, ECF_CONST, atan2, binary)
-DEF_INTERNAL_FLT_FN (COPYSIGN, ECF_CONST, copysign, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (COPYSIGN, ECF_CONST, copysign, binary)
 DEF_INTERNAL_FLT_FN (FMOD, ECF_CONST, fmod, binary)
 DEF_INTERNAL_FLT_FN (POW, ECF_CONST, pow, binary)
 DEF_INTERNAL_FLT_FN (REMAINDER, ECF_CONST, remainder, binary)
 DEF_INTERNAL_FLT_FN (SCALB, ECF_CONST, scalb, binary)
-DEF_INTERNAL_FLT_FN (FMIN, ECF_CONST, fmin, binary)
-DEF_INTERNAL_FLT_FN (FMAX, ECF_CONST, fmax, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMIN, ECF_CONST, fmin, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (FMAX, ECF_CONST, fmax, binary)
 DEF_INTERNAL_OPTAB_FN (XORSIGN, ECF_CONST, xorsign, binary)
 
 /* FP scales.  */
@@ -230,5 +235,6 @@ DEF_INTERNAL_FN (DIVMOD, ECF_CONST | ECF
 
 #undef DEF_INTERNAL_INT_FN
 #undef DEF_INTERNAL_FLT_FN
+#undef DEF_INTERNAL_FLT_FLOATN_FN
 #undef DEF_INTERNAL_OPTAB_FN
 #undef DEF_INTERNAL_FN
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 254054)
+++ gcc/fold-const.c	(working copy)
@@ -12761,6 +12761,7 @@ tree_call_nonnegative_warnv_p (tree type
       return true;
 
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       /* sqrt(-0.0) is -0.0.  */
       if (!HONOR_SIGNED_ZEROS (element_mode (type)))
 	return true;
@@ -12805,14 +12806,17 @@ tree_call_nonnegative_warnv_p (tree type
       return RECURSE (arg0);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       /* True if the 1st OR 2nd arguments are nonnegative.  */
       return RECURSE (arg0) || RECURSE (arg1);
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       /* True if the 1st AND 2nd arguments are nonnegative.  */
       return RECURSE (arg0) && RECURSE (arg1);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* True if the 2nd argument is nonnegative.  */
       return RECURSE (arg1);
 
@@ -13311,7 +13315,9 @@ integer_valued_real_call_p (combined_fn
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return RECURSE (arg0) && RECURSE (arg1);
 
     default:
Index: gcc/fold-const-call.c
===================================================================
--- gcc/fold-const-call.c	(revision 254054)
+++ gcc/fold-const-call.c	(working copy)
@@ -596,6 +596,7 @@ fold_const_call_ss (real_value *result,
   switch (fn)
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       return (real_compare (GE_EXPR, arg, &dconst0)
 	      && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
 
@@ -1179,14 +1180,17 @@ fold_const_call_sss (real_value *result,
       return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       *result = *arg0;
       real_copysign (result, arg1);
       return true;
 
     CASE_CFN_FMIN:
+    CASE_CFN_FMIN_FN:
       return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
 
     CASE_CFN_FMAX:
+    CASE_CFN_FMAX_FN:
       return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
 
     CASE_CFN_POW:
@@ -1473,6 +1477,7 @@ fold_const_call_ssss (real_value *result
   switch (fn)
     {
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
 
     default:
Index: gcc/gimple-ssa-backprop.c
===================================================================
--- gcc/gimple-ssa-backprop.c	(revision 254054)
+++ gcc/gimple-ssa-backprop.c	(working copy)
@@ -354,6 +354,7 @@ backprop::process_builtin_call_use (gcal
       break;
 
     CASE_CFN_COPYSIGN:
+    CASE_CFN_COPYSIGN_FN:
       /* The sign of the first input is ignored.  */
       if (rhs != gimple_call_arg (call, 1))
 	info->flags.ignore_sign = true;
@@ -373,6 +374,7 @@ backprop::process_builtin_call_use (gcal
       }
 
     CASE_CFN_FMA:
+    CASE_CFN_FMA_FN:
       /* In X * X + Y, where Y is distinct from X, the sign of X doesn't
 	 matter.  */
       if (gimple_call_arg (call, 0) == rhs
@@ -689,6 +691,7 @@ strip_sign_op_1 (tree rhs)
     switch (gimple_call_combined_fn (call))
       {
       CASE_CFN_COPYSIGN:
+      CASE_CFN_COPYSIGN_FN:
 	return gimple_call_arg (call, 0);
 
       default:
Index: gcc/tree-call-cdce.c
===================================================================
--- gcc/tree-call-cdce.c	(revision 254054)
+++ gcc/tree-call-cdce.c	(working copy)
@@ -314,6 +314,7 @@ can_test_argument_range (gcall *call)
     CASE_FLT_FN (BUILT_IN_POW10):
     /* Sqrt.  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return check_builtin_call (call);
     /* Special one: two argument pow.  */
     case BUILT_IN_POW:
@@ -342,6 +343,7 @@ edom_only_function (gcall *call)
     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
     CASE_FLT_FN (BUILT_IN_SIN):
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
     CASE_FLT_FN (BUILT_IN_FMOD):
     CASE_FLT_FN (BUILT_IN_REMAINDER):
       return true;
@@ -703,6 +705,7 @@ get_no_error_domain (enum built_in_funct
                          308, true, false);
     /* sqrt: [0, +inf)  */
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
       return get_domain (0, true, true,
                          0, false, false);
     default:
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(revision 254054)
+++ gcc/tree-ssa-math-opts.c	(working copy)
@@ -515,6 +515,7 @@ internal_fn_reciprocal (gcall *call)
   switch (gimple_call_combined_fn (call))
     {
     CASE_CFN_SQRT:
+    CASE_CFN_SQRT_FN:
       ifn = IFN_RSQRT;
       break;
 
Index: gcc/tree-ssa-reassoc.c
===================================================================
--- gcc/tree-ssa-reassoc.c	(revision 254054)
+++ gcc/tree-ssa-reassoc.c	(working copy)
@@ -5625,6 +5625,7 @@ attempt_builtin_copysign (vec<operand_en
 	      switch (gimple_call_combined_fn (old_call))
 		{
 		CASE_CFN_COPYSIGN:
+		CASE_CFN_COPYSIGN_FN:
 		  arg0 = gimple_call_arg (old_call, 0);
 		  arg1 = gimple_call_arg (old_call, 1);
 		  /* The first argument of copysign must be a constant,
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 254054)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -2374,17 +2374,13 @@ BU_FLOAT128_1 (FABSQ,		"fabsq",       CO
 BU_FLOAT128_2 (COPYSIGNQ,	"copysignq",   CONST, copysignkf3)
 
 /* 1, 2, and 3 argument IEEE 128-bit floating point functions that require ISA
-   3.0 hardware.  These functions use the new 'f128' suffix.  Eventually the
-   standard functions should be folded into the common built-in function
-   handling. */
-BU_FLOAT128_1_HW (SQRTF128,	 "sqrtf128",		   CONST, sqrtkf2)
+   3.0 hardware.  These functions use the new 'f128' suffix.  */
 BU_FLOAT128_1_HW (SQRTF128_ODD,	 "sqrtf128_round_to_odd",  CONST, sqrtkf2_odd)
 BU_FLOAT128_1_HW (TRUNCF128_ODD, "truncf128_round_to_odd", CONST, trunckfdf2_odd)
 BU_FLOAT128_2_HW (ADDF128_ODD,	 "addf128_round_to_odd",   CONST, addkf3_odd)
 BU_FLOAT128_2_HW (SUBF128_ODD,	 "subf128_round_to_odd",   CONST, subkf3_odd)
 BU_FLOAT128_2_HW (MULF128_ODD,	 "mulf128_round_to_odd",   CONST, mulkf3_odd)
 BU_FLOAT128_2_HW (DIVF128_ODD,	 "divf128_round_to_odd",   CONST, divkf3_odd)
-BU_FLOAT128_3_HW (FMAF128,	 "fmaf128",		   CONST, fmakf4_hw)
 BU_FLOAT128_3_HW (FMAF128_ODD,	 "fmaf128_round_to_odd",   CONST, fmakf4_odd)
 \f
 /* 1 argument crypto functions.  */
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 254054)
+++ gcc/c/c-decl.c	(working copy)
@@ -3160,6 +3160,7 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_CBRT):
     CASE_FLT_FN (BUILT_IN_CEIL):
     CASE_FLT_FN (BUILT_IN_COPYSIGN):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
     CASE_FLT_FN (BUILT_IN_COS):
     CASE_FLT_FN (BUILT_IN_COSH):
     CASE_FLT_FN (BUILT_IN_ERF):
@@ -3168,11 +3169,15 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_EXP2):
     CASE_FLT_FN (BUILT_IN_EXPM1):
     CASE_FLT_FN (BUILT_IN_FABS):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
     CASE_FLT_FN (BUILT_IN_FDIM):
     CASE_FLT_FN (BUILT_IN_FLOOR):
     CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
     CASE_FLT_FN (BUILT_IN_FMAX):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMAX):
     CASE_FLT_FN (BUILT_IN_FMIN):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMIN):
     CASE_FLT_FN (BUILT_IN_FMOD):
     CASE_FLT_FN (BUILT_IN_FREXP):
     CASE_FLT_FN (BUILT_IN_HYPOT):
@@ -3204,6 +3209,7 @@ header_for_builtin_fn (enum built_in_fun
     CASE_FLT_FN (BUILT_IN_SINH):
     CASE_FLT_FN (BUILT_IN_SINCOS):
     CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
     CASE_FLT_FN (BUILT_IN_TAN):
     CASE_FLT_FN (BUILT_IN_TANH):
     CASE_FLT_FN (BUILT_IN_TGAMMA):
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c	(revision 254054)
+++ gcc/c-family/c-cppbuiltin.c	(working copy)
@@ -82,6 +82,11 @@ mode_has_fma (machine_mode mode)
       return !!HAVE_fmadf4;
 #endif
 
+#ifdef HAVE_fmakf4	/* PowerPC if long double != __float128.  */
+    case E_KFmode:
+      return !!HAVE_fmakf4;
+#endif
+
 #ifdef HAVE_fmaxf4
     case E_XFmode:
       return !!HAVE_fmaxf4;
@@ -1119,7 +1124,7 @@ c_cpp_builtins (cpp_reader *pfile)
 	       floatn_nx_types[i].extended ? "X" : "");
       sprintf (csuffix, "F%d%s", floatn_nx_types[i].n,
 	       floatn_nx_types[i].extended ? "x" : "");
-      builtin_define_float_constants (prefix, csuffix, "%s", NULL,
+      builtin_define_float_constants (prefix, csuffix, "%s", csuffix,
 				      FLOATN_NX_TYPE_NODE (i));
     }
 
Index: gcc/testsuite/gcc.target/powerpc/float128-hw.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw.c	(revision 254054)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw.c	(working copy)
@@ -2,16 +2,58 @@
 /* { dg-require-effective-target powerpc_p9vector_ok } */
 /* { dg-options "-mpower9-vector -O2" } */
 
-__float128 f128_add (__float128 a, __float128 b) { return a+b; }
-__float128 f128_sub (__float128 a, __float128 b) { return a-b; }
-__float128 f128_mul (__float128 a, __float128 b) { return a*b; }
-__float128 f128_div (__float128 a, __float128 b) { return a/b; }
-__float128 f128_fma (__float128 a, __float128 b, __float128 c) { return (a*b)+c; }
-long f128_cmove (__float128 a, __float128 b, long c, long d) { return (a == b) ? c : d; }
-
-/* { dg-final { scan-assembler "xsaddqp"  } } */
-/* { dg-final { scan-assembler "xssubqp"  } } */
-/* { dg-final { scan-assembler "xsmulqp"  } } */
-/* { dg-final { scan-assembler "xsdivqp"  } } */
-/* { dg-final { scan-assembler "xsmaddqp" } } */
-/* { dg-final { scan-assembler "xscmpuqp" } } */
+#ifndef TYPE
+#define TYPE _Float128
+#endif
+
+/* Test the code generation of the various _Float128 operations.  */
+TYPE f128_add (TYPE a, TYPE b) { return a+b; }
+TYPE f128_sub (TYPE a, TYPE b) { return a-b; }
+TYPE f128_mul (TYPE a, TYPE b) { return a*b; }
+TYPE f128_div (TYPE a, TYPE b) { return a/b; }
+TYPE f128_fma (TYPE a, TYPE b, TYPE c) { return (a*b)+c; }
+TYPE f128_fms (TYPE a, TYPE b, TYPE c) { return (a*b)-c; }
+TYPE f128_nfma (TYPE a, TYPE b, TYPE c) { return -((a*b)+c); }
+TYPE f128_nfms (TYPE a, TYPE b, TYPE c) { return -((a*b)-c); }
+TYPE f128_neg (TYPE a) { return -a; }
+
+long f128_cmove (TYPE a, TYPE b, long c, long d) { return (a == b) ? c : d; }
+
+double f128_to_double (TYPE a) { return (double)a; }
+float f128_to_float (TYPE a) { return (float)a; }
+long f128_to_long (TYPE a) { return (long)a; }
+unsigned long f128_to_ulong (TYPE a) { return (unsigned long)a; }
+int f128_to_int (TYPE a) { return (int)a; }
+unsigned int f128_to_uint (TYPE a) { return (unsigned int)a; }
+
+TYPE double_to_f128 (double a) { return (TYPE)a; }
+TYPE float_to_f128 (float a) { return (TYPE)a; }
+TYPE long_to_f128 (long a) { return (TYPE)a; }
+TYPE ulong_to_f128 (unsigned long a) { return (TYPE)a; }
+TYPE int_to_f128 (int a) { return (TYPE)a; }
+TYPE uint_to_f128 (unsigned int a) { return (TYPE)a; }
+
+/* { dg-final { scan-assembler     {\mmfvsrd\M}    } } */
+/* { dg-final { scan-assembler     {\mmfvsrwz\M}   } } */
+/* { dg-final { scan-assembler     {\mmtvsrd\M}    } } */
+/* { dg-final { scan-assembler     {\mmtvsrwa\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxscmpuqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvdpqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpdp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpdpo\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpsdz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpswz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpudz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvqpuwz\M} } } */
+/* { dg-final { scan-assembler 	   {\mxscvsdqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxscvudqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxsdivqp\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler 	   {\mxsmulqp\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxsnegqp\M}   } } */
+/* { dg-final { scan-assembler 	   {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler 	   {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler 	   {\mxssubqp\M}   } } */
+/* { dg-final { scan-assembler-not {\mbl\M}        } } */
+
Index: gcc/testsuite/gcc.target/powerpc/float128-hw2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw2.c	(working copy)
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math -std=gnu11" } */
+
+/* Test to make sure the compiler handles the standard _Float128 functions that
+   have hardware support in ISA 3.0/power9.  */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+
+#ifndef __FP_FAST_FMAF128
+#error "__FP_FAST_FMAF128 should be defined."
+#endif
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+extern _Float128 sqrtf128 (_Float128);
+extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return copysignf128 (a, b);
+}
+
+_Float128
+do_sqrt (_Float128 a)
+{
+  return sqrtf128 (a);
+}
+
+_Float128
+do_fma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, c);
+}
+
+_Float128
+do_fms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, -c);
+}
+
+_Float128
+do_nfma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, c);
+}
+
+_Float128
+do_nfms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler     {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler     {\mxssqrtqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler     {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler     {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M}        } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-hw3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-hw3.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/float128-hw3.c	(working copy)
@@ -0,0 +1,56 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math -std=c11" } */
+
+/* Test to make sure the compiler calls the external function instead of doing
+   the built-in processing for _Float128 functions that have hardware support
+   in ISA 3.0/power9 if are in strict standards mode, where the <func>f128 name
+   is not a synonym for __builtin_<func>f128.  */
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+extern _Float128 sqrtf128 (_Float128);
+extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return copysignf128 (a, b);
+}
+
+_Float128
+do_sqrt (_Float128 a)
+{
+  return sqrtf128 (a);
+}
+
+_Float128
+do_fma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, c);
+}
+
+_Float128
+do_fms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return fmaf128 (a, b, -c);
+}
+
+_Float128
+do_nfma (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, c);
+}
+
+_Float128
+do_nfms (_Float128 a, _Float128 b, _Float128 c)
+{
+  return -fmaf128 (a, b, -c);
+}
+
+/* { dg-final { scan-assembler-not   {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler-not   {\mxssqrtqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsmaddqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsmsubqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mxsnmaddqp\M} } } */
+/* { dg-final { scan-assembler-not   {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler-times {\mbl\M} 6      } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-fma2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(revision 254054)
+++ gcc/testsuite/gcc.target/powerpc/float128-fma2.c	(nonexistent)
@@ -1,9 +0,0 @@
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-/* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
-
-__float128
-xfma (__float128 a, __float128 b, __float128 c)
-{
-  return __builtin_fmaf128 (a, b, c); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
-}
Index: gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(revision 254054)
+++ gcc/testsuite/gcc.target/powerpc/float128-sqrt2.c	(nonexistent)
@@ -1,9 +0,0 @@
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-/* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -mno-float128-hardware -O2" } */
-
-__float128
-xsqrt (__float128 a)
-{
-  return __builtin_sqrtf128 (a); /* { dg-error "ISA 3.0 IEEE 128-bit" } */
-}

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-25 23:37                   ` [PATCH, version 5], " Michael Meissner
@ 2017-10-25 23:56                     ` Joseph Myers
  2017-10-26  0:04                       ` [PATCH, version 5a], " Michael Meissner
  0 siblings, 1 reply; 31+ messages in thread
From: Joseph Myers @ 2017-10-25 23:56 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

My only comment on this version is that the documentation in cpp.texi of 
__FP_FAST_* should be updated to mention __FP_FAST_FMAF@var{n} and 
__FP_FAST_FMAF@var{n}X.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-25 23:56                     ` Joseph Myers
@ 2017-10-26  0:04                       ` Michael Meissner
  2017-10-26  0:17                         ` Michael Meissner
  2017-10-27  2:27                         ` Segher Boessenkool
  0 siblings, 2 replies; 31+ messages in thread
From: Michael Meissner @ 2017-10-26  0:04 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 826 bytes --]

On Wed, Oct 25, 2017 at 11:41:24PM +0000, Joseph Myers wrote:
> My only comment on this version is that the documentation in cpp.texi of 
> __FP_FAST_* should be updated to mention __FP_FAST_FMAF@var{n} and 
> __FP_FAST_FMAF@var{n}X.

Here is the documentation to be added to the previoius patch.  With this
change, can I check it into the trunk (once Segher approves of the minor bit to
take out the PowerPC __builtin_{sqrtf128,fmaf128} builtins.

2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* doc/cpp.texi (Common Predefined Macros): Document defining
	__FP_FAST_FMAF<N> and __FP_FAST_FMAF<N>X if the back supports fma
	_Float<N> and _Float<N>X variants.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch48b --]
[-- Type: text/plain, Size: 1104 bytes --]

Index: gcc/doc/cpp.texi
===================================================================
--- gcc/doc/cpp.texi	(revision 254080)
+++ gcc/doc/cpp.texi	(working copy)
@@ -2366,6 +2366,21 @@ the include file @file{math.h} can defin
 @code{FP_FAST_FMA}, @code{FP_FAST_FMAF}, and @code{FP_FAST_FMAL}
 for compatibility with the 1999 C standard.
 
+@item __FP_FAST_FMAF16
+@itemx __FP_FAST_FMAF32
+@itemx __FP_FAST_FMAF64
+@itemx __FP_FAST_FMAF128
+@itemx __FP_FAST_FMAF32X
+@itemx __FP_FAST_FMAF64X
+@itemx __FP_FAST_FMAF128X
+These macros are defined with the value 1 if the backend supports the
+@code{fma} functions using the additional @code{_Float@var{n}} and
+@code{_Float@var{n}x} types that are defined in ISO/IEC TS
+18661-3:2015.  The include file @file{math.h} can define the
+@code{FP_FAST_FMAF@var{n}} and @code{FP_FAST_FMAF@var{n}x} macros if
+the user defined @code{__STDC_WANT_IEC_60559_TYPES_EXT__} before
+including @file{math.h}.
+
 @item __GCC_IEC_559
 This macro is defined to indicate the intended level of support for
 IEEE 754 (IEC 60559) floating-point arithmetic.  It expands to a

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-26  0:04                       ` [PATCH, version 5a], " Michael Meissner
@ 2017-10-26  0:17                         ` Michael Meissner
  2017-10-30 16:29                           ` Joseph Myers
  2017-10-27  2:27                         ` Segher Boessenkool
  1 sibling, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-26  0:17 UTC (permalink / raw)
  To: Michael Meissner, Joseph Myers, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

On Wed, Oct 25, 2017 at 07:57:09PM -0400, Michael Meissner wrote:
> On Wed, Oct 25, 2017 at 11:41:24PM +0000, Joseph Myers wrote:
> > My only comment on this version is that the documentation in cpp.texi of 
> > __FP_FAST_* should be updated to mention __FP_FAST_FMAF@var{n} and 
> > __FP_FAST_FMAF@var{n}X.
> 
> Here is the documentation to be added to the previoius patch.  With this
> change, can I check it into the trunk (once Segher approves of the minor bit to
> take out the PowerPC __builtin_{sqrtf128,fmaf128} builtins.
> 
> 2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>
> 
> 	* doc/cpp.texi (Common Predefined Macros): Document defining
> 	__FP_FAST_FMAF<N> and __FP_FAST_FMAF<N>X if the back supports fma
> 	_Float<N> and _Float<N>X variants.

Sigh, it is the end of the day for me.  The ChangeLog should be:

2017-10-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* doc/cpp.texi (Common Predefined Macros): Document defining
	__FP_FAST_FMAF<N> and __FP_FAST_FMAF<N>X if the backend supports
	fma _Float<N> and _Float<N>X variants.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-26  0:04                       ` [PATCH, version 5a], " Michael Meissner
  2017-10-26  0:17                         ` Michael Meissner
@ 2017-10-27  2:27                         ` Segher Boessenkool
  1 sibling, 0 replies; 31+ messages in thread
From: Segher Boessenkool @ 2017-10-27  2:27 UTC (permalink / raw)
  To: Michael Meissner, Joseph Myers, GCC Patches, David Edelsohn,
	Bill Schmidt

On Wed, Oct 25, 2017 at 07:57:09PM -0400, Michael Meissner wrote:
> On Wed, Oct 25, 2017 at 11:41:24PM +0000, Joseph Myers wrote:
> > My only comment on this version is that the documentation in cpp.texi of 
> > __FP_FAST_* should be updated to mention __FP_FAST_FMAF@var{n} and 
> > __FP_FAST_FMAF@var{n}X.
> 
> Here is the documentation to be added to the previoius patch.  With this
> change, can I check it into the trunk (once Segher approves of the minor bit to
> take out the PowerPC __builtin_{sqrtf128,fmaf128} builtins.

That bit is fine, of course :-)


Segher

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-26  0:17                         ` Michael Meissner
@ 2017-10-30 16:29                           ` Joseph Myers
  2017-10-30 18:05                             ` Michael Meissner
  0 siblings, 1 reply; 31+ messages in thread
From: Joseph Myers @ 2017-10-30 16:29 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

This has broken building the mainline glibc testsuite with GCC mainline 
for platforms where long double has binary128 format.

Recall that _FloatN type names are not supported for C++, because of the 
expectation that any C++ bindings for such types would be class-based like 
the TR 24733 DFP support rather than using built-in types such as 
_Float128.  Thus glibc uses __float128 to define _Float128 internally for 
C++ where __float128 is available, but where it is not available but long 
double has that format, the headers use long double to implement 
_Float128.  Thus you get conflicting declarations, headers declaring 
sqrtf128 to use a typedef for long double but the built-in functions using 
the internal _Float128 type that has no built-in name referring directly 
to it for C++.

One obvious possible fix would be for the builtins.def macros never to 
define public names such as sqrtf128 for C++, only ever for C.  That would 
be on the basis that C++ code is expected to be using a sqrt overload 
anyway - so making the built-in function available under a public name, in 
the case where __float128 exists for C++, is a matter for libstdc++ 
headers.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-30 16:29                           ` Joseph Myers
@ 2017-10-30 18:05                             ` Michael Meissner
  2017-10-30 18:38                               ` Joseph Myers
  0 siblings, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-30 18:05 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

On Mon, Oct 30, 2017 at 04:16:42PM +0000, Joseph Myers wrote:
> This has broken building the mainline glibc testsuite with GCC mainline 
> for platforms where long double has binary128 format.
> 
> Recall that _FloatN type names are not supported for C++, because of the 
> expectation that any C++ bindings for such types would be class-based like 
> the TR 24733 DFP support rather than using built-in types such as 
> _Float128.  Thus glibc uses __float128 to define _Float128 internally for 
> C++ where __float128 is available, but where it is not available but long 
> double has that format, the headers use long double to implement 
> _Float128.  Thus you get conflicting declarations, headers declaring 
> sqrtf128 to use a typedef for long double but the built-in functions using 
> the internal _Float128 type that has no built-in name referring directly 
> to it for C++.
> 
> One obvious possible fix would be for the builtins.def macros never to 
> define public names such as sqrtf128 for C++, only ever for C.  That would 
> be on the basis that C++ code is expected to be using a sqrt overload 
> anyway - so making the built-in function available under a public name, in 
> the case where __float128 exists for C++, is a matter for libstdc++ 
> headers.

Arghh, yes, I can restrict it to just the C language.  Would you prefer just
that?  Do we want a target hook to be able to over-ride this on a platform
basis (with the default behavior only enabling it for C)?

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-30 18:05                             ` Michael Meissner
@ 2017-10-30 18:38                               ` Joseph Myers
  2017-10-30 23:06                                 ` Michael Meissner
  0 siblings, 1 reply; 31+ messages in thread
From: Joseph Myers @ 2017-10-30 18:38 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Mon, 30 Oct 2017, Michael Meissner wrote:

> > One obvious possible fix would be for the builtins.def macros never to 
> > define public names such as sqrtf128 for C++, only ever for C.  That would 
> > be on the basis that C++ code is expected to be using a sqrt overload 
> > anyway - so making the built-in function available under a public name, in 
> > the case where __float128 exists for C++, is a matter for libstdc++ 
> > headers.
> 
> Arghh, yes, I can restrict it to just the C language.  Would you prefer just
> that?  Do we want a target hook to be able to over-ride this on a platform

Yes, I think such a restriction is appropriate (that is, C and ObjC get 
both sqrtf128 and __builtin_sqrtf128 built-in functions, C++ and ObjC++ 
get only __builtin_sqrtf128).

> basis (with the default behavior only enabling it for C)?

If we think that the preferred way for C++ code to access the underlying 
functions is via function overloads for __float128 (not currently 
implemented in libstdc++, it seems) rather than suffixed functions, or 
through accessing the format as long double once that support is working, 
a target hook may not be neded.  If C++ code is expected to use 
f128-suffixed functions directly, presumably it's desirable for a C++ call 
to sqrtf128 to be inlined where possible and so you'd want a hook, or some 
other way of enabling the built-in functions for C++ only in the case 
where they are usefully distinct from the float / double / long double 
functions.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-30 18:38                               ` Joseph Myers
@ 2017-10-30 23:06                                 ` Michael Meissner
  2017-10-30 23:29                                   ` Michael Meissner
  2017-10-30 23:35                                   ` Joseph Myers
  0 siblings, 2 replies; 31+ messages in thread
From: Michael Meissner @ 2017-10-30 23:06 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 2991 bytes --]

On Mon, Oct 30, 2017 at 06:32:44PM +0000, Joseph Myers wrote:
> On Mon, 30 Oct 2017, Michael Meissner wrote:
> 
> > > One obvious possible fix would be for the builtins.def macros never to 
> > > define public names such as sqrtf128 for C++, only ever for C.  That would 
> > > be on the basis that C++ code is expected to be using a sqrt overload 
> > > anyway - so making the built-in function available under a public name, in 
> > > the case where __float128 exists for C++, is a matter for libstdc++ 
> > > headers.
> > 
> > Arghh, yes, I can restrict it to just the C language.  Would you prefer just
> > that?  Do we want a target hook to be able to over-ride this on a platform
> 
> Yes, I think such a restriction is appropriate (that is, C and ObjC get 
> both sqrtf128 and __builtin_sqrtf128 built-in functions, C++ and ObjC++ 
> get only __builtin_sqrtf128).
> 
> > basis (with the default behavior only enabling it for C)?
> 
> If we think that the preferred way for C++ code to access the underlying 
> functions is via function overloads for __float128 (not currently 
> implemented in libstdc++, it seems) rather than suffixed functions, or 
> through accessing the format as long double once that support is working, 
> a target hook may not be neded.  If C++ code is expected to use 
> f128-suffixed functions directly, presumably it's desirable for a C++ call 
> to sqrtf128 to be inlined where possible and so you'd want a hook, or some 
> other way of enabling the built-in functions for C++ only in the case 
> where they are usefully distinct from the float / double / long double 
> functions.

This patch fixes exporting the non __builtin_ names to be done by default only
for the C language.  I added a target hook in case a port needs to enable
built-ins for C++ (either wholesale, or for particular built-in functions).

I have done a bootstrap on a little endian Power8 system and it had no
regressions.  The x86-64 bootstrap just entered stage3.  Assuming there are no
regressions on x86-64, can I check this patch into the trunk?

2017-10-30  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* builtins.def (DEF_FLOATN_BUILTIN): Change most _Float<N> and
	_Float<N>X built-in functions so that the variant without the
	"__builtin_" prefix is only enabled for the GNU C language when it
	is non-strict ANSI/ISO mode.
	(DEF_EXT_LIB_FLOATN_NX_BUILTINS): Likewise.
	* target.def (floatn_builtin_p): Add a target hook to control
	whether _Float<N> and _Float<N>X built-in functions without the
	"__builtin_" prefix are enabled.  Include langhooks.h in
	targhooks.c.
	* targhooks.h (default_floatn_builtin_p): Likewise.
	* targhooks.c (default_floatn_builtin_p): Likewise.
	* doc/tm.texi.in (TARGET_FLOATN_BUILTIN_P): Document the
	floatn_builtin_p target hook.
	* doc/tm.texi (TARGET_FLOATN_BUILTIN_P): Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch50b --]
[-- Type: text/plain, Size: 7008 bytes --]

Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(revision 254232)
+++ gcc/builtins.def	(working copy)
@@ -130,18 +130,26 @@ along with GCC; see the file COPYING3.
 
 /* A set of GCC builtins for _FloatN and _FloatNx types.  TYPE_MACRO is called
    with an argument such as FLOAT32 to produce the enum value for the type.  If
-   we are being fully conformant we ignore the version of these builtins that
-   does not being with __builtin_.  */
+   we are compiling for the C language with GNU extensions, we enable the name
+   without the __builtin_ prefix as well as the name with the __builtin_
+   prefix.  C++ does not enable these names by default because they don't have
+   the _Float<N> and _Float<N>X keywords, and a class based library should use
+   the __builtin_ names.  */
+#undef DEF_FLOATN_BUILTIN
+#define DEF_FLOATN_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
+	       targetm.floatn_builtin_p ((int) ENUM),			\
+	       targetm.floatn_builtin_p ((int) ENUM), true, ATTRS, false, true)
 #undef DEF_EXT_LIB_FLOATN_NX_BUILTINS
-#define DEF_EXT_LIB_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)		\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
-  DEF_EXT_LIB_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
-  DEF_EXT_LIB_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
-  DEF_EXT_LIB_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS)\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS)\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS)\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), \
-			ATTRS)
+#define DEF_EXT_LIB_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)	\
+  DEF_FLOATN_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), \
+		      ATTRS)
 
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C94 or above.  */
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 254232)
+++ gcc/target.def	(working copy)
@@ -3458,6 +3458,19 @@ if @var{extended} is false, 16 or greate
  opt_scalar_float_mode, (int n, bool extended),
  default_floatn_mode)
 
+DEFHOOK
+(floatn_builtin_p,
+  "Define this to return true if the @code{_Float@var{n}} and\n\
+@code{_Float@var{n}x} built-in functions should implicitly enable the\n\
+built-in function without the @code{__builtin_} prefix in addition to the\n\
+normal built-in function with the @code{__builtin_} prefix.  The default is\n\
+to only enable built-in functions without the @code{__builtin_} prefix for\n\
+the GNU C langauge.  In strict ANSI/ISO mode, the built-in function without\n\
+the @code{__builtin_} prefix is not enabled.  The argument @code{FUNC} is the\n\
+@code{enum builtin_in_function} id of the function to be enabled.",
+ bool, (int func),
+ default_floatn_builtin_p)
+
 /* Compute cost of moving data from a register of class FROM to one of
    TO, using MODE.  */
 DEFHOOK
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 254232)
+++ gcc/targhooks.h	(working copy)
@@ -75,6 +75,7 @@ extern tree default_mangle_assembler_nam
 extern bool default_scalar_mode_supported_p (scalar_mode);
 extern bool default_libgcc_floating_mode_supported_p (scalar_float_mode);
 extern opt_scalar_float_mode default_floatn_mode (int, bool);
+extern bool default_floatn_builtin_p (int);
 extern bool targhook_words_big_endian (void);
 extern bool targhook_float_words_big_endian (void);
 extern bool default_float_exceptions_rounding_supported_p (void);
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 254232)
+++ gcc/targhooks.c	(working copy)
@@ -81,7 +81,7 @@ along with GCC; see the file COPYING3.
 #include "predict.h"
 #include "params.h"
 #include "real.h"
-
+#include "langhooks.h"
 
 bool
 default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
@@ -563,6 +563,19 @@ default_floatn_mode (int n, bool extende
   return opt_scalar_float_mode ();
 }
 
+/* Define this to return true if the _Floatn and _Floatnx built-in functions
+   should implicitly enable the built-in function without the __builtin_ prefix
+   in addition to the normal built-in function with the __builtin_ prefix.  The
+   default is to only enable built-in functions without the __builtin_ prefix
+   for the GNU C langauge.  The argument FUNC is the enum builtin_in_function
+   id of the function to be enabled.  */
+
+bool
+default_floatn_builtin_p (int func ATTRIBUTE_UNUSED)
+{
+  return lang_GNU_C ();
+}
+
 /* Make some target macros useable by target-independent code.  */
 bool
 targhook_words_big_endian (void)
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 254232)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -3326,6 +3326,8 @@ stack.
 
 @hook TARGET_FLOATN_MODE
 
+@hook TARGET_FLOATN_BUILTIN_P
+
 @hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
 
 @node Scalar Return
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 254232)
+++ gcc/doc/tm.texi	(working copy)
@@ -4284,6 +4284,17 @@ ISO/IEC TS 18661-3:2015; that is, @var{n
 if @var{extended} is false, 16 or greater than 128 and a multiple of 32.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_FLOATN_BUILTIN_P (int @var{func})
+Define this to return true if the @code{_Float@var{n}} and
+@code{_Float@var{n}x} built-in functions should implicitly enable the
+built-in function without the @code{__builtin_} prefix in addition to the
+normal built-in function with the @code{__builtin_} prefix.  The default is
+to only enable built-in functions without the @code{__builtin_} prefix for
+the GNU C langauge.  In strict ANSI/ISO mode, the built-in function without
+the @code{__builtin_} prefix is not enabled.  The argument @code{FUNC} is the
+@code{enum builtin_in_function} id of the function to be enabled.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P (machine_mode @var{mode})
 Define this to return nonzero for machine modes for which the port has
 small register classes.  If this target hook returns nonzero for a given

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-30 23:06                                 ` Michael Meissner
@ 2017-10-30 23:29                                   ` Michael Meissner
  2017-10-30 23:35                                   ` Joseph Myers
  1 sibling, 0 replies; 31+ messages in thread
From: Michael Meissner @ 2017-10-30 23:29 UTC (permalink / raw)
  To: Michael Meissner, Joseph Myers
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

The x86-64 bootstrap/make check run has now finished, and there were no
regressions.  Can I check the changes into trunk?

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-30 23:06                                 ` Michael Meissner
  2017-10-30 23:29                                   ` Michael Meissner
@ 2017-10-30 23:35                                   ` Joseph Myers
  2017-10-30 23:48                                     ` Michael Meissner
  2017-10-31 18:04                                     ` Michael Meissner
  1 sibling, 2 replies; 31+ messages in thread
From: Joseph Myers @ 2017-10-30 23:35 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Mon, 30 Oct 2017, Michael Meissner wrote:

> This patch fixes exporting the non __builtin_ names to be done by default only
> for the C language.  I added a target hook in case a port needs to enable
> built-ins for C++ (either wholesale, or for particular built-in functions).

Testing lang_GNU_C () can't possibly be correct here; ObjC should always 
be handled like C unless there is a strong reason not to do so, explicitly 
commented.

Also, I'd expect the FALLBACK_P argument to DEF_BUILTIN to be true, not a 
call to the hook; __builtin_sqrtf128 should always end up generating a 
call to the out-of-line sqrtf128 function if not inlined, regardless of 
source language.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-30 23:35                                   ` Joseph Myers
@ 2017-10-30 23:48                                     ` Michael Meissner
  2017-10-31 18:04                                     ` Michael Meissner
  1 sibling, 0 replies; 31+ messages in thread
From: Michael Meissner @ 2017-10-30 23:48 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

On Mon, Oct 30, 2017 at 11:30:12PM +0000, Joseph Myers wrote:
> On Mon, 30 Oct 2017, Michael Meissner wrote:
> 
> > This patch fixes exporting the non __builtin_ names to be done by default only
> > for the C language.  I added a target hook in case a port needs to enable
> > built-ins for C++ (either wholesale, or for particular built-in functions).
> 
> Testing lang_GNU_C () can't possibly be correct here; ObjC should always 
> be handled like C unless there is a strong reason not to do so, explicitly 
> commented.

Ok, tomorrow, I will look for a more appropriate way to check for C.

> Also, I'd expect the FALLBACK_P argument to DEF_BUILTIN to be true, not a 
> call to the hook; __builtin_sqrtf128 should always end up generating a 
> call to the out-of-line sqrtf128 function if not inlined, regardless of 
> source language.

I was wondering whether fallback_t should always be true.

Thanks.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-30 23:35                                   ` Joseph Myers
  2017-10-30 23:48                                     ` Michael Meissner
@ 2017-10-31 18:04                                     ` Michael Meissner
  2017-10-31 18:26                                       ` Joseph Myers
  1 sibling, 1 reply; 31+ messages in thread
From: Michael Meissner @ 2017-10-31 18:04 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, GCC Patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt

[-- Attachment #1: Type: text/plain, Size: 2092 bytes --]

On Mon, Oct 30, 2017 at 11:30:12PM +0000, Joseph Myers wrote:
> On Mon, 30 Oct 2017, Michael Meissner wrote:
> 
> > This patch fixes exporting the non __builtin_ names to be done by default only
> > for the C language.  I added a target hook in case a port needs to enable
> > built-ins for C++ (either wholesale, or for particular built-in functions).
> 
> Testing lang_GNU_C () can't possibly be correct here; ObjC should always 
> be handled like C unless there is a strong reason not to do so, explicitly 
> commented.
> 
> Also, I'd expect the FALLBACK_P argument to DEF_BUILTIN to be true, not a 
> call to the hook; __builtin_sqrtf128 should always end up generating a 
> call to the out-of-line sqrtf128 function if not inlined, regardless of 
> source language.

This patch fixes both issues.  I have done bootstrap builds on both a little
endian power8 and an x86-64 system with no regressions.  Can I check this into
the trunk?

Assuming the following patch is ok, I have another patch that is awaiting
review:
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg02124.html

2017-10-31  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* builtins.def (DEF_FLOATN_BUILTIN): Change most _Float<N> and
	_Float<N>X built-in functions so that the variant without the
	"__builtin_" prefix is only enabled for the GNU C and Objective C
	languages when they are in non-strict ANSI/ISO mode.
	(DEF_EXT_LIB_FLOATN_NX_BUILTINS): Likewise.
	* target.def (floatn_builtin_p): Add a target hook to control
	whether _Float<N> and _Float<N>X built-in functions without the
	"__builtin_" prefix are enabled, and return true for C and
	Objective C in the default hook.  Include langhooks.h in
	targhooks.c.
	* targhooks.h (default_floatn_builtin_p): Likewise.
	* targhooks.c (default_floatn_builtin_p): Likewise.
	* doc/tm.texi.in (TARGET_FLOATN_BUILTIN_P): Document the
	floatn_builtin_p target hook.
	* doc/tm.texi (TARGET_FLOATN_BUILTIN_P): Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

[-- Attachment #2: ieee128-patch51b --]
[-- Type: text/plain, Size: 7174 bytes --]

Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(revision 254243)
+++ gcc/builtins.def	(working copy)
@@ -130,18 +130,26 @@ along with GCC; see the file COPYING3.
 
 /* A set of GCC builtins for _FloatN and _FloatNx types.  TYPE_MACRO is called
    with an argument such as FLOAT32 to produce the enum value for the type.  If
-   we are being fully conformant we ignore the version of these builtins that
-   does not being with __builtin_.  */
+   we are compiling for the C language with GNU extensions, we enable the name
+   without the __builtin_ prefix as well as the name with the __builtin_
+   prefix.  C++ does not enable these names by default because they don't have
+   the _Float<N> and _Float<N>X keywords, and a class based library should use
+   the __builtin_ names.  */
+#undef DEF_FLOATN_BUILTIN
+#define DEF_FLOATN_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
+	       targetm.floatn_builtin_p ((int) ENUM), true, true, ATTRS, \
+	       false, true)
 #undef DEF_EXT_LIB_FLOATN_NX_BUILTINS
-#define DEF_EXT_LIB_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)		\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
-  DEF_EXT_LIB_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
-  DEF_EXT_LIB_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
-  DEF_EXT_LIB_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS)\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS)\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS)\
-  DEF_EXT_LIB_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), \
-			ATTRS)
+#define DEF_EXT_LIB_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)	\
+  DEF_FLOATN_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS) \
+  DEF_FLOATN_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), \
+		      ATTRS)
 
 /* Like DEF_LIB_BUILTIN, except that the function is only a part of
    the standard in C94 or above.  */
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 254243)
+++ gcc/target.def	(working copy)
@@ -3458,6 +3458,19 @@ if @var{extended} is false, 16 or greate
  opt_scalar_float_mode, (int n, bool extended),
  default_floatn_mode)
 
+DEFHOOK
+(floatn_builtin_p,
+  "Define this to return true if the @code{_Float@var{n}} and\n\
+@code{_Float@var{n}x} built-in functions should implicitly enable the\n\
+built-in function without the @code{__builtin_} prefix in addition to the\n\
+normal built-in function with the @code{__builtin_} prefix.  The default is\n\
+to only enable built-in functions without the @code{__builtin_} prefix for\n\
+the GNU C langauge.  In strict ANSI/ISO mode, the built-in function without\n\
+the @code{__builtin_} prefix is not enabled.  The argument @code{FUNC} is the\n\
+@code{enum builtin_in_function} id of the function to be enabled.",
+ bool, (int func),
+ default_floatn_builtin_p)
+
 /* Compute cost of moving data from a register of class FROM to one of
    TO, using MODE.  */
 DEFHOOK
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 254243)
+++ gcc/targhooks.h	(working copy)
@@ -75,6 +75,7 @@ extern tree default_mangle_assembler_nam
 extern bool default_scalar_mode_supported_p (scalar_mode);
 extern bool default_libgcc_floating_mode_supported_p (scalar_float_mode);
 extern opt_scalar_float_mode default_floatn_mode (int, bool);
+extern bool default_floatn_builtin_p (int);
 extern bool targhook_words_big_endian (void);
 extern bool targhook_float_words_big_endian (void);
 extern bool default_float_exceptions_rounding_supported_p (void);
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 254243)
+++ gcc/targhooks.c	(working copy)
@@ -81,7 +81,7 @@ along with GCC; see the file COPYING3.
 #include "predict.h"
 #include "params.h"
 #include "real.h"
-
+#include "langhooks.h"
 
 bool
 default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
@@ -563,6 +563,28 @@ default_floatn_mode (int n, bool extende
   return opt_scalar_float_mode ();
 }
 
+/* Define this to return true if the _Floatn and _Floatnx built-in functions
+   should implicitly enable the built-in function without the __builtin_ prefix
+   in addition to the normal built-in function with the __builtin_ prefix.  The
+   default is to only enable built-in functions without the __builtin_ prefix
+   for the GNU C langauge.  The argument FUNC is the enum builtin_in_function
+   id of the function to be enabled.  */
+
+bool
+default_floatn_builtin_p (int func ATTRIBUTE_UNUSED)
+{
+  static bool first_time_p = true;
+  static bool c_or_objective_c;
+
+  if (first_time_p)
+    {
+      first_time_p = false;
+      c_or_objective_c = lang_GNU_C () || lang_GNU_OBJC ();
+    }
+
+  return c_or_objective_c;
+}
+
 /* Make some target macros useable by target-independent code.  */
 bool
 targhook_words_big_endian (void)
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 254243)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -3326,6 +3326,8 @@ stack.
 
 @hook TARGET_FLOATN_MODE
 
+@hook TARGET_FLOATN_BUILTIN_P
+
 @hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
 
 @node Scalar Return
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 254243)
+++ gcc/doc/tm.texi	(working copy)
@@ -4284,6 +4284,17 @@ ISO/IEC TS 18661-3:2015; that is, @var{n
 if @var{extended} is false, 16 or greater than 128 and a multiple of 32.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_FLOATN_BUILTIN_P (int @var{func})
+Define this to return true if the @code{_Float@var{n}} and
+@code{_Float@var{n}x} built-in functions should implicitly enable the
+built-in function without the @code{__builtin_} prefix in addition to the
+normal built-in function with the @code{__builtin_} prefix.  The default is
+to only enable built-in functions without the @code{__builtin_} prefix for
+the GNU C langauge.  In strict ANSI/ISO mode, the built-in function without
+the @code{__builtin_} prefix is not enabled.  The argument @code{FUNC} is the
+@code{enum builtin_in_function} id of the function to be enabled.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P (machine_mode @var{mode})
 Define this to return nonzero for machine modes for which the port has
 small register classes.  If this target hook returns nonzero for a given

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH, version 5a], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions
  2017-10-31 18:04                                     ` Michael Meissner
@ 2017-10-31 18:26                                       ` Joseph Myers
  0 siblings, 0 replies; 31+ messages in thread
From: Joseph Myers @ 2017-10-31 18:26 UTC (permalink / raw)
  To: Michael Meissner
  Cc: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt

On Tue, 31 Oct 2017, Michael Meissner wrote:

> On Mon, Oct 30, 2017 at 11:30:12PM +0000, Joseph Myers wrote:
> > On Mon, 30 Oct 2017, Michael Meissner wrote:
> > 
> > > This patch fixes exporting the non __builtin_ names to be done by default only
> > > for the C language.  I added a target hook in case a port needs to enable
> > > built-ins for C++ (either wholesale, or for particular built-in functions).
> > 
> > Testing lang_GNU_C () can't possibly be correct here; ObjC should always 
> > be handled like C unless there is a strong reason not to do so, explicitly 
> > commented.
> > 
> > Also, I'd expect the FALLBACK_P argument to DEF_BUILTIN to be true, not a 
> > call to the hook; __builtin_sqrtf128 should always end up generating a 
> > call to the out-of-line sqrtf128 function if not inlined, regardless of 
> > source language.
> 
> This patch fixes both issues.  I have done bootstrap builds on both a little
> endian power8 and an x86-64 system with no regressions.  Can I check this into
> the trunk?

All the references to "enum builtin_in_function", in comments and 
documentation, should be "enum built_in_function".  OK with that change.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2017-10-31 18:25 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-13 21:46 [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0 Michael Meissner
2017-09-13 22:49 ` Joseph Myers
2017-09-14 19:02   ` Michael Meissner
2017-10-19 22:15   ` [PATCH, version 2], Add support for _Float<N> and _Float<N>X sqrt, fma, fmin, fmax built-in functions Michael Meissner
2017-10-19 23:00     ` Joseph Myers
2017-10-19 23:00       ` Michael Meissner
2017-10-19 23:08         ` Joseph Myers
2017-10-24 22:40       ` [PATCH, version 3], " Michael Meissner
2017-10-24 23:13         ` Joseph Myers
2017-10-24 23:58           ` Michael Meissner
2017-10-25 19:25           ` [PATCH, version 4], " Michael Meissner
2017-10-25 20:01             ` Michael Meissner
2017-10-25 20:11             ` Joseph Myers
2017-10-25 20:31               ` Michael Meissner
2017-10-25 20:50                 ` Joseph Myers
2017-10-25 23:37                   ` [PATCH, version 5], " Michael Meissner
2017-10-25 23:56                     ` Joseph Myers
2017-10-26  0:04                       ` [PATCH, version 5a], " Michael Meissner
2017-10-26  0:17                         ` Michael Meissner
2017-10-30 16:29                           ` Joseph Myers
2017-10-30 18:05                             ` Michael Meissner
2017-10-30 18:38                               ` Joseph Myers
2017-10-30 23:06                                 ` Michael Meissner
2017-10-30 23:29                                   ` Michael Meissner
2017-10-30 23:35                                   ` Joseph Myers
2017-10-30 23:48                                     ` Michael Meissner
2017-10-31 18:04                                     ` Michael Meissner
2017-10-31 18:26                                       ` Joseph Myers
2017-10-27  2:27                         ` Segher Boessenkool
2017-09-14 14:54 ` [PATCH], Add support for __builtin_{sqrt,fma}f128 on PowerPC ISA 3.0 Segher Boessenkool
2017-09-14 22:21   ` Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).