Extract truncsfbf check into truncsfbf-check.h and remove duplicated
codes in truncsfbf-2.c, runcsfbf-5.c and truncsfbf-6.c.
PR target/126933
* gcc.target/i386/truncsfbf-2.c: Require sse2_runtime.
Include "truncsfbf-check.h".
(main): Call do_test ().
* gcc.target/i386/truncsfbf-5.c (dg-options): Add -save-temps.
(ATTRIBUTE): New.
Include "truncsfbf-check.h".
Scan "\t{vex} vcvtneps2bf16".
* gcc.target/i386/truncsfbf-6.c (dg-options): Add -save-temps.
(ATTRIBUTE): New.
Include "truncsfbf-check.h".
Scan "\tvcvtneps2bf16".
* gcc.target/i386/truncsfbf-check.h: New file.
--
H.J.
From 4f4beae80e44628345bc68c5f1b6685e6bcc2827 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Tue, 25 Aug 2026 04:46:07 +0800
Subject: [PATCH] x86: Improve truncsfbf tests
Extract truncsfbf check into truncsfbf-check.h and remove duplicated
codes in truncsfbf-2.c, runcsfbf-5.c and truncsfbf-6.c.
PR target/126933
* gcc.target/i386/truncsfbf-2.c: Require sse2_runtime.
Include "truncsfbf-check.h".
(main): Call do_test ().
* gcc.target/i386/truncsfbf-5.c (dg-options): Add -save-temps.
(ATTRIBUTE): New.
Include "truncsfbf-check.h".
Scan "\t{vex} vcvtneps2bf16".
* gcc.target/i386/truncsfbf-6.c (dg-options): Add -save-temps.
(ATTRIBUTE): New.
Include "truncsfbf-check.h".
Scan "\tvcvtneps2bf16".
* gcc.target/i386/truncsfbf-check.h: New file.
Signed-off-by: H.J. Lu <[email protected]>
---
gcc/testsuite/gcc.target/i386/truncsfbf-2.c | 89 +----------------
gcc/testsuite/gcc.target/i386/truncsfbf-5.c | 95 +------------------
gcc/testsuite/gcc.target/i386/truncsfbf-6.c | 95 +------------------
.../gcc.target/i386/truncsfbf-check.h | 95 +++++++++++++++++++
4 files changed, 108 insertions(+), 266 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/truncsfbf-check.h
diff --git a/gcc/testsuite/gcc.target/i386/truncsfbf-2.c b/gcc/testsuite/gcc.target/i386/truncsfbf-2.c
index c33ad8b0df6..44e4f3bb3d9 100644
--- a/gcc/testsuite/gcc.target/i386/truncsfbf-2.c
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-2.c
@@ -1,94 +1,11 @@
-/* { dg-do run } */
+/* { dg-do run { target sse2_runtime } } */
/* { dg-options "-msse2 -O2 -ffast-math -mno-avxneconvert -mno-avx512bf16" } */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <math.h>
-
-__attribute__ ((noipa, noinline))
-static __bf16
-foo (float a)
-{
- return a;
-}
-
-__attribute__ ((noipa, noinline))
-static __bf16
-CALC (float *a)
-{
- uint32_t bits;
- memcpy (&bits, a, sizeof (bits));
- /* Flush input denormal to zero like vcvtneps2bf16. */
- if ((bits & 0x7f800000) == 0)
- {
- bits >>= 16;
- bits &= 0x8000;
- }
- else
- {
- uint32_t rounding_bias = 0x7FFF + ((bits >> 16) & 1);
- bits += rounding_bias;
- bits >>= 16;
- }
- __bf16 bf16;
- uint16_t bfloat16_bits = (uint16_t) bits;
- memcpy (&bf16, &bfloat16_bits, sizeof (bf16));
- return bf16;
-}
+#include "truncsfbf-check.h"
int
main (void)
{
- float test_values[] =
- {
- 0.0f, -0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 1000.0f, -1000.0f,
- 3.1415926f, -3.1415926f, 1e-8f, -1e-8f, 1.0e+38f, -1.0e+38f,
- 1.0e-38f, -1.0e-38f, 1.170903e-38, -1.170903e-38, 1.175494e-38,
- -1.175494e-38, 1.170902e-38, 4.999295e-39, 1.175494e-38
- };
- size_t num_values = sizeof (test_values) / sizeof (test_values[0]);
- bool failed = false;
-
- for (size_t i = 0; i < num_values; ++i)
- {
- float original = test_values[i];
- __bf16 hw_bf16 = foo (original);
- __bf16 sw_bf16 = CALC (&original);
-
- /* Verify psrld $16, %0 == %0 >> 16 */
- if (memcmp (&hw_bf16, &sw_bf16, sizeof (__bf16)) != 0)
- {
- printf ("float -> bf16 failed: %d, %e\n", i, original);
- failed = true;
- }
-
- /* Reconstruct the float value from the __bf16 bits */
- uint16_t bf16_bits;
- memcpy (&bf16_bits, &hw_bf16, sizeof (bf16_bits));
- uint32_t reconstructed_bits = ((uint32_t) bf16_bits) << 16;
- float converted;
- memcpy (&converted, &reconstructed_bits, sizeof (converted));
-
- float diff = fabsf (original - converted);
-
- /* Expected Maximum Precision Loss */
- uint32_t orig_bits;
- memcpy (&orig_bits, &original, sizeof (orig_bits));
- int exponent = ((orig_bits >> 23) & 0xFF) - 127;
- float expected_loss = (exponent == -127)
- ? ldexpf (1.0f, -126 - 7)
- : ldexpf (1.0f, exponent - 7);
- if (diff > expected_loss)
- {
- printf ("bf16 -> float failed: %d, %e\n", i, original);
- failed = true;
- }
- }
-
- if (failed)
- abort ();
-
+ do_test ();
return 0;
}
diff --git a/gcc/testsuite/gcc.target/i386/truncsfbf-5.c b/gcc/testsuite/gcc.target/i386/truncsfbf-5.c
index c6595262f81..36a572f4618 100644
--- a/gcc/testsuite/gcc.target/i386/truncsfbf-5.c
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-5.c
@@ -1,96 +1,9 @@
/* { dg-do run } */
-/* { dg-options "-O2 -ffast-math -march=x86-64" } */
+/* { dg-options "-O2 -ffast-math -march=x86-64 -save-temps" } */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <math.h>
+#define ATTRIBUTE __attribute__ ((target("avxneconvert")))
-__attribute__ ((noipa, noinline, target("avxneconvert")))
-static __bf16
-foo (float a)
-{
- return a;
-}
-
-__attribute__ ((noipa, noinline))
-static __bf16
-CALC (float *a)
-{
- uint32_t bits;
- memcpy (&bits, a, sizeof (bits));
- /* Flush input denormal to zero like vcvtneps2bf16. */
- if ((bits & 0x7f800000) == 0)
- {
- bits >>= 16;
- bits &= 0x8000;
- }
- else
- {
- uint32_t rounding_bias = 0x7FFF + ((bits >> 16) & 1);
- bits += rounding_bias;
- bits >>= 16;
- }
- __bf16 bf16;
- uint16_t bfloat16_bits = (uint16_t) bits;
- memcpy (&bf16, &bfloat16_bits, sizeof (bf16));
- return bf16;
-}
-
-__attribute__ ((noipa, noinline))
-static void
-do_test (void)
-{
- float test_values[] =
- {
- 0.0f, -0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 1000.0f, -1000.0f,
- 3.1415926f, -3.1415926f, 1e-8f, -1e-8f, 1.0e+38f, -1.0e+38f,
- 1.0e-38f, -1.0e-38f, 1.170903e-38, -1.170903e-38, 1.175494e-38,
- -1.175494e-38, 1.170902e-38, 4.999295e-39, 1.175494e-38
- };
- size_t num_values = sizeof (test_values) / sizeof (test_values[0]);
- bool failed = false;
-
- for (size_t i = 0; i < num_values; ++i)
- {
- float original = test_values[i];
- __bf16 hw_bf16 = foo (original);
- __bf16 sw_bf16 = CALC (&original);
-
- /* Verify psrld $16, %0 == %0 >> 16 */
- if (memcmp (&hw_bf16, &sw_bf16, sizeof (__bf16)) != 0)
- {
- printf ("float -> bf16 failed: %d, %e\n", i, original);
- failed = true;
- }
-
- /* Reconstruct the float value from the __bf16 bits */
- uint16_t bf16_bits;
- memcpy (&bf16_bits, &hw_bf16, sizeof (bf16_bits));
- uint32_t reconstructed_bits = ((uint32_t) bf16_bits) << 16;
- float converted;
- memcpy (&converted, &reconstructed_bits, sizeof (converted));
-
- float diff = fabsf (original - converted);
-
- /* Expected Maximum Precision Loss */
- uint32_t orig_bits;
- memcpy (&orig_bits, &original, sizeof (orig_bits));
- int exponent = ((orig_bits >> 23) & 0xFF) - 127;
- float expected_loss = (exponent == -127)
- ? ldexpf (1.0f, -126 - 7)
- : ldexpf (1.0f, exponent - 7);
- if (diff > expected_loss)
- {
- printf ("bf16 -> float failed: %d, %e\n", i, original);
- failed = true;
- }
- }
-
- if (failed)
- abort ();
-}
+#include "truncsfbf-check.h"
int
main (void)
@@ -100,3 +13,5 @@ main (void)
return 0;
}
+
+/* { dg-final { scan-assembler-times "\t{vex} vcvtneps2bf16" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/truncsfbf-6.c b/gcc/testsuite/gcc.target/i386/truncsfbf-6.c
index 3b1707b99c2..e5223e1b19b 100644
--- a/gcc/testsuite/gcc.target/i386/truncsfbf-6.c
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-6.c
@@ -1,96 +1,9 @@
/* { dg-do run } */
-/* { dg-options "-O2 -ffast-math -march=x86-64" } */
+/* { dg-options "-O2 -ffast-math -march=x86-64 -save-temps" } */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <math.h>
+#define ATTRIBUTE __attribute__ ((target("avx512vl,avx512bf16")))
-__attribute__ ((noipa, noinline, target("avx512vl,avx512bf16")))
-static __bf16
-foo (float a)
-{
- return a;
-}
-
-__attribute__ ((noipa, noinline))
-static __bf16
-CALC (float *a)
-{
- uint32_t bits;
- memcpy (&bits, a, sizeof (bits));
- /* Flush input denormal to zero like vcvtneps2bf16. */
- if ((bits & 0x7f800000) == 0)
- {
- bits >>= 16;
- bits &= 0x8000;
- }
- else
- {
- uint32_t rounding_bias = 0x7FFF + ((bits >> 16) & 1);
- bits += rounding_bias;
- bits >>= 16;
- }
- __bf16 bf16;
- uint16_t bfloat16_bits = (uint16_t) bits;
- memcpy (&bf16, &bfloat16_bits, sizeof (bf16));
- return bf16;
-}
-
-__attribute__ ((noipa, noinline))
-static void
-do_test (void)
-{
- float test_values[] =
- {
- 0.0f, -0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 1000.0f, -1000.0f,
- 3.1415926f, -3.1415926f, 1e-8f, -1e-8f, 1.0e+38f, -1.0e+38f,
- 1.0e-38f, -1.0e-38f, 1.170903e-38, -1.170903e-38, 1.175494e-38,
- -1.175494e-38, 1.170902e-38, 4.999295e-39, 1.175494e-38
- };
- size_t num_values = sizeof (test_values) / sizeof (test_values[0]);
- bool failed = false;
-
- for (size_t i = 0; i < num_values; ++i)
- {
- float original = test_values[i];
- __bf16 hw_bf16 = foo (original);
- __bf16 sw_bf16 = CALC (&original);
-
- /* Verify psrld $16, %0 == %0 >> 16 */
- if (memcmp (&hw_bf16, &sw_bf16, sizeof (__bf16)) != 0)
- {
- printf ("float -> bf16 failed: %d, %e\n", i, original);
- failed = true;
- }
-
- /* Reconstruct the float value from the __bf16 bits */
- uint16_t bf16_bits;
- memcpy (&bf16_bits, &hw_bf16, sizeof (bf16_bits));
- uint32_t reconstructed_bits = ((uint32_t) bf16_bits) << 16;
- float converted;
- memcpy (&converted, &reconstructed_bits, sizeof (converted));
-
- float diff = fabsf (original - converted);
-
- /* Expected Maximum Precision Loss */
- uint32_t orig_bits;
- memcpy (&orig_bits, &original, sizeof (orig_bits));
- int exponent = ((orig_bits >> 23) & 0xFF) - 127;
- float expected_loss = (exponent == -127)
- ? ldexpf (1.0f, -126 - 7)
- : ldexpf (1.0f, exponent - 7);
- if (diff > expected_loss)
- {
- printf ("bf16 -> float failed: %d, %e\n", i, original);
- failed = true;
- }
- }
-
- if (failed)
- abort ();
-}
+#include "truncsfbf-check.h"
int
main (void)
@@ -101,3 +14,5 @@ main (void)
return 0;
}
+
+/* { dg-final { scan-assembler-times "\tvcvtneps2bf16" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/truncsfbf-check.h b/gcc/testsuite/gcc.target/i386/truncsfbf-check.h
new file mode 100644
index 00000000000..f0e2f0475d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-check.h
@@ -0,0 +1,95 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+
+#ifndef ATTRIBUTE
+#define ATTRIBUTE
+#endif
+
+ATTRIBUTE
+__attribute__ ((noipa, noinline))
+static __bf16
+foo (float a)
+{
+ return a;
+}
+
+__attribute__ ((noipa, noinline))
+static __bf16
+CALC (float *a)
+{
+ uint32_t bits;
+ memcpy (&bits, a, sizeof (bits));
+ /* Flush input denormal to zero like vcvtneps2bf16. */
+ if ((bits & 0x7f800000) == 0)
+ {
+ bits >>= 16;
+ bits &= 0x8000;
+ }
+ else
+ {
+ uint32_t rounding_bias = 0x7FFF + ((bits >> 16) & 1);
+ bits += rounding_bias;
+ bits >>= 16;
+ }
+ __bf16 bf16;
+ uint16_t bfloat16_bits = (uint16_t) bits;
+ memcpy (&bf16, &bfloat16_bits, sizeof (bf16));
+ return bf16;
+}
+
+__attribute__ ((noipa, noinline))
+void
+do_test (void)
+{
+ float test_values[] =
+ {
+ 0.0f, -0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 1000.0f, -1000.0f,
+ 3.1415926f, -3.1415926f, 1e-8f, -1e-8f, 1.0e+38f, -1.0e+38f,
+ 1.0e-38f, -1.0e-38f, 1.170903e-38, -1.170903e-38, 1.175494e-38,
+ -1.175494e-38, 1.170902e-38, 4.999295e-39, 1.175494e-38
+ };
+ size_t num_values = sizeof (test_values) / sizeof (test_values[0]);
+ bool failed = false;
+
+ for (size_t i = 0; i < num_values; ++i)
+ {
+ float original = test_values[i];
+ __bf16 hw_bf16 = foo (original);
+ __bf16 sw_bf16 = CALC (&original);
+
+ /* Verify psrld $16, %0 == %0 >> 16 */
+ if (memcmp (&hw_bf16, &sw_bf16, sizeof (__bf16)) != 0)
+ {
+ printf ("float -> bf16 failed: %d, %e\n", i, original);
+ failed = true;
+ }
+
+ /* Reconstruct the float value from the __bf16 bits */
+ uint16_t bf16_bits;
+ memcpy (&bf16_bits, &hw_bf16, sizeof (bf16_bits));
+ uint32_t reconstructed_bits = ((uint32_t) bf16_bits) << 16;
+ float converted;
+ memcpy (&converted, &reconstructed_bits, sizeof (converted));
+
+ float diff = fabsf (original - converted);
+
+ /* Expected Maximum Precision Loss */
+ uint32_t orig_bits;
+ memcpy (&orig_bits, &original, sizeof (orig_bits));
+ int exponent = ((orig_bits >> 23) & 0xFF) - 127;
+ float expected_loss = (exponent == -127)
+ ? ldexpf (1.0f, -126 - 7)
+ : ldexpf (1.0f, exponent - 7);
+ if (diff > expected_loss)
+ {
+ printf ("bf16 -> float failed: %d, %e\n", i, original);
+ failed = true;
+ }
+ }
+
+ if (failed)
+ abort ();
+}
--
2.55.0