https://gcc.gnu.org/g:c38e0c77915c15ed8730111f4d76b832518dc7b2
commit c38e0c77915c15ed8730111f4d76b832518dc7b2 Author: Michael Meissner <[email protected]> Date: Thu Oct 22 01:25:52 2026 -0400 Add _Float16 and __bf16 tests. This patch adds various 16-bit floating point tests. 2026-10-22 Michael Meissner <[email protected]> gcc/testsuite/ * gcc.target/powerpc/bf16-1.c: New target. * gcc.target/powerpc/bf16-2.c: Likewise. * gcc.target/powerpc/bf16-3.c: Likewise. * gcc.target/powerpc/bf16-4.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 | 97 +++++++++++++++++++ gcc/testsuite/gcc.target/powerpc/bf16-3.c | 32 +++++++ gcc/testsuite/gcc.target/powerpc/bf16-4.c | 31 ++++++ gcc/testsuite/gcc.target/powerpc/float16-1.c | 34 +++++++ gcc/testsuite/gcc.target/powerpc/float16-2.c | 98 +++++++++++++++++++ gcc/testsuite/lib/target-supports.exp | 138 +++++++++++++++++++++++++++ 7 files changed, 464 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..05f56eda5bb4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bf16-2.c @@ -0,0 +1,97 @@ +/* { dg-do run { target { power10_hw } } } */ +/* { dg-require-effective-target ppc_float16_hw } */ +/* { dg-options "-mfloat16 -O2 -mdejagnu-cpu=power10" } */ + +#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=power9) 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_power8 (void) __attribute__ ((noinline,target("cpu=power8"))); +extern void do_power9 (void) __attribute__ ((noinline,target("cpu=power9"))); +extern void do_power10 (void) __attribute__ ((noinline,target("cpu=power10"))); + +volatile __bf16 two = 2.0; +volatile __bf16 three = 3.0; +volatile __bf16 p8_add, p8_sub, p8_mul, p8_div; +volatile __bf16 p9_add, p9_sub, p9_mul, p9_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_power9 (void) +{ + p9_add = three + two; + p9_sub = three - two; + p9_mul = three * two; + p9_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_power9 (); + + if (((double)p9_add) != 5.0) + abort (); + + if (((double)p9_sub) != 1.0) + abort (); + + if (((double)p9_mul) != 6.0) + abort (); + + if (((double)p9_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/bf16-3.c b/gcc/testsuite/gcc.target/powerpc/bf16-3.c new file mode 100644 index 000000000000..3b70cb2cba78 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bf16-3.c @@ -0,0 +1,32 @@ +/* { dg-require-effective-target power10_ok } */ +/* { dg-require-effective-target ppc_bf16_runtime } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2 -mfloat16" } */ + +/* Check that we can do multiple __bf16 adds all in V4SFmode. */ + +/* Expected code: + + lxsihzx 0,0,4 + lxsihzx 11,0,5 + lxsihzx 12,0,6 + xxspltw 0,0,1 + xxspltw 11,11,1 + xxspltw 12,12,1 + xvcvbf16spn 0,0 + xvcvbf16spn 11,11 + xvcvbf16spn 12,12 + xvaddsp 0,0,11 + xvaddsp 0,0,12 + xvcvspbf16 0,0 + stxsihx 0,0,3 */ + +void +add3 (__bf16 *p, __bf16 *q, __bf16 *r, __bf16 *s) +{ + *p = *q + *r + *s; +} + +/* { dg-final { scan-assembler-times {\mxxspltw\M|\mvspltw\M|\mmtvsrws\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mxvcvbf16spn\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mxvaddsp\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvcvspbf16\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/bf16-4.c b/gcc/testsuite/gcc.target/powerpc/bf16-4.c new file mode 100644 index 000000000000..760e4751a75f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bf16-4.c @@ -0,0 +1,31 @@ +/* { dg-require-effective-target power10_ok } */ +/* { dg-require-effective-target ppc_bf16_runtime } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2 -mfloat16" } */ + +/* Check that we can do multiple __bf16 adds all in V4SFmode. */ + +/* Expected code: + + lxsihzx 0,0,4 + lxsihzx 12,0,5 + xxspltiw 11,1065353216 + xxspltw 0,0,1 + xxspltw 12,12,1 + xvcvbf16spn 0,0 + xvcvbf16spn 12,12 + xvaddsp 0,0,12 + xvaddsp 0,0,11 + xvcvspbf16 0,0 + stxsihx 0,0,3 */ + +void +add3 (__bf16 *p, __bf16 *q, __bf16 *r) +{ + *p = *q + *r + (__bf16)1.0; +} + +/* { dg-final { scan-assembler-times {\mxxspltw\M|\mvspltw\M|\mmtvsrws\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvcvbf16spn\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvaddsp\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxxspltiw\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvcvspbf16\M} 1 } } */ 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..608b5d28682c --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float16-2.c @@ -0,0 +1,98 @@ +/* { dg-do run { target { power10_hw } } } */ +/* { dg-require-effective-target ppc_float16_hw } */ +/* { dg-options "-mfloat16 -O2 -mdejagnu-cpu=power10" } */ + +#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_power8 (void) __attribute__ ((noinline,target("cpu=power8"))); +extern void do_power9 (void) __attribute__ ((noinline,target("cpu=power9"))); +extern void do_power10 (void) __attribute__ ((noinline,target("cpu=power10"))); + +volatile _Float16 two = 2.0; +volatile _Float16 three = 3.0; +volatile _Float16 p8_add, p8_sub, p8_mul, p8_div; +volatile _Float16 p9_add, p9_sub, p9_mul, p9_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_power9 (void) +{ + p9_add = three + two; + p9_sub = three - two; + p9_mul = three * two; + p9_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_power9 (); + + if (((double)p9_add) != 5.0) + abort (); + + if (((double)p9_sub) != 1.0) + abort (); + + if (((double)p9_mul) != 6.0) + abort (); + + if (((double)p9_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 3c5dfd59f6fe..a6ef7c28503e 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3731,6 +3731,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. @@ -11089,6 +11223,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] }
