public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Nan-box the result of movhf on soft-fp16
@ 2023-11-08  3:07 KuanLin Chen
  2023-11-08  6:39 ` Kito Cheng
  0 siblings, 1 reply; 2+ messages in thread
From: KuanLin Chen @ 2023-11-08  3:07 UTC (permalink / raw)
  To: gcc-patches; +Cc: Kito Cheng, kaiweng, patrick


[-- Attachment #1.1: Type: text/plain, Size: 514 bytes --]

 According to spec, fmv.h checks if the input operands are correctly
 NaN-boxed. If not, the input value is treated as an n-bit canonical NaN.
 This patch fixs the issue that operands returned by soft-fp16 libgcc
 (i.e., __truncdfhf2) was not correctly NaN-boxed.

*gcc/ChangeLog:*

* config/riscv/riscv.cc (riscv_legitimize_move): Expand movfh

with Nan-boxing value.

* config/riscv/riscv.md (*movhf_softfloat_unspec): New pattern.


*gcc/testsuite/ChangeLog:*


gcc.target/riscv/_Float16-nanboxing.c: New test.

[-- Attachment #2: 0001-RISC-V-Nan-box-the-result-of-movhf-on-soft-fp16.patch --]
[-- Type: application/octet-stream, Size: 4573 bytes --]

From cab1ef071277c5b9cd04a23afc2b9029f66efbc5 Mon Sep 17 00:00:00 2001
From: Kai Kai-Yi Weng <kaiweng@andestech.com>
Date: Wed, 18 Jan 2023 18:04:22 +0800
Subject: [PATCH] RISC-V: Nan-box the result of movhf on soft-fp16

According to spec, fmv.h checks if the input operands are correctly
NaN-boxed. If not, the input value is treated as an n-bit canonical NaN.
This patch fixs the issue that operands returned by soft-fp16 libgcc
(i.e., __truncdfhf2) was not correctly NaN-boxed.

co-author: Patrick (patrick@andestech.com), Rufus (rufus@andestech.com).
---
 gcc/config/riscv/riscv.cc                     | 44 +++++++++++++++++++
 gcc/config/riscv/riscv.md                     | 13 ++++++
 .../gcc.target/riscv/_Float16-nanboxing.c     | 30 +++++++++++++
 3 files changed, 87 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/_Float16-nanboxing.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3220161fded..c5c973d4e28 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2687,6 +2687,50 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       return true;
     }
 
+  /* In order to fit NaN boxing, expand
+       (set (reg:HF dest) (mem:HF src)
+     to
+       (set (reg:HI temp) (mem:HI src)
+       (set (reg:HF dest) (subreg:HF (reg:HI temp) 0))  */
+
+  if (TARGET_HARD_FLOAT
+      && !TARGET_ZFHMIN && mode == HFmode
+      && REG_P (dest) && MEM_P (src)
+      && can_create_pseudo_p ())
+    {
+      rtx temp = gen_reg_rtx (HImode);
+      riscv_emit_set (temp, gen_rtx_MEM (HImode, XEXP(src, 0)));
+      riscv_emit_move (dest, gen_lowpart (mode, temp));
+      return true;
+    }
+
+  /* In order to fit NaN boxing, expand
+       (set (reg:HF dest) (subreg:HF (reg:HI src) 0))
+     to
+       (set (reg:SI/DI mask) (const_int -65536)
+       (set (reg:SI/DI temp) (zero_extend:SI/DI (reg:HI src)))
+       (set (reg:SI/DI temp) (ior:SI/DI (reg:SI/DI mask) (reg:SI/DI temp)))
+       (set (reg:HF dest) (unspec:HF [ (reg:SI/DI temp) ] UNSPEC_FMV_SFP16_X))
+  */
+
+  if (TARGET_HARD_FLOAT
+      && !TARGET_ZFHMIN && mode == HFmode
+      && REG_P (dest)
+      && (SUBREG_P (src)) && (GET_MODE (XEXP (src, 0)) == HImode)
+      && can_create_pseudo_p ())
+    {
+      rtx mask = force_reg (word_mode, gen_int_mode (-65536, word_mode));
+      rtx temp = gen_reg_rtx (word_mode);
+      emit_insn (gen_extend_insn (temp, XEXP (src, 0), word_mode, HImode, 1));
+      if (word_mode == SImode)
+	emit_insn (gen_iorsi3 (temp, mask, temp));
+      else
+	emit_insn (gen_iordi3 (temp, mask, temp));
+      riscv_emit_move (dest, gen_rtx_UNSPEC (HFmode, gen_rtvec (1, temp),
+					     UNSPEC_FMV_SFP16_X));
+      return true;
+    }
+
   /* We need to deal with constants that would be legitimate
      immediate_operands but aren't legitimate move_operands.  */
   if (CONSTANT_P (src) && !move_operand (src, mode))
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index f699f6d0f97..f42ef913c80 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -86,6 +86,9 @@
 
   ;; String unspecs
   UNSPEC_STRLEN
+
+  ;; Workaround for HFmode without hardware extension
+  UNSPEC_FMV_SFP16_X
 ])
 
 (define_c_enum "unspecv" [
@@ -1819,6 +1822,16 @@
     DONE;
 })
 
+(define_insn "*movhf_softfloat_unspec"
+  [(set (match_operand:HF 0 "register_operand" "=f,m")
+	(unspec:HF [(match_operand:X 1 "nonimmediate_operand" "r,r")] UNSPEC_FMV_SFP16_X))]
+  "TARGET_HARD_FLOAT && !TARGET_ZFH"
+  "@
+   fmv.w.x\t%0,%1
+   sh\t%1,%0"
+  [(set_attr "type" "fmove, store")
+   (set_attr "mode" "SF, HI")])
+
 (define_insn "*movhf_hardfloat"
   [(set (match_operand:HF 0 "nonimmediate_operand" "=f,   f,f,f,m,m,*f,*r,  *r,*r,*m")
 	(match_operand:HF 1 "move_operand"         " f,zfli,G,m,f,G,*r,*f,*G*r,*m,*r"))]
diff --git a/gcc/testsuite/gcc.target/riscv/_Float16-nanboxing.c b/gcc/testsuite/gcc.target/riscv/_Float16-nanboxing.c
new file mode 100644
index 00000000000..c2956882997
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/_Float16-nanboxing.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64ifd -mabi=lp64d -O" } */
+
+_Float16 gvar = 9.87654;
+
+union U {
+  unsigned short i16;
+  _Float16 f16;
+};
+
+_Float16 test1(unsigned short input)
+{
+  union U tmp;
+  tmp.i16 = input;
+
+  return tmp.f16;
+}
+
+_Float16 test2()
+{
+  return 1.234f;
+}
+
+_Float16 test3()
+{
+  return gvar;
+}
+
+/* { dg-final { scan-assembler-times {\mli\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mfmv\.w\.x\M} 3 } } */
-- 
2.30.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] RISC-V: Nan-box the result of movhf on soft-fp16
  2023-11-08  3:07 [PATCH] RISC-V: Nan-box the result of movhf on soft-fp16 KuanLin Chen
@ 2023-11-08  6:39 ` Kito Cheng
  0 siblings, 0 replies; 2+ messages in thread
From: Kito Cheng @ 2023-11-08  6:39 UTC (permalink / raw)
  To: KuanLin Chen; +Cc: gcc-patches, kaiweng, patrick

Thanks for the patch!! We also found the same issue on internal
testing works and trying to figure out how to resolve that issue yet,
this patch is little bit magic, let me take a closer look.. :P

On Wed, Nov 8, 2023 at 11:08 AM KuanLin Chen <best124612@gmail.com> wrote:
>
>  According to spec, fmv.h checks if the input operands are correctly
>  NaN-boxed. If not, the input value is treated as an n-bit canonical NaN.
>  This patch fixs the issue that operands returned by soft-fp16 libgcc
>  (i.e., __truncdfhf2) was not correctly NaN-boxed.
>
> gcc/ChangeLog:
>
> * config/riscv/riscv.cc (riscv_legitimize_move): Expand movfh
>
> with Nan-boxing value.
>
> * config/riscv/riscv.md (*movhf_softfloat_unspec): New pattern.
>
>
> gcc/testsuite/ChangeLog:
>
>
> gcc.target/riscv/_Float16-nanboxing.c: New test.
>
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-11-08  6:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-08  3:07 [PATCH] RISC-V: Nan-box the result of movhf on soft-fp16 KuanLin Chen
2023-11-08  6:39 ` Kito Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).