diff mbox series

Implement _Float16 to bfloat16 conversion with float32

Message ID 20240502194443.651680-1-hjl.tools@gmail.com
State New
Headers show
Series Implement _Float16 to bfloat16 conversion with float32 | expand

Commit Message

H.J. Lu May 2, 2024, 7:44 p.m. UTC
Since bfloat16 isn't a subset nor superset of _Float16, implement _Float16
to bfloat16 conversion with _Float16 -> float32 -> bfloat16.

gcc/

	PR middle-end/114907
	* expr.cc (convert_mode_scalar): Implement _Float16 to bfloat16
	conversion with float32 conversions.

gcc/testsuite/

	PR middle-end/114907
	* gcc.dg/pr114907.c: New test.
	* gcc.target/i386/avx512fp16-hf2bf.c: Likewise.
---
 gcc/expr.cc                                    | 11 +++++++++--
 gcc/testsuite/gcc.dg/pr114907.c                | 14 ++++++++++++++
 .../gcc.target/i386/avx512fp16-hf2bf.c         | 18 ++++++++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr114907.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512fp16-hf2bf.c
diff mbox series

Patch

diff --git a/gcc/expr.cc b/gcc/expr.cc
index d4414e242cb..3a599637e34 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -373,10 +373,17 @@  convert_mode_scalar (rtx to, rtx from, int unsignedp)
 	}
 
 #ifdef HAVE_SFmode
-      if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
+      /* Since BFmode isn't a subset nor superset of BFmode, implement
+	 HFmode -> BFmode conversion by HFmode -> SFmode -> BFmode
+	 conversions.  */
+      if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
+	   || (REAL_MODE_FORMAT (from_mode) == &ieee_half_format
+	       && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format))
 	  && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
 	{
-	  if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode))
+	  if ((REAL_MODE_FORMAT (from_mode) == &ieee_half_format
+	       && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format)
+	      || GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode))
 	    {
 	      /* To cut down on libgcc size, implement
 		 BFmode -> {DF,XF,TF}mode conversions by
diff --git a/gcc/testsuite/gcc.dg/pr114907.c b/gcc/testsuite/gcc.dg/pr114907.c
new file mode 100644
index 00000000000..2f49fc0bdac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114907.c
@@ -0,0 +1,14 @@ 
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+/* { dg-add-options bfloat16 } */
+/* { dg-require-effective-target bfloat16_runtime } */
+
+__bf16 bf;
+_Float16 f16;
+
+int
+main (void)
+{
+  bf = f16;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512fp16-hf2bf.c b/gcc/testsuite/gcc.target/i386/avx512fp16-hf2bf.c
new file mode 100644
index 00000000000..91f387f5af8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512fp16-hf2bf.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-options "-mavx512fp16 -O2 -save-temps" } */
+
+__bf16 bf;
+_Float16 f16;
+
+int
+main (void)
+{
+  if (!__builtin_cpu_supports ("avx512fp16"))
+    return 0;
+
+  bf = f16;
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times "vcvtsh2ss\[ \\t\]" 1 } } */
+/* { dg-final { scan-assembler-not "__extendhfsf2\[ \\t\]" } } */