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 --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\]" } } */ -- 2.44.0