Add __builtin_iseqsig()
iseqsig() is a C2x library function, for signaling floating-point equality checks. Provide a GCC-builtin for it, which is folded to a series of comparisons. 2022-09-01 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> PR middle-end/77928 gcc/ * doc/extend.texi: Document iseqsig builtin. * builtins.cc (fold_builtin_iseqsig): New function. (fold_builtin_2): Handle BUILT_IN_ISEQSIG. (is_inexpensive_builtin): Handle BUILT_IN_ISEQSIG. * builtins.def (BUILT_IN_ISEQSIG): New built-in. gcc/c-family/ * c-common.cc (check_builtin_function_arguments): Handle BUILT_IN_ISEQSIG. gcc/testsuite/ * gcc.dg/torture/builtin-iseqsig-1.c: New test. * gcc.dg/torture/builtin-iseqsig-2.c: New test. * gcc.dg/torture/builtin-iseqsig-3.c: New test.
This commit is contained in:
parent
bb42f05d07
commit
34cf27a64e
7 changed files with 386 additions and 3 deletions
|
@ -171,6 +171,7 @@ static tree fold_builtin_fabs (location_t, tree, tree);
|
|||
static tree fold_builtin_abs (location_t, tree, tree);
|
||||
static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
|
||||
enum tree_code);
|
||||
static tree fold_builtin_iseqsig (location_t, tree, tree);
|
||||
static tree fold_builtin_varargs (location_t, tree, tree*, int);
|
||||
|
||||
static tree fold_builtin_strpbrk (location_t, tree, tree, tree, tree);
|
||||
|
@ -9445,6 +9446,42 @@ fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
|
|||
fold_build2_loc (loc, code, type, arg0, arg1));
|
||||
}
|
||||
|
||||
/* Fold a call to __builtin_iseqsig(). ARG0 and ARG1 are the arguments.
|
||||
After choosing the wider floating-point type for the comparison,
|
||||
the code is folded to:
|
||||
SAVE_EXPR<ARG0> >= SAVE_EXPR<ARG1> && SAVE_EXPR<ARG0> <= SAVE_EXPR<ARG1> */
|
||||
|
||||
static tree
|
||||
fold_builtin_iseqsig (location_t loc, tree arg0, tree arg1)
|
||||
{
|
||||
tree type0, type1;
|
||||
enum tree_code code0, code1;
|
||||
tree cmp1, cmp2, cmp_type = NULL_TREE;
|
||||
|
||||
type0 = TREE_TYPE (arg0);
|
||||
type1 = TREE_TYPE (arg1);
|
||||
|
||||
code0 = TREE_CODE (type0);
|
||||
code1 = TREE_CODE (type1);
|
||||
|
||||
if (code0 == REAL_TYPE && code1 == REAL_TYPE)
|
||||
/* Choose the wider of two real types. */
|
||||
cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
|
||||
? type0 : type1;
|
||||
else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
|
||||
cmp_type = type0;
|
||||
else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
|
||||
cmp_type = type1;
|
||||
|
||||
arg0 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg0));
|
||||
arg1 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg1));
|
||||
|
||||
cmp1 = fold_build2_loc (loc, GE_EXPR, integer_type_node, arg0, arg1);
|
||||
cmp2 = fold_build2_loc (loc, LE_EXPR, integer_type_node, arg0, arg1);
|
||||
|
||||
return fold_build2_loc (loc, TRUTH_AND_EXPR, integer_type_node, cmp1, cmp2);
|
||||
}
|
||||
|
||||
/* Fold __builtin_{,s,u}{add,sub,mul}{,l,ll}_overflow, either into normal
|
||||
arithmetics if it can never overflow, or into internal functions that
|
||||
return both result of arithmetics and overflowed boolean flag in
|
||||
|
@ -9878,6 +9915,9 @@ fold_builtin_2 (location_t loc, tree expr, tree fndecl, tree arg0, tree arg1)
|
|||
arg0, arg1, UNORDERED_EXPR,
|
||||
NOP_EXPR);
|
||||
|
||||
case BUILT_IN_ISEQSIG:
|
||||
return fold_builtin_iseqsig (loc, arg0, arg1);
|
||||
|
||||
/* We do the folding for va_start in the expander. */
|
||||
case BUILT_IN_VA_START:
|
||||
break;
|
||||
|
@ -11396,6 +11436,7 @@ is_inexpensive_builtin (tree decl)
|
|||
case BUILT_IN_ISLESSEQUAL:
|
||||
case BUILT_IN_ISLESSGREATER:
|
||||
case BUILT_IN_ISUNORDERED:
|
||||
case BUILT_IN_ISEQSIG:
|
||||
case BUILT_IN_VA_ARG_PACK:
|
||||
case BUILT_IN_VA_ARG_PACK_LEN:
|
||||
case BUILT_IN_VA_COPY:
|
||||
|
|
|
@ -1029,6 +1029,7 @@ DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOT
|
|||
DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISEQSIG, "iseqsig", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISSIGNALING, "issignaling", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||
|
|
|
@ -6334,6 +6334,7 @@ check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
|
|||
case BUILT_IN_ISLESSEQUAL:
|
||||
case BUILT_IN_ISLESSGREATER:
|
||||
case BUILT_IN_ISUNORDERED:
|
||||
case BUILT_IN_ISEQSIG:
|
||||
if (builtin_function_validate_nargs (loc, fndecl, nargs, 2))
|
||||
{
|
||||
enum tree_code code0, code1;
|
||||
|
|
|
@ -13187,6 +13187,7 @@ is called and the @var{flag} argument passed to it.
|
|||
@node Other Builtins
|
||||
@section Other Built-in Functions Provided by GCC
|
||||
@cindex built-in functions
|
||||
@findex __builtin_iseqsig
|
||||
@findex __builtin_isfinite
|
||||
@findex __builtin_isnormal
|
||||
@findex __builtin_isgreater
|
||||
|
@ -13738,9 +13739,9 @@ the same names as the standard macros ( @code{isgreater},
|
|||
@code{islessgreater}, and @code{isunordered}) , with @code{__builtin_}
|
||||
prefixed. We intend for a library implementor to be able to simply
|
||||
@code{#define} each standard macro to its built-in equivalent.
|
||||
In the same fashion, GCC provides @code{fpclassify}, @code{isfinite},
|
||||
@code{isinf_sign}, @code{isnormal} and @code{signbit} built-ins used with
|
||||
@code{__builtin_} prefixed. The @code{isinf} and @code{isnan}
|
||||
In the same fashion, GCC provides @code{fpclassify}, @code{iseqsig},
|
||||
@code{isfinite}, @code{isinf_sign}, @code{isnormal} and @code{signbit} built-ins
|
||||
used with @code{__builtin_} prefixed. The @code{isinf} and @code{isnan}
|
||||
built-in functions appear both with and without the @code{__builtin_} prefix.
|
||||
With @code{-ffinite-math-only} option the @code{isinf} and @code{isnan}
|
||||
built-in functions will always return 0.
|
||||
|
|
113
gcc/testsuite/gcc.dg/torture/builtin-iseqsig-1.c
Normal file
113
gcc/testsuite/gcc.dg/torture/builtin-iseqsig-1.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* { dg-do run { xfail powerpc*-*-* } } */
|
||||
/* remove the xfail for powerpc when pr58684 is fixed */
|
||||
/* { dg-add-options ieee } */
|
||||
/* { dg-additional-options "-fsignaling-nans" } */
|
||||
/* { dg-require-effective-target fenv_exceptions } */
|
||||
|
||||
#include <fenv.h>
|
||||
|
||||
void
|
||||
ftrue (float x, float y)
|
||||
{
|
||||
if (!__builtin_iseqsig (x, y))
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
void
|
||||
ffalse (float x, float y)
|
||||
{
|
||||
if (__builtin_iseqsig (x, y))
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
volatile float f1, f2;
|
||||
|
||||
f1 = 0.f; f2 = 0.f;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.f; f2 = -0.f;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.f; f2 = 1.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = -0.f; f2 = 1.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.f; f2 = __builtin_inff();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = -0.f; f2 = __builtin_inff();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.f; f2 = __builtin_nanf("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = -0.f; f2 = __builtin_nanf("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = 1.f; f2 = 1.f;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.f; f2 = 0.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.f; f2 = -0.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.f; f2 = __builtin_inff();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.f; f2 = __builtin_nanf("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_inff(); f2 = __builtin_inff();
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = __builtin_inff(); f2 = __builtin_nanf("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nanf(""); f2 = __builtin_nanf("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nansf(""); f2 = 1.f;
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = 1.f; f2 = __builtin_nansf("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nansf(""); f2 = __builtin_nansf("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
return 0;
|
||||
}
|
113
gcc/testsuite/gcc.dg/torture/builtin-iseqsig-2.c
Normal file
113
gcc/testsuite/gcc.dg/torture/builtin-iseqsig-2.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* { dg-do run { xfail powerpc*-*-* } } */
|
||||
/* remove the xfail for powerpc when pr58684 is fixed */
|
||||
/* { dg-add-options ieee } */
|
||||
/* { dg-additional-options "-fsignaling-nans" } */
|
||||
/* { dg-require-effective-target fenv_exceptions_double } */
|
||||
|
||||
#include <fenv.h>
|
||||
|
||||
void
|
||||
ftrue (double x, double y)
|
||||
{
|
||||
if (!__builtin_iseqsig (x, y))
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
void
|
||||
ffalse (double x, double y)
|
||||
{
|
||||
if (__builtin_iseqsig (x, y))
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
volatile double f1, f2;
|
||||
|
||||
f1 = 0.; f2 = 0.;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.; f2 = -0.;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.; f2 = 1.;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = -0.; f2 = 1.;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.; f2 = __builtin_inf();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = -0.; f2 = __builtin_inf();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.; f2 = __builtin_nan("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = -0.; f2 = __builtin_nan("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = 1.; f2 = 1.;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.; f2 = 0.;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.; f2 = -0.;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.; f2 = __builtin_inf();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.; f2 = __builtin_nan("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_inf(); f2 = __builtin_inf();
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = __builtin_inf(); f2 = __builtin_nan("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nan(""); f2 = __builtin_nan("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nans(""); f2 = 1.;
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = 1.; f2 = __builtin_nans("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nans(""); f2 = __builtin_nans("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
return 0;
|
||||
}
|
113
gcc/testsuite/gcc.dg/torture/builtin-iseqsig-3.c
Normal file
113
gcc/testsuite/gcc.dg/torture/builtin-iseqsig-3.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* { dg-do run { xfail powerpc*-*-* } } */
|
||||
/* remove the xfail for powerpc when pr58684 is fixed */
|
||||
/* { dg-add-options ieee } */
|
||||
/* { dg-additional-options "-fsignaling-nans" } */
|
||||
/* { dg-require-effective-target fenv_exceptions_long_double } */
|
||||
|
||||
#include <fenv.h>
|
||||
|
||||
void
|
||||
ftrue (long double x, long double y)
|
||||
{
|
||||
if (!__builtin_iseqsig (x, y))
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
void
|
||||
ffalse (long double x, long double y)
|
||||
{
|
||||
if (__builtin_iseqsig (x, y))
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
volatile long double f1, f2;
|
||||
|
||||
f1 = 0.L; f2 = 0.f;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.L; f2 = -0.f;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.L; f2 = 1.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = -0.L; f2 = 1.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.L; f2 = __builtin_infl();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = -0.L; f2 = __builtin_infl();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 0.L; f2 = __builtin_nanl("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = -0.L; f2 = __builtin_nanl("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = 1.L; f2 = 1.f;
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.L; f2 = 0.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.L; f2 = -0.f;
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.L; f2 = __builtin_infl();
|
||||
ffalse (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = 1.L; f2 = __builtin_nanl("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_infl(); f2 = __builtin_infl();
|
||||
ftrue (f1, f2);
|
||||
if (fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
|
||||
f1 = __builtin_infl(); f2 = __builtin_nanl("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nanl(""); f2 = __builtin_nanl("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nansl(""); f2 = 1.L;
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = 1.L; f2 = __builtin_nansl("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
f1 = __builtin_nansl(""); f2 = __builtin_nansl("");
|
||||
ffalse (f1, f2);
|
||||
if (!fetestexcept (FE_INVALID)) __builtin_abort ();
|
||||
feclearexcept (FE_INVALID);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue