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

Reply via email to