This patch adds 4 tests to make sure 16-bit floating point is supported. float16-1.c: This simple test verifies that _Float16 operations work on ISA 2.07 (power8), ISA 3.0 (power9), and ISA 3.1 (power10 and power11) systems. On ISA 2.07 systems, the tests will be done via software emulation. On ISA 3.0 and 3.1 systems, the tests will use the native instructions to support _Float16.
float16-2.c: This simple test verifies that _Float16 operations work on ISA 3.0 and ISA 3.1 sytems. This test uses the attribute((target)) support to test both the software emulation and hardware support work. bfloat16-1.c: This simple test verifies that __bfloat16 operations work on ISA 2.07, ISA 3.0, and ISA 3.1 systems. On ISA 2.07 and ISA 3.0 systems, the tests will be done via software emulation. On ISA 3.1 systems, the tests will use the native instructions to support __bfloat16. bfloat16-2.c: This simple test verifies that __bfloat16 operations work on ISA 3.1 sytems. This test uses the attribute((target)) support to test both the software emulation and hardware support work. All 11 patches have been tested on little endian and big endian PowerPC servers with no regressions. On little endian power9 systems, the bfloat16-2.c test is skipped as being unsupported. Can I check in these patches? 2025-11-14 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 4f9a79702cb..c3496bd1245 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3567,6 +3567,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. @@ -10540,6 +10674,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.51.1 -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: [email protected]
