diff mbox series

, PR 82748, Fix __builtin_fabsq on PowerPC

Message ID 20171103220738.GA29893@ibm-tiger.the-meissners.org
State New
Headers show
Series , PR 82748, Fix __builtin_fabsq on PowerPC | expand

Commit Message

Michael Meissner Nov. 3, 2017, 10:07 p.m. UTC
This patch fixes PR 82748, which is a compiler abort if you use the old
__builtin_fabsq function when you are changing the long double default from IBM
double-double format to IEEE.

The problem is __builtin_fabsq returns a KFmode type, but when you use
-mabi=ieeelongdouble, the float128 type is TFmode.

In fixing this, I made use of the recent changes that I made to move float128
fabs, copysign, fma, sqrt, etc. handling to machine independent code.  I just
made __builtin_fabsq map into __builtin_fabsf128.  So all of the old 'q'
built-ins got deleted, and #define'ed to the new name.

A related issue is the round to odd functions only take KFmode arguments and
return KFmode results.  These would not work when the -mabi=ieeelongdouble
switch is used.  I originally was going down the usual path of using the
overloaded builtin support to support these functions with KFmode or TFmode
arguments.  However, it was getting complex, in that we would need to move the
TARGET_IEEEQUAD option to a option bit, add new BTM declarations, add new BTI
type fields, etc.  It was just simpler to build the calls manually instead of
using the rs6000-builtin.def machinery.

I have checked these patches on a little endian power8 system, and after
bootstrap and check, there were no regressions.  Can I check this patch into
trunk?

Note, I will need to re-engineer a different patch for GCC 7, as the machine
independent handling of f128 builtins are not in GCC 7 (the bug was against GCC
7.x).

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

	PR target/82748
	* config/rs6000/rs6000-builtin.def (BU_FLOAT128_1): Delete
	float128 helper macros, which are no longer used after deleting
	the old 'q' built-in functions, and moving the round to odd
	built-in functions to being special built-in functions.
	(BU_FLOAT128_2): Likewise.
	(BU_FLOAT128_1_HW): Likewise.
	(BU_FLOAT128_2_HW): Likewise.
	(BU_FLOAT128_3_HW): Likewise.
	(FABSQ): Delete old 'q' built-in functions.
	(COPYSIGNQ): Likewise.
	(NQNQ): Likewise.
	(NQNSQ): Likewise.
	(INFQ): Likewise.
	(HUGE_VALQ): Likewise.
	(SQRTF128_ODD): Move round to odd built-in functions to be
	special built-in functions, so that we can handle
	-mabi=ieeelongdouble.
	(TRUNCF128_ODD): Likewise.
	(ADDF128_ODD): Likewise.
	(SUBF128_ODD): Likewise.
	(MULF128_ODD): Likewise.
	(DIVF128_ODD): Likewise.
	(FMAF128_ODD): Likewise.
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Map old 'q'
	built-in names to 'f128'.
	* config/rs6000/rs6000.c (rs6000_fold_builtin): Remove folding the
	old 'q' built-in functions, as the machine independent code for
	'f128' built-in functions handles this.
	(rs6000_expand_builtin): Add expansion for float128 round to odd
	functions, keying off on -mabi=ieeelongdouble of whether to use
	the KFmode or TFmode variant.
	(rs6000_init_builtins): Initialize the _Float128 round to odd
	built-in functions.
	* doc/extend.texi (PowerPC Built-in Functions): Document the old
	_Float128 'q' built-in functions are now mapped into the new
	'f128' built-in functions.

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

	PR target/82748
	* gcc.target/powerpc/pr82748-1.c: New test.
	* gcc.target/powerpc/pr82748-2.c: Likewise.

Comments

Segher Boessenkool Nov. 6, 2017, 11:56 a.m. UTC | #1
Hi!

On Fri, Nov 03, 2017 at 06:07:38PM -0400, Michael Meissner wrote:
> This patch fixes PR 82748, which is a compiler abort if you use the old
> __builtin_fabsq function when you are changing the long double default from IBM
> double-double format to IEEE.
> 
> The problem is __builtin_fabsq returns a KFmode type, but when you use
> -mabi=ieeelongdouble, the float128 type is TFmode.


> --- gcc/config/rs6000/rs6000.c	(revision 254357)
> +++ gcc/config/rs6000/rs6000.c	(working copy)
> @@ -16109,39 +16109,11 @@ rs6000_invalid_builtin (enum rs6000_buil
>     from ia64.c.  */
>  
>  static tree
> -rs6000_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
> -		     tree *args, bool ignore ATTRIBUTE_UNUSED)
> +rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
> +		     int n_args  ATTRIBUTE_UNUSED,
> +		     tree *args  ATTRIBUTE_UNUSED,
> +		     bool ignore ATTRIBUTE_UNUSED)

No extra spaces please.

If the arguments are always unused, you can simply leave out their name
(or comment the name), like

static tree
rs6000_fold_builtin (tree /*fndecl*/, int /*n_args*/, tree * /*args*/,
		     bool /*ignore*/)

or

static tree
rs6000_fold_builtin (tree, int, tree *, bool)

> +    case FLOAT128_BUILTIN_TRUNCF128_ODD:
> +      return rs6000_expand_unop_builtin (TARGET_IEEEQUAD
> +					  ? CODE_FOR_trunctfdf2_odd
> +					  : CODE_FOR_trunckfdf2_odd, exp, target);

The indent is wrong in this one.

Rest looks good.  Okay for trunk.  Thanks!


Segher
Michael Meissner Nov. 6, 2017, 6:01 p.m. UTC | #2
On Mon, Nov 06, 2017 at 05:56:59AM -0600, Segher Boessenkool wrote:
> Hi!
> 
> On Fri, Nov 03, 2017 at 06:07:38PM -0400, Michael Meissner wrote:
> > This patch fixes PR 82748, which is a compiler abort if you use the old
> > __builtin_fabsq function when you are changing the long double default from IBM
> > double-double format to IEEE.
> > 
> > The problem is __builtin_fabsq returns a KFmode type, but when you use
> > -mabi=ieeelongdouble, the float128 type is TFmode.
> 
> 
> > --- gcc/config/rs6000/rs6000.c	(revision 254357)
> > +++ gcc/config/rs6000/rs6000.c	(working copy)
> > @@ -16109,39 +16109,11 @@ rs6000_invalid_builtin (enum rs6000_buil
> >     from ia64.c.  */
> >  
> >  static tree
> > -rs6000_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
> > -		     tree *args, bool ignore ATTRIBUTE_UNUSED)
> > +rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
> > +		     int n_args  ATTRIBUTE_UNUSED,
> > +		     tree *args  ATTRIBUTE_UNUSED,
> > +		     bool ignore ATTRIBUTE_UNUSED)
> 
> No extra spaces please.

ok.

> If the arguments are always unused, you can simply leave out their name
> (or comment the name), like

If you look further down, you will see that SUBTARGET_FOLD_BUILTIN is called if
it is defined, and darwin seems to use it.

We could do a cleanup where the hook is now not defined if
SUBTARGET_FOLD_BUILTIN is not defined.

it is defined, so we don't know whether the arguments are used or not. 
> static tree
> rs6000_fold_builtin (tree /*fndecl*/, int /*n_args*/, tree * /*args*/,
> 		     bool /*ignore*/)
> 
> or
> 
> static tree
> rs6000_fold_builtin (tree, int, tree *, bool)
> 
> > +    case FLOAT128_BUILTIN_TRUNCF128_ODD:
> > +      return rs6000_expand_unop_builtin (TARGET_IEEEQUAD
> > +					  ? CODE_FOR_trunctfdf2_odd
> > +					  : CODE_FOR_trunckfdf2_odd, exp, target);
> 
> The indent is wrong in this one.

Ok.

> Rest looks good.  Okay for trunk.  Thanks!
> 
> 
> Segher
>
diff mbox series

Patch

Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 254357)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -660,48 +660,6 @@ 
 		     | RS6000_BTC_BINARY),				\
 		    CODE_FOR_ ## ICODE)			/* ICODE */
 
-/* IEEE 128-bit floating-point builtins.  */
-#define BU_FLOAT128_2(ENUM, NAME, ATTR, ICODE)                          \
-  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,              /* ENUM */      \
-		    "__builtin_" NAME,                  /* NAME */      \
-		    RS6000_BTM_FLOAT128,                /* MASK */      \
-		    (RS6000_BTC_ ## ATTR                /* ATTR */      \
-		     | RS6000_BTC_BINARY),                              \
-		    CODE_FOR_ ## ICODE)                 /* ICODE */
-
-#define BU_FLOAT128_1(ENUM, NAME, ATTR, ICODE)                          \
-  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,              /* ENUM */      \
-		    "__builtin_" NAME,                  /* NAME */      \
-		    RS6000_BTM_FLOAT128,                /* MASK */      \
-		    (RS6000_BTC_ ## ATTR                /* ATTR */      \
-		     | 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_2_HW(ENUM, NAME, ATTR, ICODE)                       \
-  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,              /* ENUM */      \
-		    "__builtin_" NAME,                  /* NAME */      \
-		    RS6000_BTM_FLOAT128_HW,             /* MASK */      \
-		    (RS6000_BTC_ ## ATTR                /* ATTR */      \
-		     | RS6000_BTC_BINARY),                              \
-		    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.  */
@@ -2365,23 +2323,6 @@  BU_P9_64BIT_2 (CMPEQB,	"byte_in_set",	CO
 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 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)
-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.  */
-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_ODD,	 "fmaf128_round_to_odd",   CONST, fmakf4_odd)
 
 /* 1 argument crypto functions.  */
 BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox)
@@ -2517,17 +2458,33 @@  BU_SPECIAL_X (RS6000_BUILTIN_CPU_IS, "__
 BU_SPECIAL_X (RS6000_BUILTIN_CPU_SUPPORTS, "__builtin_cpu_supports",
 	      RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
 
-BU_SPECIAL_X (RS6000_BUILTIN_NANQ, "__builtin_nanq",
-	      RS6000_BTM_FLOAT128, RS6000_BTC_CONST)
-
-BU_SPECIAL_X (RS6000_BUILTIN_NANSQ, "__builtin_nansq",
-	      RS6000_BTM_FLOAT128, RS6000_BTC_CONST)
-
-BU_SPECIAL_X (RS6000_BUILTIN_INFQ, "__builtin_infq",
-	      RS6000_BTM_FLOAT128, RS6000_BTC_CONST)
-
-BU_SPECIAL_X (RS6000_BUILTIN_HUGE_VALQ, "__builtin_huge_valq",
-	      RS6000_BTM_FLOAT128, RS6000_BTC_CONST)
+BU_SPECIAL_X (FLOAT128_BUILTIN_SQRTF128_ODD,
+	      "__builtin_sqrtf128_round_to_odd",
+	      RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
+
+BU_SPECIAL_X (FLOAT128_BUILTIN_TRUNCF128_ODD,
+	      "__builtin_truncf128_round_to_odd",
+	      RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
+
+BU_SPECIAL_X (FLOAT128_BUILTIN_ADDF128_ODD,
+	      "__builtin_addf128_round_to_odd",
+	      RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
+
+BU_SPECIAL_X (FLOAT128_BUILTIN_SUBF128_ODD,
+	      "__builtin_subf128_round_to_odd",
+	      RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
+
+BU_SPECIAL_X (FLOAT128_BUILTIN_MULF128_ODD,
+	      "__builtin_mulf128_round_to_odd",
+	      RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
+
+BU_SPECIAL_X (FLOAT128_BUILTIN_DIVF128_ODD,
+	      "__builtin_divf128_round_to_odd",
+	      RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
+
+BU_SPECIAL_X (FLOAT128_BUILTIN_FMAF128_ODD,
+	      "__builtin_fmaf128_round_to_odd",
+	      RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
 
 /* Darwin CfString builtin.  */
 BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 254357)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -683,6 +683,17 @@  rs6000_cpu_cpp_builtins (cpp_reader *pfi
       builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp");
     }
 
+  /* Map the old _Float128 'q' builtins into the new 'f128' builtins.  */
+  if (TARGET_FLOAT128_TYPE)
+    {
+      builtin_define ("__builtin_fabsq=__builtin_fabsf128");
+      builtin_define ("__builtin_copysignq=__builtin_copysignf128");
+      builtin_define ("__builtin_nanq=__builtin_nanf128");
+      builtin_define ("__builtin_nansq=__builtin_nansf128");
+      builtin_define ("__builtin_infq=__builtin_inff128");
+      builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
+    }
+
   /* Tell users they can use __builtin_bswap{16,64}.  */
   builtin_define ("__HAVE_BSWAP__");
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 254357)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -16109,39 +16109,11 @@  rs6000_invalid_builtin (enum rs6000_buil
    from ia64.c.  */
 
 static tree
-rs6000_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
-		     tree *args, bool ignore ATTRIBUTE_UNUSED)
+rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
+		     int n_args  ATTRIBUTE_UNUSED,
+		     tree *args  ATTRIBUTE_UNUSED,
+		     bool ignore ATTRIBUTE_UNUSED)
 {
-  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
-    {
-      enum rs6000_builtins fn_code
-	= (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
-      switch (fn_code)
-	{
-	case RS6000_BUILTIN_NANQ:
-	case RS6000_BUILTIN_NANSQ:
-	  {
-	    tree type = TREE_TYPE (TREE_TYPE (fndecl));
-	    const char *str = c_getstr (*args);
-	    int quiet = fn_code == RS6000_BUILTIN_NANQ;
-	    REAL_VALUE_TYPE real;
-
-	    if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
-	      return build_real (type, real);
-	    return NULL_TREE;
-	  }
-	case RS6000_BUILTIN_INFQ:
-	case RS6000_BUILTIN_HUGE_VALQ:
-	  {
-	    tree type = TREE_TYPE (TREE_TYPE (fndecl));
-	    REAL_VALUE_TYPE inf;
-	    real_inf (&inf);
-	    return build_real (type, inf);
-	  }
-	default:
-	  break;
-	}
-    }
 #ifdef SUBTARGET_FOLD_BUILTIN
   return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
 #else
@@ -16773,6 +16745,41 @@  rs6000_expand_builtin (tree exp, rtx tar
     case RS6000_BUILTIN_CPU_SUPPORTS:
       return cpu_expand_builtin (fcode, exp, target);
 
+    case FLOAT128_BUILTIN_SQRTF128_ODD:
+      return rs6000_expand_unop_builtin (TARGET_IEEEQUAD
+					 ? CODE_FOR_sqrttf2_odd
+					 : CODE_FOR_sqrtkf2_odd, exp, target);
+
+    case FLOAT128_BUILTIN_TRUNCF128_ODD:
+      return rs6000_expand_unop_builtin (TARGET_IEEEQUAD
+					  ? CODE_FOR_trunctfdf2_odd
+					  : CODE_FOR_trunckfdf2_odd, exp, target);
+
+    case FLOAT128_BUILTIN_ADDF128_ODD:
+      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
+					  ? CODE_FOR_addtf3_odd
+					  : CODE_FOR_addkf3_odd, exp, target);
+
+    case FLOAT128_BUILTIN_SUBF128_ODD:
+      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
+					  ? CODE_FOR_subtf3_odd
+					  : CODE_FOR_subkf3_odd, exp, target);
+
+    case FLOAT128_BUILTIN_MULF128_ODD:
+      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
+					  ? CODE_FOR_multf3_odd
+					  : CODE_FOR_mulkf3_odd, exp, target);
+
+    case FLOAT128_BUILTIN_DIVF128_ODD:
+      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
+					  ? CODE_FOR_divtf3_odd
+					  : CODE_FOR_divkf3_odd, exp, target);
+
+    case FLOAT128_BUILTIN_FMAF128_ODD:
+      return rs6000_expand_ternop_builtin (TARGET_IEEEQUAD
+					   ? CODE_FOR_fmatf4_odd
+					   : CODE_FOR_fmakf4_odd, exp, target);
+
     case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
     case ALTIVEC_BUILTIN_MASK_FOR_STORE:
       {
@@ -17102,15 +17109,6 @@  rs6000_init_builtins (void)
   if (TARGET_EXTRA_BUILTINS || TARGET_PAIRED_FLOAT)
     rs6000_common_init_builtins ();
 
-  ftype = build_function_type_list (ieee128_float_type_node,
-				    const_str_type_node, NULL_TREE);
-  def_builtin ("__builtin_nanq", ftype, RS6000_BUILTIN_NANQ);
-  def_builtin ("__builtin_nansq", ftype, RS6000_BUILTIN_NANSQ);
-
-  ftype = build_function_type_list (ieee128_float_type_node, NULL_TREE);
-  def_builtin ("__builtin_infq", ftype, RS6000_BUILTIN_INFQ);
-  def_builtin ("__builtin_huge_valq", ftype, RS6000_BUILTIN_HUGE_VALQ);
-
   ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
 				 RS6000_BUILTIN_RECIP, "__builtin_recipdiv");
   def_builtin ("__builtin_recipdiv", ftype, RS6000_BUILTIN_RECIP);
@@ -17160,6 +17158,32 @@  rs6000_init_builtins (void)
   def_builtin ("__builtin_cpu_is", ftype, RS6000_BUILTIN_CPU_IS);
   def_builtin ("__builtin_cpu_supports", ftype, RS6000_BUILTIN_CPU_SUPPORTS);
 
+  ftype = build_function_type_list (ieee128_float_type_node,
+				    ieee128_float_type_node, NULL_TREE);
+  def_builtin ("__builtin_sqrtf128_round_to_odd", ftype,
+	       FLOAT128_BUILTIN_SQRTF128_ODD);
+  def_builtin ("__builtin_truncf128_round_to_odd", ftype,
+	       FLOAT128_BUILTIN_TRUNCF128_ODD);
+
+  ftype = build_function_type_list (ieee128_float_type_node,
+				    ieee128_float_type_node,
+				    ieee128_float_type_node, NULL_TREE);
+  def_builtin ("__builtin_addf128_round_to_odd", ftype,
+	       FLOAT128_BUILTIN_ADDF128_ODD);
+  def_builtin ("__builtin_subf128_round_to_odd", ftype,
+	       FLOAT128_BUILTIN_SUBF128_ODD);
+  def_builtin ("__builtin_mulf128_round_to_odd", ftype,
+	       FLOAT128_BUILTIN_MULF128_ODD);
+  def_builtin ("__builtin_divf128_round_to_odd", ftype,
+	       FLOAT128_BUILTIN_DIVF128_ODD);
+
+  ftype = build_function_type_list (ieee128_float_type_node,
+				    ieee128_float_type_node,
+				    ieee128_float_type_node,
+				    ieee128_float_type_node, NULL_TREE);
+  def_builtin ("__builtin_fmaf128_round_to_odd", ftype,
+	       FLOAT128_BUILTIN_FMAF128_ODD);
+
   /* AIX libm provides clog as __clog.  */
   if (TARGET_XCOFF &&
       (tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 254357)
+++ gcc/doc/extend.texi	(working copy)
@@ -15547,36 +15547,19 @@  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.
+Previous versions of GCC supported some 'q' builtins for IEEE 128-bit
+floating point.  These functions are now mapped into the equivalent
+'f128' builtin functions.
 
 @smallexample
-__float128 __builtin_fabsq (__float128)
-__float128 __builtin_copysignq (__float128, __float128)
+__builtin_fabsq is mapped into __builtin_fabsf128
+__builtin_copysignq is mapped into __builtin_copysignf128
+__builtin_infq is mapped into __builtin_inff128
+__builtin_huge_valq is mapped into __builtin_huge_valf128
+__builtin_nanq is mapped into __builtin_nanf128
+__builtin_nansq is mapped into __builtin_nansf128
 @end smallexample
 
-The following built-in functions are available with @code{-mfloat128}
-and Altivec support.
-
-@table @code
-@item __float128 __builtin_infq (void)
-Similar to @code{__builtin_inf}, except the return type is @code{__float128}.
-@findex __builtin_infq
-
-@item __float128 __builtin_huge_valq (void)
-Similar to @code{__builtin_huge_val}, except the return type is @code{__float128}.
-@findex __builtin_huge_valq
-
-@item __float128 __builtin_nanq (void)
-Similar to @code{__builtin_nan}, except the return type is @code{__float128}.
-@findex __builtin_nanq
-
-@item __float128 __builtin_nansq (void)
-Similar to @code{__builtin_nans}, except the return type is @code{__float128}.
-@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.
 
Index: gcc/testsuite/gcc.target/powerpc/pr82748-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr82748-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr82748-1.c	(revision 0)
@@ -0,0 +1,82 @@ 
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -mabi=ieeelongdouble -Wno-psabi" } */
+
+/* Make sure the old 'q' builtin functions work correctly when the long double
+   default has been changed to be IEEE 128-bit floating point.  */
+
+_Float128
+do_fabs_f (_Float128 a)
+{
+  return __builtin_fabsq (a);
+}
+
+_Float128
+do_copysign_f (_Float128 a, _Float128 b)
+{
+  return __builtin_copysignq (a, b);
+}
+
+_Float128
+do_inf_f (void)
+{
+  return __builtin_infq ();
+}
+
+_Float128
+do_nan_f (void)
+{
+  return __builtin_nanq ("");
+}
+
+_Float128
+do_nans_f (void)
+{
+  return __builtin_nansq ("");
+}
+
+_Float128
+do_huge_val_f (void)
+{
+  return __builtin_huge_valq ();
+}
+
+long double
+do_fabs_ld (long double a)
+{
+  return __builtin_fabsq (a);
+}
+
+long double
+do_copysign_ld (long double a, long double b)
+{
+  return __builtin_copysignq (a, b);
+}
+
+long double
+do_inf_ld (void)
+{
+  return __builtin_infq ();
+}
+
+long double
+do_nan_ld (void)
+{
+  return __builtin_nanq ("");
+}
+
+long double
+do_nans_ld (void)
+{
+  return __builtin_nansq ("");
+}
+
+long double
+do_huge_val_ld (void)
+{
+  return __builtin_huge_valq ();
+}
+
+/* { dg-final { scan-assembler     {\mxsabsqp\M}   } } */
+/* { dg-final { scan-assembler     {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} }      } */
Index: gcc/testsuite/gcc.target/powerpc/pr82748-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr82748-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr82748-2.c	(revision 0)
@@ -0,0 +1,46 @@ 
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -mabi=ibmlongdouble -Wno-psabi" } */
+
+/* Make sure the old 'q' builtin functions work correctly when the long double
+   default uses the IBM double-double format.  */
+
+_Float128
+do_fabs (_Float128 a)
+{
+  return __builtin_fabsq (a);
+}
+
+_Float128
+do_copysign (_Float128 a, _Float128 b)
+{
+  return __builtin_copysignq (a, b);
+}
+
+_Float128
+do_inf (void)
+{
+  return __builtin_infq ();
+}
+
+_Float128
+do_nan (void)
+{
+  return __builtin_nanq ("");
+}
+
+_Float128
+do_nans (void)
+{
+  return __builtin_nansq ("");
+}
+
+_Float128
+do_huge_val (void)
+{
+  return __builtin_huge_valq ();
+}
+
+/* { dg-final { scan-assembler     {\mxsabsqp\M}   } } */
+/* { dg-final { scan-assembler     {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} }      } */