This patch adds various 16-bit floating point tests.
I have committed all of the patches in my backlog (dense math registers, other
-mcpu=future instructions, random bug fixes, support for _Float16 and
__bfloat16, and optimizations for vector logical operations on power10/power11)
into the IBM vendor branch:
vendors/ibm/gcc-17-future
2026-07-01 Michael Meissner <[email protected]>
gcc/testsuite/
* gcc.target/powerpc/bfloat16-1.c: New target.
* gcc.target/powerpc/bfloat16-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 __bfloat16 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 __bfloat16 targets.
---
gcc/testsuite/gcc.target/powerpc/bfloat16-1.c | 34 +++++
gcc/testsuite/gcc.target/powerpc/bfloat16-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(+)
create mode 100644 gcc/testsuite/gcc.target/powerpc/bfloat16-1.c
create mode 100644 gcc/testsuite/gcc.target/powerpc/bfloat16-2.c
create mode 100644 gcc/testsuite/gcc.target/powerpc/float16-1.c
create mode 100644 gcc/testsuite/gcc.target/powerpc/float16-2.c
diff --git a/gcc/testsuite/gcc.target/powerpc/bfloat16-1.c
b/gcc/testsuite/gcc.target/powerpc/bfloat16-1.c
new file mode 100644
index 00000000000..bbd6ce1f937
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bfloat16-1.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ppc_bfloat16_runtime } */
+/* { dg-options "-mfloat16 -O2" } */
+
+#include <stdlib.h>
+
+/* This tests whether we can do __bfloat16 calculations either with software
+ emuluation or via hardware support. */
+volatile __bfloat16 two = 2.0;
+volatile __bfloat16 three = 3.0;
+volatile __bfloat16 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/bfloat16-2.c
b/gcc/testsuite/gcc.target/powerpc/bfloat16-2.c
new file mode 100644
index 00000000000..00c70ece187
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bfloat16-2.c
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ppc_bfloat16_hw } */
+/* { dg-options "-mfloat16 -O2" } */
+
+#include <stdlib.h>
+
+/* On a power10/power11 system, test whether we can do __bfloat16 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 __bfloat16 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 __bfloat16 two = 2.0;
+volatile __bfloat16 three = 3.0;
+volatile __bfloat16 p8_add, p8_sub, p8_mul, p8_div;
+volatile __bfloat16 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 00000000000..e3a749ebbef
--- /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 00000000000..27df6dbaf23
--- /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 __bfloat16 two = 2.0;
+volatile __bfloat16 three = 3.0;
+volatile __bfloat16 p8_add, p8_sub, p8_mul, p8_div;
+volatile __bfloat16 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 c6ebbed4f4b..850b01f0c12 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -3642,6 +3642,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 __bfloat16
+# conversions
+proc check_ppc_bfloat16_hw_available { } {
+ return [check_cached_effective_target ppc_bfloat16_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 __bfloat16 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 {
+ __bfloat16 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 __bfloat16 calculations via either
+# software or hardware support.
+proc check_ppc_bfloat16_runtime_available { } {
+ return [check_cached_effective_target ppc_bfloat16_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_bfloat16_runtime_available {
+ extern void abort (void);
+ volatile __bfloat16 x = 3.0;
+ volatile __bfloat16 y = 4.0;
+ volatile __bfloat16 z;
+ volatile union {
+ __bfloat16 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.
@@ -10792,6 +10926,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_bfloat16_hw" { set selected
[check_ppc_bfloat16_hw_available] }
+ "ppc_bfloat16_runtime" { set selected
[check_ppc_bfloat16_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] }
--
2.54.0
--
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]