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'" }
        }
     }

Reply via email to