[gcc(refs/users/meissner/heads/work255-float)] Add _Float16 and __bf16 tests.

Michael Meissner via Gcc-cvs <[email protected]> Tue, 4 Aug 2026 02:17:19 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:eabf0f2cbc137a563df0fc4ad383594df1d6a705

commit eabf0f2cbc137a563df0fc4ad383594df1d6a705
Author: Michael Meissner <[email protected]>
Date:   Mon Aug 3 22:15:54 2026 -0400

    Add _Float16 and __bf16 tests.
    
    This patch adds various 16-bit floating point tests.
    
    2026-08-03  Michael Meissner  <[email protected]>
    
    gcc/testsuite/
    
            * gcc.target/powerpc/bf16-1.c: New target.
            * gcc.target/powerpc/bf16-2.c: Likewise.
            * gcc.target/powerpc/float16-1.c: Likewise.
            * gcc.target/powerpc/float16-2.c: Likewise.
            * lib/target-supports.exp (check_ppc_float16_hw_available): New target
            supports for _Float16 and __bf16 support.
            (check_ppc_float16_runtime_available): Likewise.
            (check_ppc_bfloat16_hw_available): Likewise.
            (check_ppc_bfloat16_runtime_available): Likewise.
            (is-effective-target): Add new _Float16 and __bf16 targets.

Diff:
---
 gcc/testsuite/gcc.target/powerpc/bf16-1.c    |  34 +++++++
 gcc/testsuite/gcc.target/powerpc/bf16-2.c    |  72 ++++++++++++++
 gcc/testsuite/gcc.target/powerpc/float16-1.c |  34 +++++++
 gcc/testsuite/gcc.target/powerpc/float16-2.c |  73 ++++++++++++++
 gcc/testsuite/lib/target-supports.exp        | 138 +++++++++++++++++++++++++++
 5 files changed, 351 insertions(+)

diff --git a/gcc/testsuite/gcc.target/powerpc/bf16-1.c b/gcc/testsuite/gcc.target/powerpc/bf16-1.c
new file mode 100644
index 000000000000..bb4ebf2ca950
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bf16-1.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ppc_bf16_runtime } */
+/* { dg-options "-mfloat16 -O2" } */
+
+#include <stdlib.h>
+
+/* This tests whether we can do __bf16 calculations either with software
+   emuluation or via hardware support.  */
+volatile __bf16 two = 2.0;
+volatile __bf16 three = 3.0;
+volatile __bf16 result_add, result_sub, result_mul, result_div;
+
+int
+main (int argc, char *argv[])
+{
+  result_add = three + two;
+  result_sub = three - two;
+  result_mul = three * two;
+  result_div = three / two;
+
+  if (((double)result_add) != 5.0)
+    abort ();
+
+  if (((double)result_sub) != 1.0)
+    abort ();
+
+  if (((double)result_mul) != 6.0)
+    abort ();
+
+  if (((double)result_div) != 1.5)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/bf16-2.c b/gcc/testsuite/gcc.target/powerpc/bf16-2.c
new file mode 100644
index 000000000000..7a7079f6bd92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bf16-2.c
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ppc_bf16_hw } */
+/* { dg-options "-mfloat16 -O2" } */
+
+#include <stdlib.h>
+
+/* On a power10/power11 system, test whether we can do __bf16 calculations
+   with both software emulation (i.e. running the code with -mcpu=power8) and
+   hardware conversions (i.e. with -mcpu=power10 or -mcpu=power11).
+
+   Power10 supports the XVCVBF16SPN and XVCVSPBF16 instructions that convert between
+   a vector __bf16 and a vector float. */
+
+extern void do_power10 (void) __attribute__ ((noinline,target("cpu=power10")));
+extern void do_power8  (void) __attribute__ ((noinline,target("cpu=power8")));
+
+volatile __bf16 two = 2.0;
+volatile __bf16 three = 3.0;
+volatile __bf16 p8_add, p8_sub, p8_mul, p8_div;
+volatile __bf16 p10_add, p10_sub, p10_mul, p10_div;
+
+void
+do_power8 (void)
+{
+  p8_add = three + two;
+  p8_sub = three - two;
+  p8_mul = three * two;
+  p8_div = three / two;
+}
+
+void
+do_power10 (void)
+{
+  p10_add = three + two;
+  p10_sub = three - two;
+  p10_mul = three * two;
+  p10_div = three / two;
+}
+
+int
+main (int argc, char *argv[])
+{
+  do_power8 ();
+
+  if (((double)p8_add) != 5.0)
+    abort ();
+
+  if (((double)p8_sub) != 1.0)
+    abort ();
+
+  if (((double)p8_mul) != 6.0)
+    abort ();
+
+  if (((double)p8_div) != 1.5)
+    abort ();
+
+  do_power10 ();
+
+  if (((double)p10_add) != 5.0)
+    abort ();
+
+  if (((double)p10_sub) != 1.0)
+    abort ();
+
+  if (((double)p10_mul) != 6.0)
+    abort ();
+
+  if (((double)p10_div) != 1.5)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/float16-1.c b/gcc/testsuite/gcc.target/powerpc/float16-1.c
new file mode 100644
index 000000000000..e3a749ebbef8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float16-1.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ppc_float16_runtime } */
+/* { dg-options "-mfloat16 -O2" } */
+
+#include <stdlib.h>
+
+/* This tests whether we can do _Float16 calculations either with software
+   emuluation or via hardware support.  */
+volatile _Float16 two = 2.0F16;
+volatile _Float16 three = 3.0F16;
+volatile _Float16 result_add, result_sub, result_mul, result_div;
+
+int
+main (int argc, char *argv[])
+{
+  result_add = three + two;
+  result_sub = three - two;
+  result_mul = three * two;
+  result_div = three / two;
+
+  if (((double)result_add) != 5.0)
+    abort ();
+
+  if (((double)result_sub) != 1.0)
+    abort ();
+
+  if (((double)result_mul) != 6.0)
+    abort ();
+
+  if (((double)result_div) != 1.5)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/float16-2.c b/gcc/testsuite/gcc.target/powerpc/float16-2.c
new file mode 100644
index 000000000000..9e773821f627
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float16-2.c
@@ -0,0 +1,73 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ppc_float16_hw } */
+/* { dg-options "-mfloat16 -O2" } */
+
+#include <stdlib.h>
+
+/* On a power10/power11 system, test whether we can do _Float16 calculations
+   with both software emulation (i.e. running the code with -mcpu=power8) and
+   hardware conversions (i.e. with -mcpu=power9, -mcpu=power10 or
+   -mcpu=power11).
+
+   Power9 supports the XSCVHPDP and XSCVDPHP instructions that convert between
+   a scalar _Float16 and a scalar double. */
+
+extern void do_power9 (void) __attribute__ ((noinline,target("cpu=power9")));
+extern void do_power8 (void) __attribute__ ((noinline,target("cpu=power8")));
+
+volatile _Float16 two = 2.0;
+volatile _Float16 three = 3.0;
+volatile _Float16 p8_add, p8_sub, p8_mul, p8_div;
+volatile _Float16 p10_add, p10_sub, p10_mul, p10_div;
+
+void
+do_power8 (void)
+{
+  p8_add = three + two;
+  p8_sub = three - two;
+  p8_mul = three * two;
+  p8_div = three / two;
+}
+
+void
+do_power10 (void)
+{
+  p10_add = three + two;
+  p10_sub = three - two;
+  p10_mul = three * two;
+  p10_div = three / two;
+}
+
+int
+main (int argc, char *argv[])
+{
+  do_power8 ();
+
+  if (((double)p8_add) != 5.0)
+    abort ();
+
+  if (((double)p8_sub) != 1.0)
+    abort ();
+
+  if (((double)p8_mul) != 6.0)
+    abort ();
+
+  if (((double)p8_div) != 1.5)
+    abort ();
+
+  do_power10 ();
+
+  if (((double)p10_add) != 5.0)
+    abort ();
+
+  if (((double)p10_sub) != 1.0)
+    abort ();
+
+  if (((double)p10_mul) != 6.0)
+    abort ();
+
+  if (((double)p10_div) != 1.5)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 42cbb5ce3df0..68672e3e9e43 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -3667,6 +3667,140 @@ proc check_ppc_recip_hw_available { } {
     }]
 }
 
+# Return true if the PowerPC has hardware support for doing _Float16
+# conversions
+proc check_ppc_float16_hw_available { } {
+    return [check_cached_effective_target ppc_float16_hw_available {
+	# Some simulators may not support XSCVHPDP
+	# For now, disable on Darwin
+	if { [istarget powerpc-*-eabi] || [istarget *-*-darwin*]} {
+	    expr 0
+	} else {
+	    set options "-mfloat16"
+	    check_runtime_nocache ppc_float16_hw_available {
+		extern void abort (void);
+		volatile _Float16 x = 3.0F16;
+		volatile union {
+		  _Float16 five_f16;
+		  unsigned short five_us;
+		} u = { 5.0F16 };
+		int main()
+		{
+		  double y;
+		  asm ("xscvhpdp %x0,%x1" : "=wa" (y) : "wa" (x));
+		  if (y != 3.0)
+		    abort ();
+		  if (u.five_us != 0x4500)
+		    abort ();
+		  return 0;
+		}
+	    } $options
+	}
+    }]
+}
+
+# Return true if the PowerPC can do _Float16 calculations via either
+# software or hardware support.
+proc check_ppc_float16_runtime_available { } {
+    return [check_cached_effective_target ppc_float16_runtime_available {
+	# Some simulators may not support XSCVHPDP
+	# For now, disable on Darwin
+	if { [istarget powerpc-*-eabi] || [istarget *-*-darwin*]} {
+	    expr 0
+	} else {
+	    set options "-mfloat16"
+	    check_runtime_nocache ppc_float16_runtime_available {
+		extern void abort (void);
+		volatile _Float16 x = 3.0F16;
+		volatile _Float16 y = 4.0F16;
+		volatile _Float16 z;
+		volatile union {
+		  _Float16 five_f16;
+		  unsigned short five_us;
+		} u = { 5.0F16 };
+		int main()
+		{
+		  z = x + y;
+		  if (((double)z) != 7.0)
+		    abort ();
+		  if (u.five_us != 0x4500)
+		    abort ();
+		  return 0;
+		}
+	    } $options
+	}
+    }]
+}
+
+# Return true if the PowerPC has hardware support for doing __bf16
+# conversions
+proc check_ppc_bf16_hw_available { } {
+    return [check_cached_effective_target ppc_bf16_hw_available {
+	# Some simulators may not support XVCVBF16SPN/XVADDSP
+	# For now, disable on Darwin
+	if { [istarget powerpc-*-eabi] || [istarget *-*-darwin*]} {
+	    expr 0
+	} else {
+	    set options "-mfloat16"
+	    check_runtime_nocache ppc_float16_hw_available {
+		extern void abort (void);
+		typedef __bf16 vbf16 __attribute__ ((vector_size (16)));
+		volatile vbf16 x = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
+		volatile vector float y = { 2.0f, 2.0f, 2.0f, 2.0f };
+		volatile vector float z;
+		volatile vector float r;
+		volatile union {
+		  __bf16 five_bf16;
+		  unsigned short five_us;
+		} u = { 5.0 };
+		int main()
+		{
+		  asm ("xvcvbf16spn %x0,%x1" : "=wa" (z) : "wa" (x));
+		  r = y + z;
+		  if (r[0] != 3.0 || r[1] != 3.0 || r[2] != 3.0 || r[3] != 3.0)
+		    abort ();
+		  if (u.five_us != 0x40a0)
+		    abort ();
+		  return 0;
+		}
+	    } $options
+	}
+    }]
+}
+
+# Return true if the PowerPC can do __bf16 calculations via either
+# software or hardware support.
+proc check_ppc_bf16_runtime_available { } {
+    return [check_cached_effective_target ppc_bf16_runtime_available {
+	# Some simulators may not support XVCVBF16SPN
+	# For now, disable on Darwin
+	if { [istarget powerpc-*-eabi] || [istarget *-*-darwin*]} {
+	    expr 0
+	} else {
+	    set options "-mfloat16"
+	    check_runtime_nocache ppc_bf16_runtime_available {
+		extern void abort (void);
+		volatile __bf16 x = 3.0;
+		volatile __bf16 y = 4.0;
+		volatile __bf16 z;
+		volatile union {
+		  __bf16 five_bf16;
+		  unsigned short five_us;
+		} u = { 5.0 };
+		int main()
+		{
+		  z = x + y;
+		  if (((double)z) != 7.0)
+		    abort ();
+		  if (u.five_us != 0x40a0)
+		    abort ();
+		  return 0;
+		}
+	    } $options
+	}
+    }]
+}
+
 # Return 1 if the target supports executing AltiVec and Cell PPU
 # instructions, 0 otherwise.  Cache the result.
 
@@ -10950,6 +11084,10 @@ proc is-effective-target { arg } {
 	  "ppc_recip_hw"   { set selected [check_ppc_recip_hw_available] }
 	  "ppc_cpu_supports_hw" { set selected [check_ppc_cpu_supports_hw_available] }
 	  "ppc_mma_hw"     { set selected [check_ppc_mma_hw_available] }
+	  "ppc_float16_hw"       { set selected [check_ppc_float16_hw_available] }
+	  "ppc_float16_runtime"  { set selected [check_ppc_float16_runtime_available] }
+	  "ppc_bf16_hw"      { set selected [check_ppc_bf16_hw_available] }
+	  "ppc_bf16_runtime" { set selected [check_ppc_bf16_runtime_available] }
 	  "dfp_hw"         { set selected [check_dfp_hw_available] }
 	  "htm_hw"         { set selected [check_htm_hw_available] }
 	  "named_sections" { set selected [check_named_sections_available] }