From aa8fdb441fe94e5527ec527b9cd752e67e040bdc Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Sun, 12 Jun 2016 19:22:16 +0200 Subject: [PATCH] re PR target/71241 ([x86] Missing built-in functions for float128 NaNs) PR target/71241 * config/i386/i386.i386-builtin-types.def (CONST_STRING): New primitive type. (FLOAT128_FTYPE_CONST_STRING): New function type. * config/i386/i386.c (enum ix86_builtins) [IX86_BUILTIN_NANQ]: New. [IX86_BUILTIN_NANSQ]: Ditto. (ix86_fold_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ. (ix86_init_builtin_types) Declare const_string_type_node. Add __builtin_nanq and __builtin_nansq builtin functions. (ix86_expand_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ. * doc/extend.texi (x86 Built-in Functions): Document __builtin_nanq and __builtin_nansq. testsuite/ChangeLog: PR target/71241 * testsuite/gcc.dg/torture/float128-nan.c: New test. From-SVN: r237338 --- gcc/ChangeLog | 35 +++++-- gcc/config/i386/i386-builtin-types.def | 2 + gcc/config/i386/i386.c | 47 ++++++++- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.dg/torture/float128-nan.c | 101 ++++++++++++++++++++ 5 files changed, 176 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/float128-nan.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6266fb35712..0a48316e0f9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2016-06-12 Uros Bizjak + + PR target/71241 + * config/i386/i386.i386-builtin-types.def (CONST_STRING): + New primitive type. + (FLOAT128_FTYPE_CONST_STRING): New function type. + * config/i386/i386.c (enum ix86_builtins) [IX86_BUILTIN_NANQ]: New. + [IX86_BUILTIN_NANSQ]: Ditto. + (ix86_fold_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ. + (ix86_init_builtin_types) Declare const_string_type_node. + Add __builtin_nanq and __builtin_nansq builtin functions. + (ix86_expand_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ. + * doc/extend.texi (x86 Built-in Functions): Document + __builtin_nanq and __builtin_nansq. + 2016-06-11 Jiong Wang PR target/71061 @@ -60,7 +75,7 @@ (fsm_find_control_statement_thread_paths): Avoid putting the same block on the thread path twice, but ensure the thread path is unchanged from the caller's point of view. - + 2016-06-10 Jan Hubicka * predict.c (predict_loops): Remove PRED_LOOP_BRANCH. @@ -144,21 +159,22 @@ Jiong Wang PR rtl-optimization/70751 - * lra-constraints.c (process_alt_operands): Recognize Non-pseudo spilled - into memory. + * lra-constraints.c (process_alt_operands): Recognize Non-pseudo + spilled into memory. -2016-06-09 Jonathan Yong <10walls@gmail.com> +2016-06-09 Jonathan Yong <10walls@gmail.com> Revert: 2015-09-21 Jonathan Yong <10walls@gmail.com> - * config/i386/cygwin.h (STARTFILE_SPEC): Explicitly search - sysroot/usr/lib/32api for additional win32 libraries, - fixes failing Cygwin bootstrapping. + + * config/i386/cygwin.h (STARTFILE_SPEC): Explicitly search + sysroot/usr/lib/32api for additional win32 libraries, + fixes failing Cygwin bootstrapping. 2016-06-09 Marcin Baczyński * diagnostic.h (diagnostic_line_cutoff, diagnostic_flush_buffer): - delete. + Delete. 2016-06-09 David Malcolm @@ -503,8 +519,7 @@ 2016-06-07 Kyrylo Tkachov - * simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local - variable. + * simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local variable. 2016-06-07 Jakub Jelinek diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index c66f65108f8..7eb6fc96e66 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -73,6 +73,7 @@ DEF_PRIMITIVE_TYPE (FLOAT, float_type_node) DEF_PRIMITIVE_TYPE (DOUBLE, double_type_node) DEF_PRIMITIVE_TYPE (FLOAT80, float80_type_node) DEF_PRIMITIVE_TYPE (FLOAT128, float128_type_node) +DEF_PRIMITIVE_TYPE (CONST_STRING, const_string_type_node) # MMX vectors DEF_VECTOR_TYPE (V2SF, FLOAT) @@ -191,6 +192,7 @@ DEF_FUNCTION_TYPE (PVOID) DEF_FUNCTION_TYPE (FLOAT, FLOAT) DEF_FUNCTION_TYPE (FLOAT128, FLOAT128) +DEF_FUNCTION_TYPE (FLOAT128, CONST_STRING) DEF_FUNCTION_TYPE (INT, INT) DEF_FUNCTION_TYPE (INT, V16QI) DEF_FUNCTION_TYPE (INT, V2DF) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b807a9a0004..dd47305c5b0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -32718,6 +32718,8 @@ enum ix86_builtins /* TFmode support builtins. */ IX86_BUILTIN_INFQ, IX86_BUILTIN_HUGE_VALQ, + IX86_BUILTIN_NANQ, + IX86_BUILTIN_NANSQ, IX86_BUILTIN_FABSQ, IX86_BUILTIN_COPYSIGNQ, @@ -38105,11 +38107,28 @@ ix86_fold_builtin (tree fndecl, int n_args, { enum ix86_builtins fn_code = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl); - if (fn_code == IX86_BUILTIN_CPU_IS - || fn_code == IX86_BUILTIN_CPU_SUPPORTS) + switch (fn_code) { + case IX86_BUILTIN_CPU_IS: + case IX86_BUILTIN_CPU_SUPPORTS: gcc_assert (n_args == 1); - return fold_builtin_cpu (fndecl, args); + return fold_builtin_cpu (fndecl, args); + + case IX86_BUILTIN_NANQ: + case IX86_BUILTIN_NANSQ: + { + tree type = TREE_TYPE (TREE_TYPE (fndecl)); + const char *str = c_getstr (*args); + int quiet = fn_code == IX86_BUILTIN_NANQ; + REAL_VALUE_TYPE real; + + if (str && real_nan (&real, str, quiet, TYPE_MODE (type))) + return build_real (type, real); + return NULL_TREE; + } + + default: + break; } } @@ -38210,7 +38229,7 @@ ix86_init_builtins_va_builtins_abi (void) static void ix86_init_builtin_types (void) { - tree float128_type_node, float80_type_node; + tree float128_type_node, float80_type_node, const_string_type_node; /* The __float80 type. */ float80_type_node = long_double_type_node; @@ -38230,6 +38249,10 @@ ix86_init_builtin_types (void) layout_type (float128_type_node); lang_hooks.types.register_builtin_type (float128_type_node, "__float128"); + const_string_type_node + = build_pointer_type (build_qualified_type + (char_type_node, TYPE_QUAL_CONST)); + /* This macro is built by i386-builtin-types.awk. */ DEFINE_BUILTIN_PRIMITIVE_TYPES; } @@ -38250,6 +38273,18 @@ ix86_init_builtins (void) def_builtin_const (0, "__builtin_huge_valq", FLOAT128_FTYPE_VOID, IX86_BUILTIN_HUGE_VALQ); + t = ix86_get_builtin_func_type (FLOAT128_FTYPE_CONST_STRING); + t = add_builtin_function ("__builtin_nanq", t, IX86_BUILTIN_NANQ, + BUILT_IN_MD, "nanq", NULL_TREE); + TREE_READONLY (t) = 1; + ix86_builtins[(int) IX86_BUILTIN_NANQ] = t; + + t = ix86_get_builtin_func_type (FLOAT128_FTYPE_CONST_STRING); + t = add_builtin_function ("__builtin_nansq", t, IX86_BUILTIN_NANSQ, + BUILT_IN_MD, "nansq", NULL_TREE); + TREE_READONLY (t) = 1; + ix86_builtins[(int) IX86_BUILTIN_NANSQ] = t; + /* We will expand them to normal call if SSE isn't available since they are used by libgcc. */ t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128); @@ -41463,6 +41498,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, return target; } + case IX86_BUILTIN_NANQ: + case IX86_BUILTIN_NANSQ: + return expand_call (exp, target, ignore); + case IX86_BUILTIN_RDPMC: case IX86_BUILTIN_RDTSC: case IX86_BUILTIN_RDTSCP: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 305af6b92f0..426c8ad1865 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-06-12 Uros Bizjak + + PR target/71241 + * testsuite/gcc.dg/torture/float128-nan.c: New test. + 2016-06-12 Dominique d'Humieres PR target/60751 diff --git a/gcc/testsuite/gcc.dg/torture/float128-nan.c b/gcc/testsuite/gcc.dg/torture/float128-nan.c new file mode 100644 index 00000000000..b5706234987 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/float128-nan.c @@ -0,0 +1,101 @@ +/* Test __float128 NaN generation. */ +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target fenv_exceptions } */ +/* { dg-options "" } */ + +#include +#include + +typedef unsigned long long int uint64_t; + +typedef union +{ + __float128 value; + + struct +#ifdef __MINGW32__ + /* Make sure we are using gnu-style bitfield handling. */ + __attribute__ ((gcc_struct)) +#endif + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + unsigned negative:1; + unsigned exponent:15; + unsigned quiet_nan:1; + uint64_t mant_high:47; + uint64_t mant_low:64; +#else + uint64_t mant_low:64; + uint64_t mant_high:47; + unsigned quiet_nan:1; + unsigned exponent:15; + unsigned negative:1; +#endif + } nan; + +} ieee854_float128; + +bool +__attribute__((noinline, noclone)) +check_nan (__float128 val, bool quiet) +{ + ieee854_float128 u; + volatile __float128 tmp; + + u.value = val; + + if (u.nan.exponent != 0x7fff + || (u.nan.quiet_nan | u.nan.mant_high | u.nan.mant_low) == 0 + || u.nan.quiet_nan != quiet) + return false; + + if (!__builtin_isnan (u.value)) + return false; + + feclearexcept (FE_INVALID); + + tmp = u.value + u.value; + + if ((fetestexcept (FE_INVALID) != 0) == quiet) + return false; + + return true; +} + +int +main (void) +{ + __float128 nan; + + nan = __builtin_nanq (""); + + if (!check_nan (nan, true)) + __builtin_abort (); + + nan = __builtin_nanq ("0x0"); + + if (!check_nan (nan, true)) + __builtin_abort (); + + nan = __builtin_nanq ("0x1"); + + if (!check_nan (nan, true)) + __builtin_abort (); + + nan = __builtin_nansq (""); + + if (!check_nan (nan, false)) + __builtin_abort (); + + nan = __builtin_nansq ("0x0"); + + if (!check_nan (nan, false)) + __builtin_abort (); + + nan = __builtin_nansq ("0x1"); + + if (!check_nan (nan, false)) + __builtin_abort (); + + return 0; +} -- 2.30.2