On Tue, Aug 25, 2026 at 3:34 PM Liu, Hongtao <[email protected]> wrote:
>
>
>
> > -----Original Message-----
> > From: H.J. Lu <[email protected]>
> > Sent: Tuesday, August 25, 2026 10:30 AM
> > To: GCC Patches <[email protected]>; Uros Bizjak
> > <[email protected]>; Liu, Hongtao <[email protected]>
> > 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.
>
> *-check.h under gcc.target/i386 follows the style of main() + the ISA runtime
> guard,.i.e
> Int
> Main (void)
> {
> #ifdef CHECK_CPU_SUPPORTS
> If (CHECK_CPU_SUPPORTS)
> #endif
> do_test ();
> return 0;
> }
>
> Could you follow the original conversion? Move main from those .c files into
> the check.h and define those .c as options + #define + include?
Fixed in v2.
> And should we fflsuh(stdout) before abort () or use fprintf instead printf
> since the buffer in printf may be throw way when aborted.
Used fprintf (stderr, in v2.
Here is the v2 patch.
--
H.J.
--
Move 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".
* gcc.target/i386/truncsfbf-5.c (dg-options): Add -save-temps.
(CHECK_CPU_SUPPORTS): New.
(ATTRIBUTE): Likewise.
Include "truncsfbf-check.h".
Scan "\t{vex} vcvtneps2bf16".
* gcc.target/i386/truncsfbf-6.c (dg-options): Add -save-temps.
Include "truncsfbf-check.h".
(CHECK_CPU_SUPPORTS): New.
(ATTRIBUTE): Likewise.
Scan "\tvcvtneps2bf16".
* gcc.target/i386/truncsfbf-check.h: New file.
From 9f1175b293a58005540853fc9451cba005de81bd Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Tue, 25 Aug 2026 04:46:07 +0800
Subject: [PATCH v2] x86: Improve truncsfbf tests
Move 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".
* gcc.target/i386/truncsfbf-5.c (dg-options): Add -save-temps.
(CHECK_CPU_SUPPORTS): New.
(ATTRIBUTE): Likewise.
Include "truncsfbf-check.h".
Scan "\t{vex} vcvtneps2bf16".
* gcc.target/i386/truncsfbf-6.c (dg-options): Add -save-temps.
Include "truncsfbf-check.h".
(CHECK_CPU_SUPPORTS): New.
(ATTRIBUTE): Likewise.
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 | 94 +--------------
gcc/testsuite/gcc.target/i386/truncsfbf-5.c | 103 +----------------
gcc/testsuite/gcc.target/i386/truncsfbf-6.c | 105 +----------------
.../gcc.target/i386/truncsfbf-check.h | 107 ++++++++++++++++++
4 files changed, 120 insertions(+), 289 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..a048f8c8f42 100644
--- a/gcc/testsuite/gcc.target/i386/truncsfbf-2.c
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-2.c
@@ -1,94 +1,4 @@
-/* { 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;
-}
-
-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 ();
-
- return 0;
-}
+#include "truncsfbf-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/truncsfbf-5.c b/gcc/testsuite/gcc.target/i386/truncsfbf-5.c
index c6595262f81..a2ef701e124 100644
--- a/gcc/testsuite/gcc.target/i386/truncsfbf-5.c
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-5.c
@@ -1,102 +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 CHECK_CPU_SUPPORTS __builtin_cpu_supports ("avxneconvert")
+#define ATTRIBUTE __attribute__ ((target("avxneconvert")))
-__attribute__ ((noipa, noinline, target("avxneconvert")))
-static __bf16
-foo (float a)
-{
- return a;
-}
+#include "truncsfbf-check.h"
-__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 ();
-}
-
-int
-main (void)
-{
- if (__builtin_cpu_supports ("avxneconvert"))
- do_test ();
-
- 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..f8670449269 100644
--- a/gcc/testsuite/gcc.target/i386/truncsfbf-6.c
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-6.c
@@ -1,103 +1,10 @@
/* { 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 CHECK_CPU_SUPPORTS (__builtin_cpu_supports ("avx512vl") \
+ && __builtin_cpu_supports ("avx512bf16"))
+#define ATTRIBUTE __attribute__ ((target("avx512vl,avx512bf16")))
-__attribute__ ((noipa, noinline, target("avx512vl,avx512bf16")))
-static __bf16
-foo (float a)
-{
- return a;
-}
+#include "truncsfbf-check.h"
-__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 ();
-}
-
-int
-main (void)
-{
- if (__builtin_cpu_supports ("avx512vl")
- && __builtin_cpu_supports ("avx512bf16"))
- do_test ();
-
- 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..7f649e9f489
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/truncsfbf-check.h
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+
+#ifndef CHECK_CPU_SUPPORTS
+#define CHECK_CPU_SUPPORTS true
+#endif
+
+#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)
+ {
+ fprintf (stderr, "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)
+ {
+ fprintf (stderr, "bf16 -> float failed: %d, %e\n", i, original);
+ failed = true;
+ }
+ }
+
+ if (failed)
+ abort ();
+}
+
+int
+main (void)
+{
+ if (CHECK_CPU_SUPPORTS)
+ do_test ();
+ return 0;
+}
--
2.55.0