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
This commit is contained in:
Uros Bizjak 2016-06-12 19:22:16 +02:00
parent a543674d47
commit aa8fdb441f
5 changed files with 176 additions and 14 deletions

View File

@ -1,3 +1,18 @@
2016-06-12 Uros Bizjak <ubizjak@gmail.com>
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 <jiong.wang@arm.com> 2016-06-11 Jiong Wang <jiong.wang@arm.com>
PR target/71061 PR target/71061
@ -60,7 +75,7 @@
(fsm_find_control_statement_thread_paths): Avoid putting the same (fsm_find_control_statement_thread_paths): Avoid putting the same
block on the thread path twice, but ensure the thread path is block on the thread path twice, but ensure the thread path is
unchanged from the caller's point of view. unchanged from the caller's point of view.
2016-06-10 Jan Hubicka <hubicka@ucw.cz> 2016-06-10 Jan Hubicka <hubicka@ucw.cz>
* predict.c (predict_loops): Remove PRED_LOOP_BRANCH. * predict.c (predict_loops): Remove PRED_LOOP_BRANCH.
@ -144,21 +159,22 @@
Jiong Wang <jiong.wang@arm.com> Jiong Wang <jiong.wang@arm.com>
PR rtl-optimization/70751 PR rtl-optimization/70751
* lra-constraints.c (process_alt_operands): Recognize Non-pseudo spilled * lra-constraints.c (process_alt_operands): Recognize Non-pseudo
into memory. spilled into memory.
2016-06-09 Jonathan Yong <10walls@gmail.com> 2016-06-09 Jonathan Yong <10walls@gmail.com>
Revert: Revert:
2015-09-21 Jonathan Yong <10walls@gmail.com> 2015-09-21 Jonathan Yong <10walls@gmail.com>
* config/i386/cygwin.h (STARTFILE_SPEC): Explicitly search
sysroot/usr/lib/32api for additional win32 libraries, * config/i386/cygwin.h (STARTFILE_SPEC): Explicitly search
fixes failing Cygwin bootstrapping. sysroot/usr/lib/32api for additional win32 libraries,
fixes failing Cygwin bootstrapping.
2016-06-09 Marcin Baczyński <marbacz@gmail.com> 2016-06-09 Marcin Baczyński <marbacz@gmail.com>
* diagnostic.h (diagnostic_line_cutoff, diagnostic_flush_buffer): * diagnostic.h (diagnostic_line_cutoff, diagnostic_flush_buffer):
delete. Delete.
2016-06-09 David Malcolm <dmalcolm@redhat.com> 2016-06-09 David Malcolm <dmalcolm@redhat.com>
@ -503,8 +519,7 @@
2016-06-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2016-06-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local * simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local variable.
variable.
2016-06-07 Jakub Jelinek <jakub@redhat.com> 2016-06-07 Jakub Jelinek <jakub@redhat.com>

View File

@ -73,6 +73,7 @@ DEF_PRIMITIVE_TYPE (FLOAT, float_type_node)
DEF_PRIMITIVE_TYPE (DOUBLE, double_type_node) DEF_PRIMITIVE_TYPE (DOUBLE, double_type_node)
DEF_PRIMITIVE_TYPE (FLOAT80, float80_type_node) DEF_PRIMITIVE_TYPE (FLOAT80, float80_type_node)
DEF_PRIMITIVE_TYPE (FLOAT128, float128_type_node) DEF_PRIMITIVE_TYPE (FLOAT128, float128_type_node)
DEF_PRIMITIVE_TYPE (CONST_STRING, const_string_type_node)
# MMX vectors # MMX vectors
DEF_VECTOR_TYPE (V2SF, FLOAT) DEF_VECTOR_TYPE (V2SF, FLOAT)
@ -191,6 +192,7 @@ DEF_FUNCTION_TYPE (PVOID)
DEF_FUNCTION_TYPE (FLOAT, FLOAT) DEF_FUNCTION_TYPE (FLOAT, FLOAT)
DEF_FUNCTION_TYPE (FLOAT128, FLOAT128) DEF_FUNCTION_TYPE (FLOAT128, FLOAT128)
DEF_FUNCTION_TYPE (FLOAT128, CONST_STRING)
DEF_FUNCTION_TYPE (INT, INT) DEF_FUNCTION_TYPE (INT, INT)
DEF_FUNCTION_TYPE (INT, V16QI) DEF_FUNCTION_TYPE (INT, V16QI)
DEF_FUNCTION_TYPE (INT, V2DF) DEF_FUNCTION_TYPE (INT, V2DF)

View File

@ -32718,6 +32718,8 @@ enum ix86_builtins
/* TFmode support builtins. */ /* TFmode support builtins. */
IX86_BUILTIN_INFQ, IX86_BUILTIN_INFQ,
IX86_BUILTIN_HUGE_VALQ, IX86_BUILTIN_HUGE_VALQ,
IX86_BUILTIN_NANQ,
IX86_BUILTIN_NANSQ,
IX86_BUILTIN_FABSQ, IX86_BUILTIN_FABSQ,
IX86_BUILTIN_COPYSIGNQ, IX86_BUILTIN_COPYSIGNQ,
@ -38105,11 +38107,28 @@ ix86_fold_builtin (tree fndecl, int n_args,
{ {
enum ix86_builtins fn_code = (enum ix86_builtins) enum ix86_builtins fn_code = (enum ix86_builtins)
DECL_FUNCTION_CODE (fndecl); DECL_FUNCTION_CODE (fndecl);
if (fn_code == IX86_BUILTIN_CPU_IS switch (fn_code)
|| fn_code == IX86_BUILTIN_CPU_SUPPORTS)
{ {
case IX86_BUILTIN_CPU_IS:
case IX86_BUILTIN_CPU_SUPPORTS:
gcc_assert (n_args == 1); 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 static void
ix86_init_builtin_types (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. */ /* The __float80 type. */
float80_type_node = long_double_type_node; float80_type_node = long_double_type_node;
@ -38230,6 +38249,10 @@ ix86_init_builtin_types (void)
layout_type (float128_type_node); layout_type (float128_type_node);
lang_hooks.types.register_builtin_type (float128_type_node, "__float128"); 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. */ /* This macro is built by i386-builtin-types.awk. */
DEFINE_BUILTIN_PRIMITIVE_TYPES; DEFINE_BUILTIN_PRIMITIVE_TYPES;
} }
@ -38250,6 +38273,18 @@ ix86_init_builtins (void)
def_builtin_const (0, "__builtin_huge_valq", def_builtin_const (0, "__builtin_huge_valq",
FLOAT128_FTYPE_VOID, IX86_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 /* We will expand them to normal call if SSE isn't available since
they are used by libgcc. */ they are used by libgcc. */
t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128); t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128);
@ -41463,6 +41498,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
return target; return target;
} }
case IX86_BUILTIN_NANQ:
case IX86_BUILTIN_NANSQ:
return expand_call (exp, target, ignore);
case IX86_BUILTIN_RDPMC: case IX86_BUILTIN_RDPMC:
case IX86_BUILTIN_RDTSC: case IX86_BUILTIN_RDTSC:
case IX86_BUILTIN_RDTSCP: case IX86_BUILTIN_RDTSCP:

View File

@ -1,3 +1,8 @@
2016-06-12 Uros Bizjak <ubizjak@gmail.com>
PR target/71241
* testsuite/gcc.dg/torture/float128-nan.c: New test.
2016-06-12 Dominique d'Humieres <dominiq@lps.ens.fr> 2016-06-12 Dominique d'Humieres <dominiq@lps.ens.fr>
PR target/60751 PR target/60751

View File

@ -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 <fenv.h>
#include <stdbool.h>
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;
}