https://gcc.gnu.org/g:cc4d562015c009077ece9cce2f222615d6d30566
commit cc4d562015c009077ece9cce2f222615d6d30566 Author: Michael Meissner <[email protected]> Date: Fri Nov 14 14:54:04 2025 -0500 Add _Float16 and __bfloat16 tests. 2025-11-13 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. Diff: --- 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 | 139 ++++++++++++++++++++++++++ 5 files changed, 352 insertions(+) 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 000000000000..322221b2b8e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bfloat16-1.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-require-effective-target 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 000000000000..89b5f1062881 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bfloat16-2.c @@ -0,0 +1,72 @@ +/* { dg-do run } */ +/* { dg-require-effective-target 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 000000000000..3aa86a500bff --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float16-1.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-require-effective-target 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..a202bb0a653a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float16-2.c @@ -0,0 +1,73 @@ +/* { dg-do run } */ +/* { dg-require-effective-target 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 4f9a79702cba..1120ac6a017b 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3567,6 +3567,141 @@ 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() + { + double y; + 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. @@ -10546,6 +10681,10 @@ proc is-effective-target { arg } { "gc_sections" { set selected [check_gc_sections_available] } "linker_plugin" { set selected [check_linker_plugin_available] } "cxa_atexit" { set selected [check_cxa_atexit_available] } + "float16_hw" { set selected [check_ppc_float16_hw_available] } + "float16_runtime" { set selected [check_ppc_float16_runtime_available] } + "bfloat16_hw" { set selected [check_ppc_bfloat16_hw_available] } + "bfloat16_runtime" { set selected [check_ppc_bfloat16_runtime_available] } default { error "unknown effective target keyword `$arg'" } } }
