Commit 94fc87ec by Tamar Christina Committed by Tamar Christina

re PR middle-end/77925 (Add __builtin_issubnormal)

2017-06-08  Tamar Christina  <tamar.christina@arm.com>

	PR middle-end/77925
	PR middle-end/77926
	PR middle-end/66462

	* gcc/builtins.c (fold_builtin_fpclassify): Remove.
	(fold_builtin_interclass_mathfn): Remove.
	(expand_builtin): Add builtins to lowering list.
	(fold_builtin_n): Remove fold_builtin_varargs.
	(fold_builtin_varargs): Remove.
	* gcc/builtins.def (BUILT_IN_ISZERO, BUILT_IN_ISSUBNORMAL): New.
	* gcc/real.h (get_min_float): New.
	(real_format): Add is_ieee_compatible field.
	* gcc/real.c (get_min_float): New.
	(ieee_single_format): Set is_ieee_compatible flag.
	* gcc/gimple-low.c (lower_stm): Define BUILT_IN_FPCLASSIFY,
	CASE_FLT_FN (BUILT_IN_ISINF), BUILT_IN_ISINFD32, BUILT_IN_ISINFD64,
	BUILT_IN_ISINFD128, BUILT_IN_ISNAND32, BUILT_IN_ISNAND64,
	BUILT_IN_ISNAND128, BUILT_IN_ISNAN, BUILT_IN_ISNORMAL, BUILT_IN_ISZERO,
	BUILT_IN_ISSUBNORMAL, CASE_FLT_FN (BUILT_IN_FINITE), BUILT_IN_FINITED32
	BUILT_IN_FINITED64, BUILT_IN_FINITED128, BUILT_IN_ISFINITE.
	(lower_builtin_fpclassify, is_nan, is_normal, is_infinity): New.
	(is_zero, is_subnormal, is_finite, use_ieee_int_mode): Likewise.
	(lower_builtin_isnan, lower_builtin_isinfinite): Likewise.
	(lower_builtin_isnormal, lower_builtin_iszero): Likewise.
	(lower_builtin_issubnormal, lower_builtin_isfinite): Likewise.
	(emit_tree_cond, get_num_as_int, emit_tree_and_return_var): New.
	(mips_single_format): Likewise.
	(motorola_single_format): Likewise.
	(spu_single_format): Likewise.
	(ieee_double_format): Likewise.
	(mips_double_format): Likewise.
	(motorola_double_format): Likewise.
	(ieee_extended_motorola_format): Likewise.
	(ieee_extended_intel_128_format): Likewise.
	(ieee_extended_intel_96_round_53_format): Likewise.
	(ibm_extended_format): Likewise.
	(mips_extended_format): Likewise.
	(ieee_quad_format): Likewise.
	(mips_quad_format): Likewise.
	(vax_f_format): Likewise.
	(vax_d_format): Likewise.
	(vax_g_format): Likewise.
	(decimal_single_format): Likewise.
	(decimal_quad_format): Likewise.
	(iee_half_format): Likewise.
	(mips_single_format): Likewise.
	(arm_half_format): Likewise.
	(real_internal_format): Likewise.
	* gcc/doc/extend.texi: Add documentation for built-ins.
	* gcc/c/c-typeck.c (convert_arguments): Add BUILT_IN_ISZERO
	and BUILT_IN_ISSUBNORMAL.

gcc/testsuite/
2017-06-08  Tamar Christina  <tamar.christina@arm.com>

	* gcc.target/aarch64/builtin-fpclassify.c: New codegen test.
	* gcc.dg/fold-notunord.c: Removed.
	* gcc.dg/torture/floatn-tg-4.h: Add tests for iszero and issubnormal.
	* gcc.dg/torture/float128-tg-4.c: Likewise.
	* gcc.dg/torture/float128x-tg-4: Likewise.
	* gcc.dg/torture/float16-tg-4.c: Likewise.
	* gcc.dg/torture/float32-tg-4.c: Likewise.
	* gcc.dg/torture/float32x-tg-4.c: Likewise.
	* gcc.dg/torture/float64-tg-4.c: Likewise.
	* gcc.dg/torture/float64x-tg-4.c: Likewise.
	* gcc.dg/pr28796-1.c: Add -O2.
	* gcc.dg/builtins-43.c: Check lower instead of gimple.
	* gcc.dg/tg-tests.h: Add iszero and issubnormal.
	* gcc.dg/pr77925.c: Add to test safe cases.

From-SVN: r249005
parent fb4bc6ff
2017-06-08 Tamar Christina <tamar.christina@arm.com>
PR middle-end/77925
PR middle-end/77926
PR middle-end/66462
* gcc/builtins.c (fold_builtin_fpclassify): Remove.
(fold_builtin_interclass_mathfn): Remove.
(expand_builtin): Add builtins to lowering list.
(fold_builtin_n): Remove fold_builtin_varargs.
(fold_builtin_varargs): Remove.
* gcc/builtins.def (BUILT_IN_ISZERO, BUILT_IN_ISSUBNORMAL): New.
* gcc/real.h (get_min_float): New.
(real_format): Add is_ieee_compatible field.
* gcc/real.c (get_min_float): New.
(ieee_single_format): Set is_ieee_compatible flag.
* gcc/gimple-low.c (lower_stm): Define BUILT_IN_FPCLASSIFY,
CASE_FLT_FN (BUILT_IN_ISINF), BUILT_IN_ISINFD32, BUILT_IN_ISINFD64,
BUILT_IN_ISINFD128, BUILT_IN_ISNAND32, BUILT_IN_ISNAND64,
BUILT_IN_ISNAND128, BUILT_IN_ISNAN, BUILT_IN_ISNORMAL, BUILT_IN_ISZERO,
BUILT_IN_ISSUBNORMAL, CASE_FLT_FN (BUILT_IN_FINITE), BUILT_IN_FINITED32
BUILT_IN_FINITED64, BUILT_IN_FINITED128, BUILT_IN_ISFINITE.
(lower_builtin_fpclassify, is_nan, is_normal, is_infinity): New.
(is_zero, is_subnormal, is_finite, use_ieee_int_mode): Likewise.
(lower_builtin_isnan, lower_builtin_isinfinite): Likewise.
(lower_builtin_isnormal, lower_builtin_iszero): Likewise.
(lower_builtin_issubnormal, lower_builtin_isfinite): Likewise.
(emit_tree_cond, get_num_as_int, emit_tree_and_return_var): New.
(mips_single_format): Likewise.
(motorola_single_format): Likewise.
(spu_single_format): Likewise.
(ieee_double_format): Likewise.
(mips_double_format): Likewise.
(motorola_double_format): Likewise.
(ieee_extended_motorola_format): Likewise.
(ieee_extended_intel_128_format): Likewise.
(ieee_extended_intel_96_round_53_format): Likewise.
(ibm_extended_format): Likewise.
(mips_extended_format): Likewise.
(ieee_quad_format): Likewise.
(mips_quad_format): Likewise.
(vax_f_format): Likewise.
(vax_d_format): Likewise.
(vax_g_format): Likewise.
(decimal_single_format): Likewise.
(decimal_quad_format): Likewise.
(iee_half_format): Likewise.
(mips_single_format): Likewise.
(arm_half_format): Likewise.
(real_internal_format): Likewise.
* gcc/doc/extend.texi: Add documentation for built-ins.
* gcc/c/c-typeck.c (convert_arguments): Add BUILT_IN_ISZERO
and BUILT_IN_ISSUBNORMAL.
2017-06-07 Carl Love <cel@us.ibm.com>
* config/rs6000/rs6000-c: The return type of the following
......
......@@ -845,6 +845,8 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CO
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_ISZERO, "iszero", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_ISSUBNORMAL, "issubnormal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
......
......@@ -3241,6 +3241,8 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
case BUILT_IN_ISINF_SIGN:
case BUILT_IN_ISNAN:
case BUILT_IN_ISNORMAL:
case BUILT_IN_ISZERO:
case BUILT_IN_ISSUBNORMAL:
case BUILT_IN_FPCLASSIFY:
type_generic_remove_excess_precision = true;
break;
......
......@@ -10501,6 +10501,10 @@ in the Cilk Plus language manual which can be found at
@findex __builtin_isgreater
@findex __builtin_isgreaterequal
@findex __builtin_isinf_sign
@findex __builtin_isinf
@findex __builtin_isnan
@findex __builtin_iszero
@findex __builtin_issubnormal
@findex __builtin_isless
@findex __builtin_islessequal
@findex __builtin_islessgreater
......@@ -11564,7 +11568,54 @@ constant values and they must appear in this order: @code{FP_NAN},
@code{FP_INFINITE}, @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.
means it does not do default promotion from @code{float} to @code{double}.
@end deftypefn
@deftypefn {Built-in Function} int __builtin_isnan (...)
This built-in implements the C99 isnan functionality which checks if
the given argument represents a NaN. The return value of the
function will either be a 0 (false) or a 1 (true).
On most systems, when an IEEE 754 floating-point type is used this
built-in does not produce a signal when a signaling NaN is used.
GCC treats the argument as type-generic, which means it does
not do default promotion from @code{float} to @code{double}.
@end deftypefn
@deftypefn {Built-in Function} int __builtin_isinf (...)
This built-in implements the C99 isinf functionality which checks if
the given argument represents an infinite number. The return
value of the function will either be a 0 (false) or a 1 (true).
GCC treats the argument as type-generic, which means it does
not do default promotion from @code{float} to @code{double}.
@end deftypefn
@deftypefn {Built-in Function} int __builtin_isnormal (...)
This built-in implements the C99 isnormal functionality which checks if
the given argument represents a normal number. The return
value of the function will either be a 0 (false) or a 1 (true).
GCC treats the argument as type-generic, which means it does
not do default promotion from @code{float} to @code{double}.
@end deftypefn
@deftypefn {Built-in Function} int __builtin_iszero (...)
This built-in implements the TS 18661-1:2014 iszero functionality which checks if
the given argument represents the number 0 or -0. The return
value of the function will either be a 0 (false) or a 1 (true).
GCC treats the argument as type-generic, which means it does
not do default promotion from @code{float} to @code{double}.
@end deftypefn
@deftypefn {Built-in Function} int __builtin_issubnormal (...)
This built-in implements the TS 18661-1:2014 issubnormal functionality which checks if
the given argument represents a subnormal number. The return
value of the function will either be a 0 (false) or a 1 (true).
GCC treats the argument as type-generic, which means it does
not do default promotion from @code{float} to @code{double}.
@end deftypefn
@deftypefn {Built-in Function} double __builtin_inf (void)
......
......@@ -3052,6 +3052,7 @@ const struct real_format ieee_single_format =
true,
true,
false,
true,
"ieee_single"
};
......@@ -3075,6 +3076,7 @@ const struct real_format mips_single_format =
true,
false,
true,
true,
"mips_single"
};
......@@ -3098,6 +3100,7 @@ const struct real_format motorola_single_format =
true,
true,
true,
true,
"motorola_single"
};
......@@ -3132,6 +3135,7 @@ const struct real_format spu_single_format =
true,
false,
false,
false,
"spu_single"
};
......@@ -3343,6 +3347,7 @@ const struct real_format ieee_double_format =
true,
true,
false,
true,
"ieee_double"
};
......@@ -3366,6 +3371,7 @@ const struct real_format mips_double_format =
true,
false,
true,
true,
"mips_double"
};
......@@ -3389,6 +3395,7 @@ const struct real_format motorola_double_format =
true,
true,
true,
true,
"motorola_double"
};
......@@ -3735,6 +3742,7 @@ const struct real_format ieee_extended_motorola_format =
true,
true,
true,
false,
"ieee_extended_motorola"
};
......@@ -3758,6 +3766,7 @@ const struct real_format ieee_extended_intel_96_format =
true,
true,
false,
false,
"ieee_extended_intel_96"
};
......@@ -3781,6 +3790,7 @@ const struct real_format ieee_extended_intel_128_format =
true,
true,
false,
false,
"ieee_extended_intel_128"
};
......@@ -3806,6 +3816,7 @@ const struct real_format ieee_extended_intel_96_round_53_format =
true,
true,
false,
false,
"ieee_extended_intel_96_round_53"
};
......@@ -3896,6 +3907,7 @@ const struct real_format ibm_extended_format =
true,
true,
false,
false,
"ibm_extended"
};
......@@ -3919,6 +3931,7 @@ const struct real_format mips_extended_format =
true,
false,
true,
false,
"mips_extended"
};
......@@ -4184,6 +4197,7 @@ const struct real_format ieee_quad_format =
true,
true,
false,
true,
"ieee_quad"
};
......@@ -4207,6 +4221,7 @@ const struct real_format mips_quad_format =
true,
false,
true,
true,
"mips_quad"
};
......@@ -4509,6 +4524,7 @@ const struct real_format vax_f_format =
false,
false,
false,
false,
"vax_f"
};
......@@ -4532,6 +4548,7 @@ const struct real_format vax_d_format =
false,
false,
false,
false,
"vax_d"
};
......@@ -4555,6 +4572,7 @@ const struct real_format vax_g_format =
false,
false,
false,
false,
"vax_g"
};
......@@ -4633,6 +4651,7 @@ const struct real_format decimal_single_format =
true,
true,
false,
false,
"decimal_single"
};
......@@ -4657,6 +4676,7 @@ const struct real_format decimal_double_format =
true,
true,
false,
false,
"decimal_double"
};
......@@ -4681,6 +4701,7 @@ const struct real_format decimal_quad_format =
true,
true,
false,
false,
"decimal_quad"
};
......@@ -4820,6 +4841,7 @@ const struct real_format ieee_half_format =
true,
true,
false,
true,
"ieee_half"
};
......@@ -4846,6 +4868,7 @@ const struct real_format arm_half_format =
true,
false,
false,
false,
"arm_half"
};
......@@ -4893,6 +4916,7 @@ const struct real_format real_internal_format =
true,
true,
false,
false,
"real_internal"
};
......@@ -5080,6 +5104,16 @@ get_max_float (const struct real_format *fmt, char *buf, size_t len)
gcc_assert (strlen (buf) < len);
}
/* Write into BUF the minimum negative representable finite floating-point
number, x, such that b**(x-1) is normalized.
BUF must be large enough to contain the result. */
void
get_min_float (const struct real_format *fmt, char *buf, size_t len)
{
sprintf (buf, "0x1p%d", fmt->emin - 1);
gcc_assert (strlen (buf) < len);
}
/* True if mode M has a NaN representation and
the treatment of NaN operands is important. */
......
......@@ -161,6 +161,19 @@ struct real_format
bool has_signed_zero;
bool qnan_msb_set;
bool canonical_nan_lsbs_set;
/* This flag indicates whether the format is suitable for the optimized
code paths for the __builtin_fpclassify function and friends. For
this, the format must be a base 2 representation with the sign bit as
the most-significant bit followed by (exp <= 32) exponent bits
followed by the mantissa bits. It must be possible to interpret the
bits of the floating-point representation as an integer. NaNs and
INFs (if available) must be represented by the same schema used by
IEEE 754. (NaNs must be represented by an exponent with all bits 1,
any mantissa except all bits 0 and any sign bit. +INF and -INF must be
represented by an exponent with all bits 1, a mantissa with all bits 0 and
a sign bit of 0 and 1 respectively.) */
bool is_binary_ieee_compatible;
const char *name;
};
......@@ -511,6 +524,11 @@ extern bool real_isinteger (const REAL_VALUE_TYPE *, HOST_WIDE_INT *);
float string. BUF must be large enough to contain the result. */
extern void get_max_float (const struct real_format *, char *, size_t);
/* Write into BUF the smallest positive normalized number x,
such that b**(x-1) is normalized. BUF must be large enough
to contain the result. */
extern void get_min_float (const struct real_format *, char *, size_t);
#ifndef GENERATOR_FILE
/* real related routines. */
extern wide_int real_to_integer (const REAL_VALUE_TYPE *, bool *, int);
......
2017-06-08 Tamar Christina <tamar.christina@arm.com>
* gcc.target/aarch64/builtin-fpclassify.c: New codegen test.
* gcc.dg/fold-notunord.c: Removed.
* gcc.dg/torture/floatn-tg-4.h: Add tests for iszero and issubnormal.
* gcc.dg/torture/float128-tg-4.c: Likewise.
* gcc.dg/torture/float128x-tg-4: Likewise.
* gcc.dg/torture/float16-tg-4.c: Likewise.
* gcc.dg/torture/float32-tg-4.c: Likewise.
* gcc.dg/torture/float32x-tg-4.c: Likewise.
* gcc.dg/torture/float64-tg-4.c: Likewise.
* gcc.dg/torture/float64x-tg-4.c: Likewise.
* gcc.dg/pr28796-1.c: Add -O2.
* gcc.dg/builtins-43.c: Check lower instead of gimple.
* gcc.dg/tg-tests.h: Add iszero and issubnormal.
* gcc.dg/pr77925.c: Add to test safe cases.
2017-06-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/80928
......
/* { dg-do compile } */
/* { dg-options "-O1 -fno-trapping-math -fno-finite-math-only -fdump-tree-gimple -fdump-tree-optimized" } */
/* { dg-options "-O1 -fno-trapping-math -fno-finite-math-only -fdump-tree-lower -fdump-tree-optimized" } */
extern void f(int);
extern void link_error ();
......@@ -51,7 +51,7 @@ main ()
/* Check that all instances of __builtin_isnan were folded. */
/* { dg-final { scan-tree-dump-times "isnan" 0 "gimple" } } */
/* { dg-final { scan-tree-dump-times "isnan" 0 "lower" } } */
/* Check that all instances of link_error were subject to DCE. */
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O -ftrapping-math -fdump-tree-optimized" } */
int f (double d)
{
return !__builtin_isnan (d);
}
/* { dg-final { scan-tree-dump " ord " "optimized" } } */
/* { dg-do link } */
/* { dg-options "-ffinite-math-only" } */
/* { dg-options "-ffinite-math-only -O2" } */
extern void link_error(void);
......
/* { dg-do run } */
/* { dg-options "-O2" } */
/* { dg-add-options ieee } */
/* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */
#include "tg-tests.h"
int main(void)
{
return main_tests ();
}
......@@ -11,6 +11,7 @@ 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_iszero, int res_issubnorm,
int res_signbit, int classification)
{
if (__builtin_isunordered (f, 0) != res_unord)
......@@ -80,6 +81,29 @@ foo_1 (float f, double d, long double ld,
if (__builtin_finitel (ld) != res_isfin)
__builtin_abort ();
/* On CPUs which flush denormals to zero these tests can never work one
denormals for the floating point version of the implementation. The integer
versions would work fine but we can't detect which version we have here. */
#ifdef UNSAFE
if (!res_issubnorm) {
#endif
if (__builtin_iszero (f) != res_iszero)
__builtin_abort ();
if (__builtin_iszero (d) != res_iszero)
__builtin_abort ();
if (__builtin_iszero (ld) != res_iszero)
__builtin_abort ();
if (__builtin_issubnormal (f) != res_issubnorm)
__builtin_abort ();
if (__builtin_issubnormal (d) != res_issubnorm)
__builtin_abort ();
if (__builtin_issubnormal (ld) != res_issubnorm)
__builtin_abort ();
#ifdef UNSAFE
}
#endif
/* Sign bit of zeros and nans is not preserved in unsafe math mode. */
#ifdef UNSAFE
if (!res_isnan && f != 0 && d != 0 && ld != 0)
......@@ -115,12 +139,13 @@ foo_1 (float f, double d, long double ld,
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 classification)
int res_isfin, int res_isnorm, int res_iszero,
int res_issubnorm, int classification)
{
foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm, 0, classification);
foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm, res_iszero, res_issubnorm, 0, classification);
/* Try all the values negated as well. All will have the sign bit set,
except for the nan. */
foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm, 1, classification);
foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm, res_iszero, res_issubnorm, 1, classification);
}
int __attribute__ ((__noinline__))
......@@ -132,35 +157,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, FP_NAN);
foo(f, d, ld, /*unord=*/ 1, /*isnan=*/ 1, /*isinf=*/ 0, /*isfin=*/ 0, /*isnorm=*/ 0, /*iszero=*/0, /*issubnorm=*/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, FP_INFINITE);
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0, /*iszero=*/0, /*issubnorm=*/0, FP_INFINITE);
/* Test zero. */
f = 0; d = 0; ld = 0;
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0, FP_ZERO);
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0, /*iszero=*/1, /*issubnorm=*/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, FP_NORMAL);
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, /*iszero=*/0, /*issubnorm=*/0, 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, FP_NORMAL);
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, /*iszero=*/0, /*issubnorm=*/0, 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, FP_SUBNORMAL);
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0, /*iszero=*/0, /*issubnorm=*/1, 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, FP_NORMAL);
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, /*iszero=*/0, /*issubnorm=*/0, 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, FP_INFINITE);
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0, /*iszero=*/0, /*issubnorm=*/0, FP_INFINITE);
return 0;
}
/* Test _Float128 type-generic built-in functions: __builtin_iszero,
__builtin_issubnormal. */
/* { dg-do run } */
/* { dg-options "" } */
/* { dg-add-options float128 } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target float128_runtime } */
#define WIDTH 128
#define EXT 0
#include "floatn-tg-4.h"
/* Test _Float128x type-generic built-in functions: __builtin_iszero,
__builtin_issubnormal. */
/* { dg-do run } */
/* { dg-options "" } */
/* { dg-add-options float128x } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target float128x_runtime } */
#define WIDTH 128
#define EXT 1
#include "floatn-tg-4.h"
/* Test _Float16 type-generic built-in functions: __builtin_iszero,
__builtin_issubnormal. */
/* { dg-do run } */
/* { dg-options "" } */
/* { dg-add-options float16 } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target float16_runtime } */
#define WIDTH 16
#define EXT 0
#include "floatn-tg-4.h"
/* Test _Float32 type-generic built-in functions: __builtin_f__builtin_iszero,
__builtin_issubnormal. */
/* { dg-do run } */
/* { dg-options "" } */
/* { dg-add-options float32 } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target float32_runtime } */
#define WIDTH 32
#define EXT 0
#include "floatn-tg-4.h"
/* Test _Float32x type-generic built-in functions: __builtin_iszero,
__builtin_issubnormal. */
/* { dg-do run } */
/* { dg-options "" } */
/* { dg-add-options float32x } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target float32x_runtime } */
#define WIDTH 32
#define EXT 1
#include "floatn-tg-4.h"
/* Test _Float64 type-generic built-in functions: __builtin_iszero,
__builtin_issubnormal */
/* { dg-do run } */
/* { dg-options "" } */
/* { dg-add-options float64 } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target float64_runtime } */
#define WIDTH 64
#define EXT 0
#include "floatn-tg-4.h"
/* Test _Float64x type-generic built-in functions: __builtin_iszero,
__builtin_issubnormal. */
/* { dg-do run } */
/* { dg-options "" } */
/* { dg-add-options float64x } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target float64x_runtime } */
#define WIDTH 64
#define EXT 1
#include "floatn-tg-4.h"
/* Tests for _FloatN / _FloatNx types: compile and execution tests for
type-generic built-in functions: __builtin_iszero, __builtin_issubnormal.
Before including this file, define WIDTH as the value N; define EXT to 1
for _FloatNx and 0 for _FloatN. */
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <float.h>
#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 MAX CONCAT3 (FLT, WIDTH, X_MAX)
# define MIN CONCAT3 (FLT, WIDTH, X_MIN)
# define TRUE_MIN CONCAT3 (FLT, WIDTH, X_TRUE_MIN)
#else
# define TYPE CONCAT (_Float, WIDTH)
# define CST(C) CONCAT3 (C, f, WIDTH)
# define MAX CONCAT3 (FLT, WIDTH, _MAX)
# define MIN CONCAT3 (FLT, WIDTH, _MIN)
# define TRUE_MIN CONCAT3 (FLT, WIDTH, _TRUE_MIN)
#endif
extern void exit (int);
extern void abort (void);
volatile TYPE inf = __builtin_inf (), nanval = __builtin_nan ("");
volatile TYPE neginf = -__builtin_inf (), negnanval = -__builtin_nan ("");
volatile TYPE zero = CST (0.0), negzero = -CST (0.0), one = CST (1.0);
volatile TYPE max = MAX, negmax = -MAX, min = MIN, negmin = -MIN;
volatile TYPE true_min = TRUE_MIN, negtrue_min = -TRUE_MIN;
volatile TYPE sub_norm = MIN / 2.0;
int
main (void)
{
if (__builtin_iszero (inf) == 1)
abort ();
if (__builtin_iszero (nanval) == 1)
abort ();
if (__builtin_iszero (neginf) == 1)
abort ();
if (__builtin_iszero (negnanval) == 1)
abort ();
if (__builtin_iszero (zero) != 1)
abort ();
if (__builtin_iszero (negzero) != 1)
abort ();
if (__builtin_iszero (one) == 1)
abort ();
if (__builtin_iszero (max) == 1)
abort ();
if (__builtin_iszero (negmax) == 1)
abort ();
if (__builtin_iszero (min) == 1)
abort ();
if (__builtin_iszero (negmin) == 1)
abort ();
if (__builtin_iszero (true_min) == 1)
abort ();
if (__builtin_iszero (negtrue_min) == 1)
abort ();
if (__builtin_iszero (sub_norm) == 1)
abort ();
if (__builtin_issubnormal (inf) == 1)
abort ();
if (__builtin_issubnormal (nanval) == 1)
abort ();
if (__builtin_issubnormal (neginf) == 1)
abort ();
if (__builtin_issubnormal (negnanval) == 1)
abort ();
if (__builtin_issubnormal (zero) == 1)
abort ();
if (__builtin_issubnormal (negzero) == 1)
abort ();
if (__builtin_issubnormal (one) == 1)
abort ();
if (__builtin_issubnormal (max) == 1)
abort ();
if (__builtin_issubnormal (negmax) == 1)
abort ();
if (__builtin_issubnormal (min) == 1)
abort ();
if (__builtin_issubnormal (negmin) == 1)
abort ();
if (__builtin_issubnormal (true_min) != 1)
abort ();
if (__builtin_issubnormal (negtrue_min) != 1)
abort ();
if (__builtin_issubnormal (sub_norm) != 1)
abort ();
exit (0);
}
/* This file checks the code generation for the new __builtin_fpclassify.
because checking the exact assembly isn't very useful, we'll just be checking
for the presence of certain instructions and the omition of others. */
/* { dg-options "-O2" } */
/* { dg-do compile } */
/* { dg-final { scan-assembler-not "\[ \t\]?fabs\[ \t\]?" } } */
/* { dg-final { scan-assembler-not "\[ \t\]?fcmp\[ \t\]?" } } */
/* { dg-final { scan-assembler-not "\[ \t\]?fcmpe\[ \t\]?" } } */
/* { dg-final { scan-assembler "\[ \t\]?ubfx\[ \t\]?" } } */
#include <stdio.h>
#include <math.h>
/*
fp_nan = args[0];
fp_infinite = args[1];
fp_normal = args[2];
fp_subnormal = args[3];
fp_zero = args[4];
*/
int f(double x) { return __builtin_fpclassify(0, 1, 4, 3, 2, x); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment