aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorXiao Zeng <zengxiao@eswincomputing.com>2024-05-08 14:00:58 -0600
committerJeff Law <jlaw@ventanamicro.com>2024-05-08 14:00:58 -0600
commitce51e6727c9d69bbab0e766c449e60fd41f5f2f9 (patch)
treeaf14908f78cbb9d314372423de7374054f5edaed /gcc
parent1c234097487927a4388ddcc690b63597bb3a90dc (diff)
downloadgcc-ce51e6727c9d69bbab0e766c449e60fd41f5f2f9.zip
gcc-ce51e6727c9d69bbab0e766c449e60fd41f5f2f9.tar.gz
gcc-ce51e6727c9d69bbab0e766c449e60fd41f5f2f9.tar.bz2
[PATCH v1 1/1] RISC-V: Nan-box the result of movbf on soft-bf16
1 This patch implements the Nan-box of bf16. 2 Please refer to the Nan-box implementation of hf16 in: <https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=057dc349021660c40699fb5c98fd9cac8e168653> 3 The discussion about Nan-box can be found on the website: <https://www.mail-archive.com/search?q=Nan-box+the+result+of+movhf+on+soft-fp16&l=gcc-patches%40gcc.gnu.org> 4 Below test are passed for this patch * The riscv fully regression test. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_legitimize_move): Expand movbf with Nan-boxing value. * config/riscv/riscv.md (*movbf_softfloat_boxing): New pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/_Bfloat16-nanboxing.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv.cc52
-rw-r--r--gcc/config/riscv/riscv.md12
-rw-r--r--gcc/testsuite/gcc.target/riscv/_Bfloat16-nanboxing.c38
3 files changed, 77 insertions, 25 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 633b55f..2eac67b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3130,35 +3130,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
}
/* In order to fit NaN boxing, expand
- (set FP_REG (reg:HF src))
+ (set FP_REG (reg:HF/BF src))
to
(set (reg:SI/DI mask) (const_int -65536)
- (set (reg:SI/DI temp) (zero_extend:SI/DI (subreg:HI (reg:HF src) 0)))
+ (set (reg:SI/DI temp) (zero_extend:SI/DI (subreg:HI (reg:HF/BF src) 0)))
(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))
+ (set (reg:HF/BF dest) (unspec:HF/BF[ (reg:SI/DI temp) ]
+ UNSPEC_FMV_SFP16_X/UNSPEC_FMV_SBF16_X))
*/
- if (TARGET_HARD_FLOAT
- && !TARGET_ZFHMIN && mode == HFmode
- && REG_P (dest) && FP_REG_P (REGNO (dest))
- && REG_P (src) && !FP_REG_P (REGNO (src))
- && 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,
- simplify_gen_subreg (HImode, src, mode, 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;
- }
+ if (TARGET_HARD_FLOAT
+ && ((!TARGET_ZFHMIN && mode == HFmode)
+ || (!TARGET_ZFBFMIN && mode == BFmode))
+ && REG_P (dest) && FP_REG_P (REGNO (dest))
+ && REG_P (src) && !FP_REG_P (REGNO (src))
+ && 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,
+ simplify_gen_subreg (HImode, src, mode, 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 (mode, gen_rtvec (1, temp),
+ mode == HFmode ? UNSPEC_FMV_SFP16_X
+ : UNSPEC_FMV_SBF16_X));
+
+ return true;
+ }
/* We need to deal with constants that would be legitimate
immediate_operands but aren't legitimate move_operands. */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 620a1b3..4d6de99 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -86,8 +86,9 @@
;; String unspecs
UNSPEC_STRLEN
- ;; Workaround for HFmode without hardware extension
+ ;; Workaround for HFmode and BFmode without hardware extension
UNSPEC_FMV_SFP16_X
+ UNSPEC_FMV_SBF16_X
;; XTheadFmv moves
UNSPEC_XTHEADFMV
@@ -1926,6 +1927,15 @@
[(set_attr "type" "fmove")
(set_attr "mode" "SF")])
+(define_insn "*movbf_softfloat_boxing"
+ [(set (match_operand:BF 0 "register_operand" "=f")
+ (unspec:BF [(match_operand:X 1 "register_operand" " r")]
+ UNSPEC_FMV_SBF16_X))]
+ "!TARGET_ZFBFMIN"
+ "fmv.w.x\t%0,%1"
+ [(set_attr "type" "fmove")
+ (set_attr "mode" "SF")])
+
;;
;; ....................
;;
diff --git a/gcc/testsuite/gcc.target/riscv/_Bfloat16-nanboxing.c b/gcc/testsuite/gcc.target/riscv/_Bfloat16-nanboxing.c
new file mode 100644
index 0000000..11a73d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/_Bfloat16-nanboxing.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64ifd -mabi=lp64d -mcmodel=medlow -O" } */
+
+_Bfloat16 gvar = 9.87654;
+union U
+{
+ unsigned short i16;
+ _Bfloat16 f16;
+};
+
+_Bfloat16
+test1 (unsigned short input)
+{
+ union U tmp;
+ tmp.i16 = input;
+ return tmp.f16;
+}
+
+_Bfloat16
+test2 ()
+{
+ return 1.234f;
+}
+
+_Bfloat16
+test3 ()
+{
+ return gvar;
+}
+
+_Bfloat16
+test ()
+{
+ return 0.0f;
+}
+
+/* { dg-final { scan-assembler-times "li\[ \t\]" 4 } } */
+/* { dg-final { scan-assembler-times "fmv\.w\.x\[ \t\]" 4 } } */