On Fri, Aug 19, 2016 at 10:57 PM, Joseph Myers <jos...@codesourcery.com> wrote:
> [Version 2 of this patch updates the testcases to use dg-add-options as in
> the final version of the _FloatN patch that went in; there are no changes
> of substance outside the testsuite.  Version 1 was
> <https://gcc.gnu.org/ml/gcc-patches/2016-06/msg01702.html>.]
>
>
> This patch adds a minimal set of built-in functions for the new
> _FloatN and _FloatNx types.
>
> The functions added are __builtin_fabs*, __builtin_copysign*,
> __builtin_huge_val*, __builtin_inf*, __builtin_nan* and
> __builtin_nans* (where * = fN or fNx).  That is, 42 new entries are
> added to the enum of built-in functions and the associated array of
> decls, where not all of them are actually supported on any one target.
>
> These functions are believed to be sufficient for libgcc (complex
> multiplication and division use __builtin_huge_val*,
> __builtin_copysign* and __builtin_fabs*) and for glibc (which also
> depends on complex multiplication from libgcc, as well as using such
> functions itself).  The basic target-independent support for folding /
> expanding calls to these built-in functions is wired up, so those for
> constants can be used in static initializers, and the fabs and
> copysign built-ins can always be expanded to bit-manipulation inline
> (for any format setting signbit_ro and signbit_rw, which covers all
> formats supported for _FloatN and _FloatNx), although insn patterns
> for fabs (abs<mode>2) and copysign (copysign<mode>3) will be used when
> available and may result in more optimal code.
>
> The complex multiplication and division functions in libgcc rely on
> predefined macros (defined with -fbuilding-libgcc) to say what the
> built-in function suffixes to use with a particular mode are.  This
> patch updates that code accordingly, where previously it involved a
> hack supposing that machine-specific suffixes for constants were also
> suffixes for built-in functions.
>
> As with the main _FloatN / _FloatNx patch, this patch does not update
> code dealing only with optimizations that currently has cases only
> covering float, double and long double, though some such cases are
> straightforward and may be covered in a followup patch.
>
> The functions are defined with DEF_GCC_BUILTIN, so calls to the TS
> 18661-3 functions such as fabsf128 and copysignf128, without the
> __builtin_, will not be optimized.  As noted in the original _FloatN /
> _FloatNx patch submission, in principle the bulk of the libm functions
> that have built-in versions should have those versions extended to
> cover the new types, but that would require more consideration of the
> effects of increasing the size of the enum and initializing many more
> functions at startup.
>
> I don't know whether target-specific built-in functions can readily be
> made into aliases for target-independent functions, but if they can,
> it would make sense to do so for the x86, ia64 and rs6000 *q functions
> corresponding to these, so that they can benefit from the
> architecture-independent folding logic and from any optimizations
> enabled for these functions in future, and so that less
> target-specific code is needed to support them.
>
> Bootstrapped with no regressions on x86_64-pc-linux-gnu.  OK to
> commit (the non-C-front-end parts)?

Ok.

I guess for the future we might want to consider building builtin trees
on-demand (though the interesting part would be to still feed the
frontends bindings to make name-lookup work...)

Thanks,
Richard.

> gcc:
> 2016-08-19  Joseph Myers  <jos...@codesourcery.com>
>
>         * tree.h (CASE_FLT_FN_FLOATN_NX, float16_type_node)
>         (float32_type_node, float64_type_node, float32x_type_node)
>         (float128x_type_node): New macros.
>         * builtin-types.def (BT_FLOAT16, BT_FLOAT32, BT_FLOAT64)
>         (BT_FLOAT128, BT_FLOAT32X, BT_FLOAT64X, BT_FLOAT128X)
>         (BT_FN_FLOAT16, BT_FN_FLOAT32, BT_FN_FLOAT64, BT_FN_FLOAT128)
>         (BT_FN_FLOAT32X, BT_FN_FLOAT64X, BT_FN_FLOAT128X)
>         (BT_FN_FLOAT16_FLOAT16, BT_FN_FLOAT32_FLOAT32)
>         (BT_FN_FLOAT64_FLOAT64, BT_FN_FLOAT128_FLOAT128)
>         (BT_FN_FLOAT32X_FLOAT32X, BT_FN_FLOAT64X_FLOAT64X)
>         (BT_FN_FLOAT128X_FLOAT128X, BT_FN_FLOAT16_CONST_STRING)
>         (BT_FN_FLOAT32_CONST_STRING, BT_FN_FLOAT64_CONST_STRING)
>         (BT_FN_FLOAT128_CONST_STRING, BT_FN_FLOAT32X_CONST_STRING)
>         (BT_FN_FLOAT64X_CONST_STRING, BT_FN_FLOAT128X_CONST_STRING)
>         (BT_FN_FLOAT16_FLOAT16_FLOAT16, BT_FN_FLOAT32_FLOAT32_FLOAT32)
>         (BT_FN_FLOAT64_FLOAT64_FLOAT64, BT_FN_FLOAT128_FLOAT128_FLOAT128)
>         (BT_FN_FLOAT32X_FLOAT32X_FLOAT32X)
>         (BT_FN_FLOAT64X_FLOAT64X_FLOAT64X)
>         (BT_FN_FLOAT128X_FLOAT128X_FLOAT128X): New type definitions.
>         * builtins.def (DEF_GCC_FLOATN_NX_BUILTINS): New macro.
>         (copysign, fabs, huge_val, inf, nan, nans): Use it.
>         * builtins.c (expand_builtin): Use CASE_FLT_FN_FLOATN_NX for fabs
>         and copysign.
>         (fold_builtin_0): Use CASE_FLT_FN_FLOATN_NX for inf and huge_val.
>         (fold_builtin_1): Use CASE_FLT_FN_FLOATN_NX for fabs.
>         * doc/extend.texi (Other Builtins): Document these built-in
>         functions.
>         * fold-const-call.c (fold_const_call): Use CASE_FLT_FN_FLOATN_NX
>         for nan and nans.
>
> gcc/c-family:
> 2016-08-19  Joseph Myers  <jos...@codesourcery.com>
>
>         * c-family/c-cppbuiltin.c (c_cpp_builtins): Check _FloatN and
>         _FloatNx types for suffixes for built-in functions.
>
> gcc/testsuite:
> 2016-08-19  Joseph Myers  <jos...@codesourcery.com>
>
>         * gcc.dg/torture/float128-builtin.c,
>         gcc.dg/torture/float128-ieee-nan.c,
>         gcc.dg/torture/float128x-builtin.c,
>         gcc.dg/torture/float128x-nan.c, gcc.dg/torture/float16-builtin.c,
>         gcc.dg/torture/float16-nan.c, gcc.dg/torture/float32-builtin.c,
>         gcc.dg/torture/float32-nan.c, gcc.dg/torture/float32x-builtin.c,
>         gcc.dg/torture/float32x-nan.c, gcc.dg/torture/float64-builtin.c,
>         gcc.dg/torture/float64-nan.c, gcc.dg/torture/float64x-builtin.c,
>         gcc.dg/torture/float64x-nan.c, gcc.dg/torture/floatn-builtin.h,
>         gcc.dg/torture/floatn-nan.h: New tests.
>
> Index: gcc/builtin-types.def
> ===================================================================
> --- gcc/builtin-types.def       (revision 239628)
> +++ gcc/builtin-types.def       (working copy)
> @@ -76,6 +76,27 @@ DEF_PRIMITIVE_TYPE (BT_UNWINDWORD, (*lang_hooks.ty
>  DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node)
>  DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node)
>  DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node)
> +DEF_PRIMITIVE_TYPE (BT_FLOAT16, (float16_type_node
> +                                ? float16_type_node
> +                                : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_FLOAT32, (float32_type_node
> +                                ? float32_type_node
> +                                : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_FLOAT64, (float64_type_node
> +                                ? float64_type_node
> +                                : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_FLOAT128, (float128_type_node
> +                                 ? float128_type_node
> +                                 : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_FLOAT32X, (float32x_type_node
> +                                 ? float32x_type_node
> +                                 : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_FLOAT64X, (float64x_type_node
> +                                 ? float64x_type_node
> +                                 : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_FLOAT128X, (float128x_type_node
> +                                  ? float128x_type_node
> +                                  : error_mark_node))
>  DEF_PRIMITIVE_TYPE (BT_COMPLEX_FLOAT, complex_float_type_node)
>  DEF_PRIMITIVE_TYPE (BT_COMPLEX_DOUBLE, complex_double_type_node)
>  DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONGDOUBLE, complex_long_double_type_node)
> @@ -146,6 +167,13 @@ DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
>     distinguish it from two types in sequence, "long" followed by
>     "double".  */
>  DEF_FUNCTION_TYPE_0 (BT_FN_LONGDOUBLE, BT_LONGDOUBLE)
> +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT16, BT_FLOAT16)
> +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT32, BT_FLOAT32)
> +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT64, BT_FLOAT64)
> +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT128, BT_FLOAT128)
> +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT32X, BT_FLOAT32X)
> +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT64X, BT_FLOAT64X)
> +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT128X, BT_FLOAT128X)
>  DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT32, BT_DFLOAT32)
>  DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT64, BT_DFLOAT64)
>  DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT128, BT_DFLOAT128)
> @@ -157,6 +185,13 @@ DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_FLOAT, BT_FLOAT,
>  DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_DOUBLE, BT_DOUBLE, BT_DOUBLE)
>  DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_LONGDOUBLE,
>                      BT_LONGDOUBLE, BT_LONGDOUBLE)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT16_FLOAT16, BT_FLOAT16, BT_FLOAT16)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32_FLOAT32, BT_FLOAT32, BT_FLOAT32)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64_FLOAT64, BT_FLOAT64, BT_FLOAT64)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128_FLOAT128, BT_FLOAT128, BT_FLOAT128)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32X_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64X_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128X_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
>  DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
>                      BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
>  DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
> @@ -208,6 +243,13 @@ DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_
>  DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
>  DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_CONST_STRING,
>                      BT_LONGDOUBLE, BT_CONST_STRING)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT16_CONST_STRING, BT_FLOAT16, BT_CONST_STRING)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32_CONST_STRING, BT_FLOAT32, BT_CONST_STRING)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64_CONST_STRING, BT_FLOAT64, BT_CONST_STRING)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128_CONST_STRING, BT_FLOAT128, 
> BT_CONST_STRING)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32X_CONST_STRING, BT_FLOAT32X, 
> BT_CONST_STRING)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64X_CONST_STRING, BT_FLOAT64X, 
> BT_CONST_STRING)
> +DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128X_CONST_STRING, BT_FLOAT128X, 
> BT_CONST_STRING)
>  DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_CONST_STRING, BT_DFLOAT32, 
> BT_CONST_STRING)
>  DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_CONST_STRING, BT_DFLOAT64, 
> BT_CONST_STRING)
>  DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_CONST_STRING,
> @@ -271,6 +313,20 @@ DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLE,
>                      BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
>  DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
>                      BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
> +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT16_FLOAT16_FLOAT16,
> +                    BT_FLOAT16, BT_FLOAT16, BT_FLOAT16)
> +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT32_FLOAT32_FLOAT32,
> +                    BT_FLOAT32, BT_FLOAT32, BT_FLOAT32)
> +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT64_FLOAT64_FLOAT64,
> +                    BT_FLOAT64, BT_FLOAT64, BT_FLOAT64)
> +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT128_FLOAT128_FLOAT128,
> +                    BT_FLOAT128, BT_FLOAT128, BT_FLOAT128)
> +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT32X_FLOAT32X_FLOAT32X,
> +                    BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
> +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT64X_FLOAT64X_FLOAT64X,
> +                    BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
> +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT128X_FLOAT128X_FLOAT128X,
> +                    BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
>  DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOATPTR,
>                      BT_FLOAT, BT_FLOAT, BT_FLOAT_PTR)
>  DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLEPTR,
> Index: gcc/builtins.c
> ===================================================================
> --- gcc/builtins.c      (revision 239628)
> +++ gcc/builtins.c      (working copy)
> @@ -5874,6 +5874,7 @@ expand_builtin (tree exp, rtx target, rtx subtarge
>    switch (fcode)
>      {
>      CASE_FLT_FN (BUILT_IN_FABS):
> +    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
>      case BUILT_IN_FABSD32:
>      case BUILT_IN_FABSD64:
>      case BUILT_IN_FABSD128:
> @@ -5883,6 +5884,7 @@ expand_builtin (tree exp, rtx target, rtx subtarge
>        break;
>
>      CASE_FLT_FN (BUILT_IN_COPYSIGN):
> +    CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
>        target = expand_builtin_copysign (exp, target, subtarget);
>        if (target)
>         return target;
> @@ -8207,6 +8209,7 @@ fold_builtin_0 (location_t loc, tree fndecl)
>        return fold_builtin_LINE (loc, type);
>
>      CASE_FLT_FN (BUILT_IN_INF):
> +    CASE_FLT_FN_FLOATN_NX (BUILT_IN_INF):
>      case BUILT_IN_INFD32:
>      case BUILT_IN_INFD64:
>      case BUILT_IN_INFD128:
> @@ -8213,6 +8216,7 @@ fold_builtin_0 (location_t loc, tree fndecl)
>        return fold_builtin_inf (loc, type, true);
>
>      CASE_FLT_FN (BUILT_IN_HUGE_VAL):
> +    CASE_FLT_FN_FLOATN_NX (BUILT_IN_HUGE_VAL):
>        return fold_builtin_inf (loc, type, false);
>
>      case BUILT_IN_CLASSIFY_TYPE:
> @@ -8261,6 +8265,7 @@ fold_builtin_1 (location_t loc, tree fndecl, tree
>        return fold_builtin_strlen (loc, type, arg0);
>
>      CASE_FLT_FN (BUILT_IN_FABS):
> +    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
>      case BUILT_IN_FABSD32:
>      case BUILT_IN_FABSD64:
>      case BUILT_IN_FABSD128:
> Index: gcc/builtins.def
> ===================================================================
> --- gcc/builtins.def    (revision 239628)
> +++ gcc/builtins.def    (working copy)
> @@ -87,6 +87,19 @@ along with GCC; see the file COPYING3.  If not see
>    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST,     \
>                false, false, false, ATTRS, true, 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.  */
> +#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)
> +
>  /* 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,
> @@ -296,6 +309,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILL, "ceill", B
>  DEF_C99_BUILTIN        (BUILT_IN_COPYSIGN, "copysign", 
> BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
>  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)
> +#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)
>  DEF_LIB_BUILTIN        (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, 
> ATTR_MATHFN_FPROUNDING_ERRNO)
> @@ -326,6 +342,9 @@ DEF_C99_BUILTIN        (BUILT_IN_EXPM1L, "expm1l",
>  DEF_LIB_BUILTIN        (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  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)
> +#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)
>  DEF_GCC_BUILTIN        (BUILT_IN_FABSD128, "fabsd128", 
> BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
> @@ -359,6 +378,8 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_GAMMAL_R, "gammal
>  DEF_GCC_BUILTIN        (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_GCC_BUILTIN        (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_GCC_BUILTIN        (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
> +#define INF_TYPE(F) BT_FN_##F
> +DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_HUGE_VAL, "huge_val", INF_TYPE, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_C99_BUILTIN        (BUILT_IN_HYPOT, "hypot", BT_FN_DOUBLE_DOUBLE_DOUBLE, 
> ATTR_MATHFN_FPROUNDING_ERRNO)
>  DEF_C99_BUILTIN        (BUILT_IN_HYPOTF, "hypotf", BT_FN_FLOAT_FLOAT_FLOAT, 
> ATTR_MATHFN_FPROUNDING_ERRNO)
>  DEF_C99_BUILTIN        (BUILT_IN_HYPOTL, "hypotl", 
> BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
> @@ -374,6 +395,8 @@ DEF_C99_BUILTIN        (BUILT_IN_ILOGBL, "ilogbl",
>  DEF_GCC_BUILTIN        (BUILT_IN_INF, "inf", BT_FN_DOUBLE, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_GCC_BUILTIN        (BUILT_IN_INFF, "inff", BT_FN_FLOAT, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_GCC_BUILTIN        (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_INF, "inf", INF_TYPE, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
> +#undef INF_TYPE
>  DEF_GCC_BUILTIN               (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_GCC_BUILTIN        (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_GCC_BUILTIN        (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, 
> ATTR_CONST_NOTHROW_LEAF_LIST)
> @@ -446,6 +469,8 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", B
>  DEF_C99_BUILTIN        (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, 
> ATTR_CONST_NOTHROW_NONNULL)
>  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_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)
> @@ -452,6 +477,8 @@ DEF_GCC_BUILTIN        (BUILT_IN_NAND128, "nand128
>  DEF_GCC_BUILTIN        (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, 
> ATTR_CONST_NOTHROW_NONNULL)
>  DEF_GCC_BUILTIN        (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, 
> ATTR_CONST_NOTHROW_NONNULL)
>  DEF_GCC_BUILTIN        (BUILT_IN_NANSL, "nansl", 
> BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
> +DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_NANS, "nans", NAN_TYPE, 
> ATTR_CONST_NOTHROW_NONNULL)
> +#undef NAN_TYPE
>  DEF_C99_BUILTIN        (BUILT_IN_NEARBYINT, "nearbyint", 
> BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_C99_BUILTIN        (BUILT_IN_NEARBYINTF, "nearbyintf", 
> BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
>  DEF_C99_BUILTIN        (BUILT_IN_NEARBYINTL, "nearbyintl", 
> BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
> Index: gcc/c-family/c-cppbuiltin.c
> ===================================================================
> --- gcc/c-family/c-cppbuiltin.c (revision 239628)
> +++ gcc/c-family/c-cppbuiltin.c (working copy)
> @@ -1095,24 +1095,27 @@ c_cpp_builtins (cpp_reader *pfile)
>           macro_name = (char *) alloca (strlen (name)
>                                         + sizeof ("__LIBGCC__FUNC_EXT__"));
>           sprintf (macro_name, "__LIBGCC_%s_FUNC_EXT__", name);
> -         const char *suffix;
> +         char suffix[20] = "";
>           if (mode == TYPE_MODE (double_type_node))
> -           suffix = "";
> +           ; /* Empty suffix correct.  */
>           else if (mode == TYPE_MODE (float_type_node))
> -           suffix = "f";
> +           suffix[0] = 'f';
>           else if (mode == TYPE_MODE (long_double_type_node))
> -           suffix = "l";
> -         /* ??? The following assumes the built-in functions (defined
> -            in target-specific code) match the suffixes used for
> -            constants.  Because in fact such functions are not
> -            defined for the 'w' suffix, 'l' is used there
> -            instead.  */
> -         else if (mode == targetm.c.mode_for_suffix ('q'))
> -           suffix = "q";
> -         else if (mode == targetm.c.mode_for_suffix ('w'))
> -           suffix = "l";
> +           suffix[0] = 'l';
>           else
> -           gcc_unreachable ();
> +           {
> +             bool found_suffix = false;
> +             for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
> +               if (FLOATN_NX_TYPE_NODE (i) != NULL_TREE
> +                   && mode == TYPE_MODE (FLOATN_NX_TYPE_NODE (i)))
> +                 {
> +                   sprintf (suffix, "f%d%s", floatn_nx_types[i].n,
> +                            floatn_nx_types[i].extended ? "x" : "");
> +                   found_suffix = true;
> +                   break;
> +                 }
> +             gcc_assert (found_suffix);
> +           }
>           builtin_define_with_value (macro_name, suffix, 0);
>           bool excess_precision = false;
>           if (TARGET_FLT_EVAL_METHOD != 0
> Index: gcc/doc/extend.texi
> ===================================================================
> --- gcc/doc/extend.texi (revision 239628)
> +++ gcc/doc/extend.texi (working copy)
> @@ -10856,6 +10856,13 @@ that are recognized in any mode since ISO C90 rese
>  the purpose to which ISO C99 puts them.  All these functions have
>  corresponding versions prefixed with @code{__builtin_}.
>
> +There are also built-in functions @code{__builtin_fabsf@var{n}},
> +@code{__builtin_fabsf@var{n}x}, @code{__builtin_copysignf@var{n}} and
> +@code{__builtin_copysignf@var{n}x}, corresponding to the TS 18661-3
> +functions @code{fabsf@var{n}}, @code{fabsf@var{n}x},
> +@code{copysignf@var{n}} and @code{copysignf@var{n}x}, for supported
> +types @code{_Float@var{n}} and @code{_Float@var{n}x}.
> +
>  There are also GNU extension functions @code{clog10}, @code{clog10f} and
>  @code{clog10l} which names are reserved by ISO C99 for future use.
>  All these functions have versions prefixed with @code{__builtin_}.
> @@ -11394,6 +11401,16 @@ Similar to @code{__builtin_huge_val}, except the r
>  type is @code{long double}.
>  @end deftypefn
>
> +@deftypefn {Built-in Function} _Float@var{n} __builtin_huge_valf@var{n} 
> (void)
> +Similar to @code{__builtin_huge_val}, except the return type is
> +@code{_Float@var{n}}.
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} _Float@var{n}x __builtin_huge_valf@var{n}x 
> (void)
> +Similar to @code{__builtin_huge_val}, except the return type is
> +@code{_Float@var{n}x}.
> +@end deftypefn
> +
>  @deftypefn {Built-in Function} int __builtin_fpclassify (int, int, int, int, 
> int, ...)
>  This built-in implements the C99 fpclassify functionality.  The first
>  five int arguments should be the target library's notion of the
> @@ -11432,6 +11449,16 @@ Similar to @code{__builtin_inf}, except the return
>  type is @code{long double}.
>  @end deftypefn
>
> +@deftypefn {Built-in Function} _Float@var{n} __builtin_inff@var{n} (void)
> +Similar to @code{__builtin_inf}, except the return
> +type is @code{_Float@var{n}}.
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} _Float@var{n} __builtin_inff@var{n}x (void)
> +Similar to @code{__builtin_inf}, except the return
> +type is @code{_Float@var{n}x}.
> +@end deftypefn
> +
>  @deftypefn {Built-in Function} int __builtin_isinf_sign (...)
>  Similar to @code{isinf}, except the return value is -1 for
>  an argument of @code{-Inf} and 1 for an argument of @code{+Inf}.
> @@ -11478,6 +11505,16 @@ Similar to @code{__builtin_nan}, except the return
>  Similar to @code{__builtin_nan}, except the return type is @code{long 
> double}.
>  @end deftypefn
>
> +@deftypefn {Built-in Function} _Float@var{n} __builtin_nanf@var{n} (const 
> char *str)
> +Similar to @code{__builtin_nan}, except the return type is
> +@code{_Float@var{n}}.
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} _Float@var{n}x __builtin_nanf@var{n}x (const 
> char *str)
> +Similar to @code{__builtin_nan}, except the return type is
> +@code{_Float@var{n}x}.
> +@end deftypefn
> +
>  @deftypefn {Built-in Function} double __builtin_nans (const char *str)
>  Similar to @code{__builtin_nan}, except the significand is forced
>  to be a signaling NaN@.  The @code{nans} function is proposed by
> @@ -11492,6 +11529,16 @@ Similar to @code{__builtin_nans}, except the retur
>  Similar to @code{__builtin_nans}, except the return type is @code{long 
> double}.
>  @end deftypefn
>
> +@deftypefn {Built-in Function} _Float@var{n} __builtin_nansf@var{n} (const 
> char *str)
> +Similar to @code{__builtin_nans}, except the return type is
> +@code{_Float@var{n}}.
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} _Float@var{n}x __builtin_nansf@var{n}x (const 
> char *str)
> +Similar to @code{__builtin_nans}, except the return type is
> +@code{_Float@var{n}x}.
> +@end deftypefn
> +
>  @deftypefn {Built-in Function} int __builtin_ffs (int x)
>  Returns one plus the index of the least significant 1-bit of @var{x}, or
>  if @var{x} is zero, returns zero.
> Index: gcc/fold-const-call.c
> ===================================================================
> --- gcc/fold-const-call.c       (revision 239628)
> +++ gcc/fold-const-call.c       (working copy)
> @@ -1131,6 +1131,7 @@ fold_const_call (combined_fn fn, tree type, tree a
>        return NULL_TREE;
>
>      CASE_CFN_NAN:
> +    CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
>      case CFN_BUILT_IN_NAND32:
>      case CFN_BUILT_IN_NAND64:
>      case CFN_BUILT_IN_NAND128:
> @@ -1137,6 +1138,7 @@ fold_const_call (combined_fn fn, tree type, tree a
>        return fold_const_builtin_nan (type, arg, true);
>
>      CASE_CFN_NANS:
> +    CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
>        return fold_const_builtin_nan (type, arg, false);
>
>      default:
> Index: gcc/testsuite/gcc.dg/torture/float128-builtin.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float128-builtin.c     (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float128-builtin.c     (working copy)
> @@ -0,0 +1,9 @@
> +/* Test _Float128 built-in functions.  */
> +/* { dg-do run } */
> +/* { dg-options "" } */
> +/* { dg-add-options float128 } */
> +/* { dg-require-effective-target float128_runtime } */
> +
> +#define WIDTH 128
> +#define EXT 0
> +#include "floatn-builtin.h"
> Index: gcc/testsuite/gcc.dg/torture/float128-ieee-nan.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float128-ieee-nan.c    (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float128-ieee-nan.c    (working copy)
> @@ -0,0 +1,10 @@
> +/* Test _Float128 NaNs.  */
> +/* { dg-do run } */
> +/* { dg-options "-fsignaling-nans" } */
> +/* { dg-add-options float128 } */
> +/* { dg-require-effective-target float128_runtime } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#define WIDTH 128
> +#define EXT 0
> +#include "floatn-nan.h"
> Index: gcc/testsuite/gcc.dg/torture/float128x-builtin.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float128x-builtin.c    (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float128x-builtin.c    (working copy)
> @@ -0,0 +1,9 @@
> +/* Test _Float128x built-in functions.  */
> +/* { dg-do run } */
> +/* { dg-options "" } */
> +/* { dg-add-options float128x } */
> +/* { dg-require-effective-target float128x_runtime } */
> +
> +#define WIDTH 128
> +#define EXT 1
> +#include "floatn-builtin.h"
> Index: gcc/testsuite/gcc.dg/torture/float128x-nan.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float128x-nan.c        (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float128x-nan.c        (working copy)
> @@ -0,0 +1,10 @@
> +/* Test _Float128x NaNs.  */
> +/* { dg-do run } */
> +/* { dg-options "-fsignaling-nans" } */
> +/* { dg-add-options float128x } */
> +/* { dg-require-effective-target float128x_runtime } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#define WIDTH 128
> +#define EXT 1
> +#include "floatn-nan.h"
> Index: gcc/testsuite/gcc.dg/torture/float16-builtin.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float16-builtin.c      (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float16-builtin.c      (working copy)
> @@ -0,0 +1,9 @@
> +/* Test _Float16 built-in functions.  */
> +/* { dg-do run } */
> +/* { dg-options "" } */
> +/* { dg-add-options float16 } */
> +/* { dg-require-effective-target float16_runtime } */
> +
> +#define WIDTH 16
> +#define EXT 0
> +#include "floatn-builtin.h"
> Index: gcc/testsuite/gcc.dg/torture/float16-nan.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float16-nan.c  (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float16-nan.c  (working copy)
> @@ -0,0 +1,10 @@
> +/* Test _Float16 NaNs.  */
> +/* { dg-do run } */
> +/* { dg-options "-fsignaling-nans" } */
> +/* { dg-add-options float16 } */
> +/* { dg-require-effective-target float16_runtime } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#define WIDTH 16
> +#define EXT 0
> +#include "floatn-nan.h"
> Index: gcc/testsuite/gcc.dg/torture/float32-builtin.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float32-builtin.c      (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float32-builtin.c      (working copy)
> @@ -0,0 +1,9 @@
> +/* Test _Float32 built-in functions.  */
> +/* { dg-do run } */
> +/* { dg-options "" } */
> +/* { dg-add-options float32 } */
> +/* { dg-require-effective-target float32_runtime } */
> +
> +#define WIDTH 32
> +#define EXT 0
> +#include "floatn-builtin.h"
> Index: gcc/testsuite/gcc.dg/torture/float32-nan.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float32-nan.c  (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float32-nan.c  (working copy)
> @@ -0,0 +1,10 @@
> +/* Test _Float32 NaNs.  */
> +/* { dg-do run } */
> +/* { dg-options "-fsignaling-nans" } */
> +/* { dg-add-options float32 } */
> +/* { dg-require-effective-target float32_runtime } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#define WIDTH 32
> +#define EXT 0
> +#include "floatn-nan.h"
> Index: gcc/testsuite/gcc.dg/torture/float32x-builtin.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float32x-builtin.c     (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float32x-builtin.c     (working copy)
> @@ -0,0 +1,9 @@
> +/* Test _Float32x built-in functions.  */
> +/* { dg-do run } */
> +/* { dg-options "" } */
> +/* { dg-add-options float32x } */
> +/* { dg-require-effective-target float32x_runtime } */
> +
> +#define WIDTH 32
> +#define EXT 1
> +#include "floatn-builtin.h"
> Index: gcc/testsuite/gcc.dg/torture/float32x-nan.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float32x-nan.c (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float32x-nan.c (working copy)
> @@ -0,0 +1,10 @@
> +/* Test _Float32x NaNs.  */
> +/* { dg-do run } */
> +/* { dg-options "-fsignaling-nans" } */
> +/* { dg-add-options float32x } */
> +/* { dg-require-effective-target float32x_runtime } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#define WIDTH 32
> +#define EXT 1
> +#include "floatn-nan.h"
> Index: gcc/testsuite/gcc.dg/torture/float64-builtin.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float64-builtin.c      (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float64-builtin.c      (working copy)
> @@ -0,0 +1,9 @@
> +/* Test _Float64 built-in functions.  */
> +/* { dg-do run } */
> +/* { dg-options "" } */
> +/* { dg-add-options float64 } */
> +/* { dg-require-effective-target float64_runtime } */
> +
> +#define WIDTH 64
> +#define EXT 0
> +#include "floatn-builtin.h"
> Index: gcc/testsuite/gcc.dg/torture/float64-nan.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float64-nan.c  (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float64-nan.c  (working copy)
> @@ -0,0 +1,10 @@
> +/* Test _Float64 NaNs.  */
> +/* { dg-do run } */
> +/* { dg-options "-fsignaling-nans" } */
> +/* { dg-add-options float64 } */
> +/* { dg-require-effective-target float64_runtime } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#define WIDTH 64
> +#define EXT 0
> +#include "floatn-nan.h"
> Index: gcc/testsuite/gcc.dg/torture/float64x-builtin.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float64x-builtin.c     (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float64x-builtin.c     (working copy)
> @@ -0,0 +1,9 @@
> +/* Test _Float64x built-in functions.  */
> +/* { dg-do run } */
> +/* { dg-options "" } */
> +/* { dg-add-options float64x } */
> +/* { dg-require-effective-target float64x_runtime } */
> +
> +#define WIDTH 64
> +#define EXT 1
> +#include "floatn-builtin.h"
> Index: gcc/testsuite/gcc.dg/torture/float64x-nan.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/float64x-nan.c (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/float64x-nan.c (working copy)
> @@ -0,0 +1,10 @@
> +/* Test _Float64x NaNs.  */
> +/* { dg-do run } */
> +/* { dg-options "-fsignaling-nans" } */
> +/* { dg-add-options float64x } */
> +/* { dg-require-effective-target float64x_runtime } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#define WIDTH 64
> +#define EXT 1
> +#include "floatn-nan.h"
> Index: gcc/testsuite/gcc.dg/torture/floatn-builtin.h
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/floatn-builtin.h       (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/floatn-builtin.h       (working copy)
> @@ -0,0 +1,64 @@
> +/* Tests for _FloatN / _FloatNx types: compile and execution tests for
> +   built-in functions.  Before including this file, define WIDTH as
> +   the value N; define EXT to 1 for _FloatNx and 0 for _FloatN.  */
> +
> +#define CONCATX(X, Y) X ## Y
> +#define CONCAT(X, Y) CONCATX (X, Y)
> +#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
> +#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
> +
> +#if EXT
> +# define TYPE CONCAT3 (_Float, WIDTH, x)
> +# define CST(C) CONCAT4 (C, f, WIDTH, x)
> +# define FN(F) CONCAT4 (F, f, WIDTH, x)
> +#else
> +# define TYPE CONCAT (_Float, WIDTH)
> +# define CST(C) CONCAT3 (C, f, WIDTH)
> +# define FN(F) CONCAT3 (F, f, WIDTH)
> +#endif
> +
> +extern void exit (int);
> +extern void abort (void);
> +
> +extern TYPE test_type;
> +extern __typeof (FN (__builtin_inf) ()) test_type;
> +extern __typeof (FN (__builtin_huge_val) ()) test_type;
> +extern __typeof (FN (__builtin_nan) ("")) test_type;
> +extern __typeof (FN (__builtin_nans) ("")) test_type;
> +extern __typeof (FN (__builtin_fabs) (0)) test_type;
> +extern __typeof (FN (__builtin_copysign) (0, 0)) test_type;
> +
> +volatile TYPE inf_cst = FN (__builtin_inf) ();
> +volatile TYPE huge_val_cst = FN (__builtin_huge_val) ();
> +volatile TYPE nan_cst = FN (__builtin_nan) ("");
> +volatile TYPE nans_cst = FN (__builtin_nans) ("");
> +volatile TYPE neg0 = -CST (0.0), neg1 = -CST (1.0), one = 1.0;
> +
> +int
> +main (void)
> +{
> +  volatile TYPE r;
> +  if (!__builtin_isinf (inf_cst))
> +    abort ();
> +  if (!__builtin_isinf (huge_val_cst))
> +    abort ();
> +  if (inf_cst != huge_val_cst)
> +    abort ();
> +  if (!__builtin_isnan (nan_cst))
> +    abort ();
> +  if (!__builtin_isnan (nans_cst))
> +    abort ();
> +  r = FN (__builtin_fabs) (neg1);
> +  if (r != CST (1.0))
> +    abort ();
> +  r = FN (__builtin_copysign) (one, neg0);
> +  if (r != neg1)
> +    abort ();
> +  r = FN (__builtin_copysign) (inf_cst, neg1);
> +  if (r != -huge_val_cst)
> +    abort ();
> +  r = FN (__builtin_copysign) (-inf_cst, one);
> +  if (r != huge_val_cst)
> +    abort ();
> +  exit (0);
> +}
> Index: gcc/testsuite/gcc.dg/torture/floatn-nan.h
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/floatn-nan.h   (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/floatn-nan.h   (working copy)
> @@ -0,0 +1,39 @@
> +/* Tests for _FloatN / _FloatNx types: compile and execution tests for
> +   NaNs.  Before including this file, define WIDTH as the value N;
> +   define EXT to 1 for _FloatNx and 0 for _FloatN.  */
> +
> +#define CONCATX(X, Y) X ## Y
> +#define CONCAT(X, Y) CONCATX (X, Y)
> +#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
> +#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
> +
> +#if EXT
> +# define TYPE CONCAT3 (_Float, WIDTH, x)
> +# define CST(C) CONCAT4 (C, f, WIDTH, x)
> +# define FN(F) CONCAT4 (F, f, WIDTH, x)
> +#else
> +# define TYPE CONCAT (_Float, WIDTH)
> +# define CST(C) CONCAT3 (C, f, WIDTH)
> +# define FN(F) CONCAT3 (F, f, WIDTH)
> +#endif
> +
> +#include <fenv.h>
> +
> +extern void exit (int);
> +extern void abort (void);
> +
> +volatile TYPE nan_cst = FN (__builtin_nan) ("");
> +volatile TYPE nans_cst = FN (__builtin_nans) ("");
> +
> +int
> +main (void)
> +{
> +  volatile TYPE r;
> +  r = nan_cst + nan_cst;
> +  if (fetestexcept (FE_INVALID))
> +    abort ();
> +  r = nans_cst + nans_cst;
> +  if (!fetestexcept (FE_INVALID))
> +    abort ();
> +  exit (0);
> +}
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h  (revision 239628)
> +++ gcc/tree.h  (working copy)
> @@ -234,6 +234,9 @@ as_internal_fn (combined_fn code)
>  /* Helper macros for math builtins.  */
>
>  #define CASE_FLT_FN(FN) case FN: case FN##F: case FN##L
> +#define CASE_FLT_FN_FLOATN_NX(FN)                         \
> +  case FN##F16: case FN##F32: case FN##F64: case FN##F128: \
> +  case FN##F32X: case FN##F64X: case FN##F128X
>  #define CASE_FLT_FN_REENT(FN) case FN##_R: case FN##F_R: case FN##L_R
>  #define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL: case FN##IMAX
>
> @@ -3610,11 +3613,16 @@ tree_operand_check_code (const_tree __t, enum tree
>  #define FLOATN_NX_TYPE_NODE(IDX)       global_trees[TI_FLOATN_NX_TYPE_FIRST 
> + (IDX)]
>  #define FLOATNX_TYPE_NODE(IDX)         global_trees[TI_FLOATNX_TYPE_FIRST + 
> (IDX)]
>
> -/* Names for individual types, where required by back ends
> -   (architecture-independent code should always iterate over all such
> -   types).  */
> +/* Names for individual types (code should normally iterate over all
> +   such types; these are only for back-end use, or in contexts such as
> +   *.def where iteration is not possible).  */
> +#define float16_type_node              global_trees[TI_FLOAT16_TYPE]
> +#define float32_type_node              global_trees[TI_FLOAT32_TYPE]
> +#define float64_type_node              global_trees[TI_FLOAT64_TYPE]
>  #define float128_type_node             global_trees[TI_FLOAT128_TYPE]
> +#define float32x_type_node             global_trees[TI_FLOAT32X_TYPE]
>  #define float64x_type_node             global_trees[TI_FLOAT64X_TYPE]
> +#define float128x_type_node            global_trees[TI_FLOAT128X_TYPE]
>
>  #define float_ptr_type_node            global_trees[TI_FLOAT_PTR_TYPE]
>  #define double_ptr_type_node           global_trees[TI_DOUBLE_PTR_TYPE]
>
>
>
> --
> Joseph S. Myers
> jos...@codesourcery.com

Reply via email to