aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2017-06-08 07:38:42 +0000
committerTamar Christina <tnfchris@gcc.gnu.org>2017-06-08 07:38:42 +0000
commit94fc87ecdf45e2455deb7ee50e13765c98d4e904 (patch)
tree01e590119900d4a8b6df6a832bb5456d8a7fd03c /gcc/testsuite
parentfb4bc6ff6c08f4e5524fa5e1881b478b0f689155 (diff)
downloadgcc-94fc87ecdf45e2455deb7ee50e13765c98d4e904.zip
gcc-94fc87ecdf45e2455deb7ee50e13765c98d4e904.tar.gz
gcc-94fc87ecdf45e2455deb7ee50e13765c98d4e904.tar.bz2
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
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog17
-rw-r--r--gcc/testsuite/gcc.dg/builtins-43.c4
-rw-r--r--gcc/testsuite/gcc.dg/fold-notunord.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr28796-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr77925.c11
-rw-r--r--gcc/testsuite/gcc.dg/tg-tests.h47
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-tg-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128x-tg-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float16-tg-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32-tg-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32x-tg-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64-tg-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64x-tg-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-tg-4.h99
-rw-r--r--gcc/testsuite/gcc.target/aarch64/builtin-fpclassify.c22
15 files changed, 265 insertions, 23 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 52a0854..3899e20 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,20 @@
+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
diff --git a/gcc/testsuite/gcc.dg/builtins-43.c b/gcc/testsuite/gcc.dg/builtins-43.c
index f7c318e..5d41c28 100644
--- a/gcc/testsuite/gcc.dg/builtins-43.c
+++ b/gcc/testsuite/gcc.dg/builtins-43.c
@@ -1,5 +1,5 @@
/* { 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" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-notunord.c b/gcc/testsuite/gcc.dg/fold-notunord.c
deleted file mode 100644
index ca34515..0000000
--- a/gcc/testsuite/gcc.dg/fold-notunord.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* { 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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr28796-1.c b/gcc/testsuite/gcc.dg/pr28796-1.c
index 077118a..a57b4e3 100644
--- a/gcc/testsuite/gcc.dg/pr28796-1.c
+++ b/gcc/testsuite/gcc.dg/pr28796-1.c
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "-ffinite-math-only" } */
+/* { dg-options "-ffinite-math-only -O2" } */
extern void link_error(void);
diff --git a/gcc/testsuite/gcc.dg/pr77925.c b/gcc/testsuite/gcc.dg/pr77925.c
new file mode 100644
index 0000000..f92518b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr77925.c
@@ -0,0 +1,11 @@
+/* { 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 ();
+}
diff --git a/gcc/testsuite/gcc.dg/tg-tests.h b/gcc/testsuite/gcc.dg/tg-tests.h
index 0cf1f64..134bc82 100644
--- a/gcc/testsuite/gcc.dg/tg-tests.h
+++ b/gcc/testsuite/gcc.dg/tg-tests.h
@@ -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;
}
diff --git a/gcc/testsuite/gcc.dg/torture/float128-tg-4.c b/gcc/testsuite/gcc.dg/torture/float128-tg-4.c
new file mode 100644
index 0000000..ec9d3ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-tg-4.c
@@ -0,0 +1,11 @@
+/* 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"
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-tg-4.c b/gcc/testsuite/gcc.dg/torture/float128x-tg-4.c
new file mode 100644
index 0000000..0ede861
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-tg-4.c
@@ -0,0 +1,11 @@
+/* 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"
diff --git a/gcc/testsuite/gcc.dg/torture/float16-tg-4.c b/gcc/testsuite/gcc.dg/torture/float16-tg-4.c
new file mode 100644
index 0000000..007c4c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-tg-4.c
@@ -0,0 +1,11 @@
+/* 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"
diff --git a/gcc/testsuite/gcc.dg/torture/float32-tg-4.c b/gcc/testsuite/gcc.dg/torture/float32-tg-4.c
new file mode 100644
index 0000000..c7f8353
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-tg-4.c
@@ -0,0 +1,11 @@
+/* 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"
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-tg-4.c b/gcc/testsuite/gcc.dg/torture/float32x-tg-4.c
new file mode 100644
index 0000000..0d7a592
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-tg-4.c
@@ -0,0 +1,11 @@
+/* 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"
diff --git a/gcc/testsuite/gcc.dg/torture/float64-tg-4.c b/gcc/testsuite/gcc.dg/torture/float64-tg-4.c
new file mode 100644
index 0000000..bb25a22
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-tg-4.c
@@ -0,0 +1,11 @@
+/* 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"
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-tg-4.c b/gcc/testsuite/gcc.dg/torture/float64x-tg-4.c
new file mode 100644
index 0000000..82305d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-tg-4.c
@@ -0,0 +1,11 @@
+/* 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"
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-tg-4.h b/gcc/testsuite/gcc.dg/torture/floatn-tg-4.h
new file mode 100644
index 0000000..aa3448c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-tg-4.h
@@ -0,0 +1,99 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/builtin-fpclassify.c b/gcc/testsuite/gcc.target/aarch64/builtin-fpclassify.c
new file mode 100644
index 0000000..3a1bf956
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/builtin-fpclassify.c
@@ -0,0 +1,22 @@
+/* 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); }