From 3bf5906b317941790438b4503a2234cdc710dca3 Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Fri, 23 May 2008 04:47:12 +0000 Subject: [PATCH] builtin-types.def (BT_FN_INT_INT_INT_INT_INT_INT_VAR): New. * builtin-types.def (BT_FN_INT_INT_INT_INT_INT_INT_VAR): New. * builtins.c (fold_builtin_fpclassify): New. (fold_builtin_varargs): Handle BUILT_IN_FPCLASSIFY. * builtins.def (BUILT_IN_FPCLASSIFY): New. * c-common.c (handle_type_generic_attribute): Adjust to accept fixed arguments before an elipsis. (check_builtin_function_arguments): Handle BUILT_IN_FPCLASSIFY. * doc/extend.texi: Document __builtin_fpclassify. testsuite: * gcc.dg/builtins-error.c: Test __builtin_fpclassify. Also add tests for all previous type-generic builtins. * gcc.dg/pr28796-2.c: Add -DUNSAFE flag. * gcc.dg/tg-tests.h: Test __builtin_fpclassify. From-SVN: r135789 --- gcc/ChangeLog | 11 +++++ gcc/builtin-types.def | 3 ++ gcc/builtins.c | 69 +++++++++++++++++++++++++++ gcc/builtins.def | 1 + gcc/c-common.c | 36 +++++++++++++- gcc/doc/extend.texi | 20 ++++++-- gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.dg/builtins-error.c | 52 ++++++++++++++++++-- gcc/testsuite/gcc.dg/pr28796-2.c | 4 +- gcc/testsuite/gcc.dg/tg-tests.h | 46 +++++++++++++----- 10 files changed, 224 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 51712235ae0..a75c72ffcda 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2008-05-23 Kaveh R. Ghazi + + * builtin-types.def (BT_FN_INT_INT_INT_INT_INT_INT_VAR): New. + * builtins.c (fold_builtin_fpclassify): New. + (fold_builtin_varargs): Handle BUILT_IN_FPCLASSIFY. + * builtins.def (BUILT_IN_FPCLASSIFY): New. + * c-common.c (handle_type_generic_attribute): Adjust to accept + fixed arguments before an elipsis. + (check_builtin_function_arguments): Handle BUILT_IN_FPCLASSIFY. + * doc/extend.texi: Document __builtin_fpclassify. + 2008-05-22 Aldy Hernandez * omp-low.c (gate_expand_omp_ssa): Remove. diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index 081a33f0467..25b5a0964f5 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -449,6 +449,9 @@ DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE, BT_CONST_STRING) +DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_INT_INT_INT_INT_INT_VAR, + BT_INT, BT_INT, BT_INT, BT_INT, BT_INT, BT_INT) + DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR) DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE) diff --git a/gcc/builtins.c b/gcc/builtins.c index 3060f80ae00..d442469b7ee 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -9744,6 +9744,70 @@ fold_builtin_classify (tree fndecl, tree arg, int builtin_index) } } +/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...). + This builtin will generate code to return the appropriate floating + point classification depending on the value of the floating point + number passed in. The possible return values must be supplied as + int arguments to the call in the following order: FP_NAN, FP_INF, + FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly + one floating point argument which is "type generic". */ + +static tree +fold_builtin_fpclassify (tree exp) +{ + tree fp_nan, fp_inf, fp_normal, fp_subnormal, fp_zero, arg, type, res, tmp; + enum machine_mode mode; + REAL_VALUE_TYPE r; + char buf[128]; + + /* Verify the required arguments in the original call. */ + if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, + INTEGER_TYPE, INTEGER_TYPE, + INTEGER_TYPE, REAL_TYPE, VOID_TYPE)) + return NULL_TREE; + + fp_nan = CALL_EXPR_ARG (exp, 0); + fp_inf = CALL_EXPR_ARG (exp, 1); + fp_normal = CALL_EXPR_ARG (exp, 2); + fp_subnormal = CALL_EXPR_ARG (exp, 3); + fp_zero = CALL_EXPR_ARG (exp, 4); + arg = CALL_EXPR_ARG (exp, 5); + type = TREE_TYPE (arg); + mode = TYPE_MODE (type); + arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg)); + + /* fpclassify(x) -> + isnan(x) ? FP_NAN : + (fabs(x) == Inf ? FP_INF : + (fabs(x) >= DBL_MIN ? FP_NORMAL : + (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */ + + tmp = fold_build2 (EQ_EXPR, integer_type_node, arg, + build_real (type, dconst0)); + res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_zero, fp_subnormal); + + sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); + real_from_string (&r, buf); + tmp = fold_build2 (GE_EXPR, integer_type_node, arg, build_real (type, r)); + res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_normal, res); + + if (HONOR_INFINITIES (mode)) + { + real_inf (&r); + tmp = fold_build2 (EQ_EXPR, integer_type_node, arg, + build_real (type, r)); + res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_inf, res); + } + + if (HONOR_NANS (mode)) + { + tmp = fold_build2 (ORDERED_EXPR, integer_type_node, arg, arg); + res = fold_build3 (COND_EXPR, integer_type_node, tmp, res, fp_nan); + } + + return res; +} + /* Fold a call to an unordered comparison function such as __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function being called and ARG0 and ARG1 are the arguments for the call. @@ -10528,6 +10592,11 @@ fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED) case BUILT_IN_SNPRINTF_CHK: case BUILT_IN_VSNPRINTF_CHK: ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode); + break; + + case BUILT_IN_FPCLASSIFY: + ret = fold_builtin_fpclassify (exp); + break; default: break; diff --git a/gcc/builtins.def b/gcc/builtins.def index 8bae2bd467c..310e5f456a7 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -654,6 +654,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_ DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FPCLASSIFY, "fpclassify", BT_FN_INT_INT_INT_INT_INT_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) diff --git a/gcc/c-common.c b/gcc/c-common.c index 67c9c0b538f..70ba5cc4851 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -6528,8 +6528,17 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name), tree ARG_UNUSED (args), int ARG_UNUSED (flags), bool * ARG_UNUSED (no_add_attrs)) { - /* Ensure we have a function type, with no arguments. */ - gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE && ! TYPE_ARG_TYPES (*node)); + tree params; + + /* Ensure we have a function type. */ + gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); + + params = TYPE_ARG_TYPES (*node); + while (params && ! VOID_TYPE_P (TREE_VALUE (params))) + params = TREE_CHAIN (params); + + /* Ensure we have a variadic function. */ + gcc_assert (!params); return NULL_TREE; } @@ -6712,6 +6721,29 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args) } return false; + case BUILT_IN_FPCLASSIFY: + if (validate_nargs (fndecl, nargs, 6)) + { + unsigned i; + + for (i=0; i<5; i++) + if (TREE_CODE (args[i]) != INTEGER_CST) + { + error ("non-const integer argument %u in call to function %qE", + i+1, fndecl); + return false; + } + + if (TREE_CODE (TREE_TYPE (args[5])) != REAL_TYPE) + { + error ("non-floating-point argument in call to function %qE", + fndecl); + return false; + } + return true; + } + return false; + default: return true; } diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 36e81ffe55c..78d581d62e6 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5764,6 +5764,7 @@ should be 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_fpclassify @findex __builtin_isfinite @findex __builtin_isnormal @findex __builtin_isgreater @@ -6295,10 +6296,10 @@ 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{isfinite}, @code{isinf_sign} -and @code{isnormal} built-ins used with @code{__builtin_} prefixed. -The @code{isinf} and @code{isnan} builtins appear both with and -without the @code{__builtin_} prefix. +In the same fashion, GCC provides @code{fpclassify}, @code{isfinite}, +@code{isinf_sign} and @code{isnormal} built-ins used with +@code{__builtin_} prefixed. The @code{isinf} and @code{isnan} +builtins appear both with and without the @code{__builtin_} prefix. @deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1}, @var{type2}) @@ -6555,6 +6556,17 @@ Similar to @code{__builtin_huge_val}, except the return type is @code{long double}. @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 +possible FP classes and are used for return values. They must be +constant values and they must appear in this order: @code{FP_NAN}, +@code{FP_INF}, @code{FP_NORMAL}, @code{FP_SUBNORMAL} and +@code{FP_ZERO}. The ellipsis is for exactly one floating point value +to classify. GCC treats the last argument as type-generic, which +means it does not do default promotion from float to double. +@end deftypefn + @deftypefn {Built-in Function} double __builtin_inf (void) Similar to @code{__builtin_huge_val}, except a warning is generated if the target floating-point format does not support infinities. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af0260cff6f..420a482832f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-05-23 Kaveh R. Ghazi + + * gcc.dg/builtins-error.c: Test __builtin_fpclassify. Also + add tests for all previous type-generic builtins. + * gcc.dg/pr28796-2.c: Add -DUNSAFE flag. + * gcc.dg/tg-tests.h: Test __builtin_fpclassify. + 2008-05-22 Thomas Koenig PR libgfortran/36302 diff --git a/gcc/testsuite/gcc.dg/builtins-error.c b/gcc/testsuite/gcc.dg/builtins-error.c index 2c0ece1934b..0f41700ba1a 100644 --- a/gcc/testsuite/gcc.dg/builtins-error.c +++ b/gcc/testsuite/gcc.dg/builtins-error.c @@ -4,20 +4,62 @@ struct X { int x; }; int test1(struct X x) { - return __builtin_isnormal(x); /* { dg-error "non-floating-point argument" } */ + if (x.x == 1) return __builtin_fpclassify(1,2,3,4,5,x); /* { dg-error "non-floating-point argument" } */ + if (x.x == 2) return __builtin_isfinite(x); /* { dg-error "non-floating-point argument" } */ + if (x.x == 3) return __builtin_isinf_sign(x); /* { dg-error "non-floating-point argument" } */ + if (x.x == 4) return __builtin_isinf(x); /* { dg-error "non-floating-point argument" } */ + if (x.x == 5) return __builtin_isnan(x); /* { dg-error "non-floating-point argument" } */ + if (x.x == 6) return __builtin_isnormal(x); /* { dg-error "non-floating-point argument" } */ + if (x.x == 7) return __builtin_isgreater(x, x); /* { dg-error "non-floating-point arguments" } */ + if (x.x == 8) return __builtin_isgreaterequal(x, x); /* { dg-error "non-floating-point arguments" } */ + if (x.x == 9) return __builtin_isless(x, x); /* { dg-error "non-floating-point arguments" } */ + if (x.x == 10) return __builtin_islessequal(x, x); /* { dg-error "non-floating-point arguments" } */ + if (x.x == 11) return __builtin_islessgreater(x, x); /* { dg-error "non-floating-point arguments" } */ + if (x.x == 12) return __builtin_isunordered(x, x); /* { dg-error "non-floating-point arguments" } */ + + return 0; } int test2(double x) { - return __builtin_isgreater(x); /* { dg-error "not enough arguments" } */ + if (x == 1) return __builtin_fpclassify(1,2,3,4,5); /* { dg-error "not enough arguments" } */ + if (x == 2) return __builtin_isfinite(); /* { dg-error "not enough arguments" } */ + if (x == 3) return __builtin_isinf_sign(); /* { dg-error "not enough arguments" } */ + if (x == 4) return __builtin_isinf(); /* { dg-error "not enough arguments" } */ + if (x == 5) return __builtin_isnan(); /* { dg-error "not enough arguments" } */ + if (x == 6) return __builtin_isnormal(); /* { dg-error "not enough arguments" } */ + if (x == 7) return __builtin_isgreater(x); /* { dg-error "not enough arguments" } */ + if (x == 8) return __builtin_isgreaterequal(x); /* { dg-error "not enough arguments" } */ + if (x == 9) return __builtin_isless(x); /* { dg-error "not enough arguments" } */ + if (x == 10) return __builtin_islessequal(x); /* { dg-error "not enough arguments" } */ + if (x == 11) return __builtin_islessgreater(x); /* { dg-error "not enough arguments" } */ + if (x == 12) return __builtin_isunordered(x); /* { dg-error "not enough arguments" } */ + return 0; } int test3(double x) { - return __builtin_isinf(x, x); /* { dg-error "too many arguments" } */ + if (x == 1) return __builtin_fpclassify(1,2,3,4,5,x,x); /* { dg-error "too many arguments" } */ + if (x == 2) return __builtin_isfinite(x, x); /* { dg-error "too many arguments" } */ + if (x == 3) return __builtin_isinf_sign(x, x); /* { dg-error "too many arguments" } */ + if (x == 4) return __builtin_isinf(x, x); /* { dg-error "too many arguments" } */ + if (x == 5) return __builtin_isnan(x, x); /* { dg-error "too many arguments" } */ + if (x == 6) return __builtin_isnormal(x, x); /* { dg-error "too many arguments" } */ + if (x == 7) return __builtin_isgreater(x, x, x); /* { dg-error "too many arguments" } */ + if (x == 8) return __builtin_isgreaterequal(x, x, x); /* { dg-error "too many arguments" } */ + if (x == 9) return __builtin_isless(x, x, x); /* { dg-error "too many arguments" } */ + if (x == 10) return __builtin_islessequal(x, x, x); /* { dg-error "too many arguments" } */ + if (x == 11) return __builtin_islessgreater(x, x, x); /* { dg-error "too many arguments" } */ + if (x == 12) return __builtin_isunordered(x, x, x); /* { dg-error "too many arguments" } */ + return 0; } -int test4(double x) +int test4(int i, double x) { - return __builtin_isinf_sign(x, x); /* { dg-error "too many arguments" } */ + if (x == 1) return __builtin_fpclassify(i,2,3,4,5,x); /* { dg-error "non-const integer argument" } */ + if (x == 2) return __builtin_fpclassify(1,i,3,4,5,x); /* { dg-error "non-const integer argument" } */ + if (x == 3) return __builtin_fpclassify(1,2,i,4,5,x); /* { dg-error "non-const integer argument" } */ + if (x == 4) return __builtin_fpclassify(1,2,3,i,5,x); /* { dg-error "non-const integer argument" } */ + if (x == 5) return __builtin_fpclassify(1,2,3,4,i,x); /* { dg-error "non-const integer argument" } */ + return 0; } diff --git a/gcc/testsuite/gcc.dg/pr28796-2.c b/gcc/testsuite/gcc.dg/pr28796-2.c index 6a9eff827b7..f4900817581 100644 --- a/gcc/testsuite/gcc.dg/pr28796-2.c +++ b/gcc/testsuite/gcc.dg/pr28796-2.c @@ -1,6 +1,6 @@ /* { dg-do run } */ -/* { dg-options "-O2 -funsafe-math-optimizations -fno-finite-math-only" } */ -/* { dg-options "-mieee -O2 -funsafe-math-optimizations -fno-finite-math-only" { target alpha*-*-* } } */ +/* { dg-options "-O2 -funsafe-math-optimizations -fno-finite-math-only -DUNSAFE" } */ +/* { dg-options "-mieee -O2 -funsafe-math-optimizations -fno-finite-math-only -DUNSAFE" { target alpha*-*-* } } */ #include "tg-tests.h" diff --git a/gcc/testsuite/gcc.dg/tg-tests.h b/gcc/testsuite/gcc.dg/tg-tests.h index c34e8888cfa..dc95a2cde62 100644 --- a/gcc/testsuite/gcc.dg/tg-tests.h +++ b/gcc/testsuite/gcc.dg/tg-tests.h @@ -1,9 +1,17 @@ /* Test various type-generic builtins by calling "main_tests()". */ +#define FP_NAN 1 +#define FP_INF 2 +#define FP_NORMAL 3 +#define FP_SUBNORMAL 4 +#define FP_ZERO 5 +#define fpclassify(X) __builtin_fpclassify(FP_NAN, FP_INF, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, (X)) + void __attribute__ ((__noinline__)) foo_1 (float f, double d, long double ld, int res_unord, int res_isnan, int res_isinf, - int res_isinf_sign, int res_isfin, int res_isnorm) + int res_isinf_sign, int res_isfin, int res_isnorm, + int classification) { if (__builtin_isunordered (f, 0) != res_unord) __builtin_abort (); @@ -71,16 +79,30 @@ foo_1 (float f, double d, long double ld, __builtin_abort (); if (__builtin_finitel (ld) != res_isfin) __builtin_abort (); + + /* Subnormals can abruptly underflow to zero in unsafe math + mode, so bypass testing these numbers if necessary. */ +#ifdef UNSAFE + if (classification != FP_SUBNORMAL) +#endif + { + if (fpclassify(f) != classification) + __builtin_abort (); + if (fpclassify(d) != classification) + __builtin_abort (); + if (fpclassify(ld) != classification) + __builtin_abort (); + } } void __attribute__ ((__noinline__)) foo (float f, double d, long double ld, int res_unord, int res_isnan, int res_isinf, - int res_isfin, int res_isnorm) + int res_isfin, int res_isnorm, int classification) { - foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm); + foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm, classification); /* Try all the values negated as well. */ - foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm); + foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm, classification); } int __attribute__ ((__noinline__)) @@ -92,35 +114,35 @@ main_tests (void) /* Test NaN. */ f = __builtin_nanf(""); d = __builtin_nan(""); ld = __builtin_nanl(""); - foo(f, d, ld, /*unord=*/ 1, /*isnan=*/ 1, /*isinf=*/ 0, /*isfin=*/ 0, /*isnorm=*/ 0); + foo(f, d, ld, /*unord=*/ 1, /*isnan=*/ 1, /*isinf=*/ 0, /*isfin=*/ 0, /*isnorm=*/ 0, FP_NAN); /* Test infinity. */ f = __builtin_inff(); d = __builtin_inf(); ld = __builtin_infl(); - foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0); + foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0, FP_INF); /* Test zero. */ f = 0; d = 0; ld = 0; - foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0); + foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0, FP_ZERO); /* Test one. */ f = 1; d = 1; ld = 1; - foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1); + foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, FP_NORMAL); /* Test minimum values. */ f = __FLT_MIN__; d = __DBL_MIN__; ld = __LDBL_MIN__; - foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1); + foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, FP_NORMAL); /* Test subnormal values. */ f = __FLT_MIN__/2; d = __DBL_MIN__/2; ld = __LDBL_MIN__/2; - foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0); + foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0, FP_SUBNORMAL); /* Test maximum values. */ f = __FLT_MAX__; d = __DBL_MAX__; ld = __LDBL_MAX__; - foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1); + foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, FP_NORMAL); /* Test overflow values. */ f = __FLT_MAX__*2; d = __DBL_MAX__*2; ld = __LDBL_MAX__*2; - foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0); + foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0, FP_INF); return 0; } -- 2.30.2