* [PING] [PATCH] RISC-V: Add Zfbfmin extension
@ 2024-05-30 11:38 Xiao Zeng
2024-06-01 4:34 ` Jeff Law
0 siblings, 1 reply; 3+ messages in thread
From: Xiao Zeng @ 2024-05-30 11:38 UTC (permalink / raw)
To: gcc-patches
Cc: jeffreyalaw, research_trasio, kito.cheng, palmer, zhengyu, Xiao Zeng
1 In the previous patch, the libcall for BF16 was implemented:
<https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8c7cee80eb50792e57d514be1418c453ddd1073e>
2 Riscv provides Zfbfmin extension, which completes the "Scalar BF16 Converts":
<https://github.com/riscv/riscv-bfloat16/blob/main/doc/riscv-bfloat16-zfbfmin.adoc>
3 Implemented replacing libcall with Zfbfmin extension instruction.
4 Reused previous testcases in:
<https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8c7cee80eb50792e57d514be1418c453ddd1073e>
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_output_move): Handle BFmode move
for zfbfmin.
* config/riscv/riscv.md (truncsfbf2): New pattern for BFmode.
(trunchfbf2): Dotto.
(truncdfbf2): Dotto.
(trunctfbf2): Dotto.
(extendbfsf2): Dotto.
(*movhf_hardfloat): Add BFmode.
(*mov<mode>_hardfloat): Dotto.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/zfbfmin-bf16_arithmetic.c: New test.
* gcc.target/riscv/zfbfmin-bf16_comparison.c: New test.
* gcc.target/riscv/zfbfmin-bf16_float_libcall_convert.c: New test.
* gcc.target/riscv/zfbfmin-bf16_integer_libcall_convert.c: New test.
---
gcc/config/riscv/riscv.cc | 4 +-
gcc/config/riscv/riscv.md | 75 +++++++++++++++++--
.../riscv/zfbfmin-bf16_arithmetic.c | 35 +++++++++
.../riscv/zfbfmin-bf16_comparison.c | 33 ++++++++
.../zfbfmin-bf16_float_libcall_convert.c | 45 +++++++++++
.../zfbfmin-bf16_integer_libcall_convert.c | 66 ++++++++++++++++
6 files changed, 249 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_arithmetic.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_comparison.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_float_libcall_convert.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_integer_libcall_convert.c
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d0c22058b8c..7c6bafedda3 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4106,7 +4106,7 @@ riscv_output_move (rtx dest, rtx src)
switch (width)
{
case 2:
- if (TARGET_ZFHMIN)
+ if (TARGET_ZFHMIN || TARGET_ZFBFMIN)
return "fmv.x.h\t%0,%1";
/* Using fmv.x.s + sign-extend to emulate fmv.x.h. */
return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16";
@@ -4162,7 +4162,7 @@ riscv_output_move (rtx dest, rtx src)
switch (width)
{
case 2:
- if (TARGET_ZFHMIN)
+ if (TARGET_ZFHMIN || TARGET_ZFBFMIN)
return "fmv.h.x\t%0,%z1";
/* High 16 bits should be all-1, otherwise HW will treated
as a n-bit canonical NaN, but isn't matter for softfloat. */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 78c16adee98..7fd2e3aa23e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1763,6 +1763,57 @@
[(set_attr "type" "fcvt")
(set_attr "mode" "HF")])
+(define_insn "truncsfbf2"
+ [(set (match_operand:BF 0 "register_operand" "=f")
+ (float_truncate:BF
+ (match_operand:SF 1 "register_operand" " f")))]
+ "TARGET_ZFBFMIN"
+ "fcvt.bf16.s\t%0,%1"
+ [(set_attr "type" "fcvt")
+ (set_attr "mode" "BF")])
+
+;; The conversion of HF/DF/TF to BF needs to be done with SF if there is a
+;; chance to generate at least one instruction, otherwise just using
+;; libfunc __trunc[h|d|t]fbf2.
+(define_expand "trunchfbf2"
+ [(set (match_operand:BF 0 "register_operand" "=f")
+ (float_truncate:BF
+ (match_operand:HF 1 "register_operand" " f")))]
+ "TARGET_ZFBFMIN"
+ {
+ convert_move (operands[0],
+ convert_modes (SFmode, HFmode, operands[1], 0), 0);
+ DONE;
+ }
+ [(set_attr "type" "fcvt")
+ (set_attr "mode" "BF")])
+
+(define_expand "truncdfbf2"
+ [(set (match_operand:BF 0 "register_operand" "=f")
+ (float_truncate:BF
+ (match_operand:DF 1 "register_operand" " f")))]
+ "TARGET_ZFBFMIN"
+ {
+ convert_move (operands[0],
+ convert_modes (SFmode, DFmode, operands[1], 0), 0);
+ DONE;
+ }
+ [(set_attr "type" "fcvt")
+ (set_attr "mode" "BF")])
+
+(define_expand "trunctfbf2"
+ [(set (match_operand:BF 0 "register_operand" "=f")
+ (float_truncate:BF
+ (match_operand:TF 1 "register_operand" " f")))]
+ "TARGET_ZFBFMIN"
+ {
+ convert_move (operands[0],
+ convert_modes (SFmode, TFmode, operands[1], 0), 0);
+ DONE;
+ }
+ [(set_attr "type" "fcvt")
+ (set_attr "mode" "BF")])
+
;;
;; ....................
;;
@@ -1907,6 +1958,15 @@
[(set_attr "type" "fcvt")
(set_attr "mode" "SF")])
+(define_insn "extendbfsf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float_extend:SF
+ (match_operand:BF 1 "register_operand" " f")))]
+ "TARGET_ZFBFMIN"
+ "fcvt.s.bf16\t%0,%1"
+ [(set_attr "type" "fcvt")
+ (set_attr "mode" "SF")])
+
(define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(float_extend:DF
@@ -1936,16 +1996,17 @@
DONE;
})
-(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"))]
- "TARGET_ZFHMIN
- && (register_operand (operands[0], HFmode)
- || reg_or_0_operand (operands[1], HFmode))"
+(define_insn "*mov<mode>_hardfloat"
+ [(set (match_operand:HFBF 0 "nonimmediate_operand" "=f, f,f,f,m,m,*f,*r, *r,*r,*m")
+ (match_operand:HFBF 1 "move_operand" " f,zfli,G,m,f,G,*r,*f,*G*r,*m,*r"))]
+ "((TARGET_ZFHMIN && <MODE>mode == HFmode)
+ || (TARGET_ZFBFMIN && <MODE>mode == BFmode))
+ && (register_operand (operands[0], <MODE>mode)
+ || reg_or_0_operand (operands[1], <MODE>mode))"
{ return riscv_output_move (operands[0], operands[1]); }
[(set_attr "move_type" "fmove,fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
(set_attr "type" "fmove,fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
- (set_attr "mode" "HF")])
+ (set_attr "mode" "<MODE>")])
(define_insn "*mov<mode>_softfloat"
[(set (match_operand:HFBF 0 "nonimmediate_operand" "=f, r,r,m,*f,*r")
diff --git a/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_arithmetic.c b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_arithmetic.c
new file mode 100644
index 00000000000..2ca170345af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_arithmetic.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zfbfmin -mabi=ilp32f -mcmodel=medany -O" { target { rv32 } } } */
+/* { dg-options "-march=rv64i_zfbfmin -mabi=lp64f -mcmodel=medany -O" { target { rv64 } } } */
+
+/* 1) bf -> sf fcvt.s.bf16 */
+/* 2) sf1 [+|-|*|/] sf2 f[add|sub|mul|div].s */
+/* 3) sf -> bf fcvt.bf16.s */
+extern __bf16 bf;
+extern __bf16 bf1;
+extern __bf16 bf2;
+
+void bf_add_bf () { bf = bf1 + bf2; }
+
+void bf_sub_bf () { bf = bf1 - bf2; }
+
+void bf_mul_bf () { bf = bf1 * bf2; }
+
+void bf_div_bf () { bf = bf1 / bf2; }
+
+void bf_add_const () { bf = bf1 + 3.14f; }
+
+void const_sub_bf () { bf = 3.14f - bf2; }
+
+void bf_mul_const () { bf = bf1 * 3.14f; }
+
+void const_div_bf () { bf = 3.14f / bf2; }
+
+void bf_inc () { ++bf; }
+
+void bf_dec () { --bf; }
+
+/* { dg-final { scan-assembler-times "fcvt.s.bf16" 14 } } */
+/* { dg-final { scan-assembler-times "fcvt.bf16.s" 10 } } */
+
+/* { dg-final { scan-assembler-not "call" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_comparison.c b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_comparison.c
new file mode 100644
index 00000000000..62d532063c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_comparison.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zfbfmin -mabi=ilp32f -O" { target { rv32 } } } */
+/* { dg-options "-march=rv64i_zfbfmin -mabi=lp64f -O" { target { rv64 } } } */
+
+/* 1) bf -> sf fcvt.s.bf16 */
+/* 2) sf1 [<|<=|>|>=|==] sf2 f[lt|le|gt|ge|eq].s */
+extern __bf16 bf;
+extern __bf16 bf1;
+extern __bf16 bf2;
+
+void bf_lt_bf () { bf = (bf1 < bf2) ? bf1 : bf2; }
+
+void bf_le_bf () { bf = (bf1 <= bf2) ? bf1 : bf2; }
+
+void bf_gt_bf () { bf = (bf1 > bf2) ? bf1 : bf2; }
+
+void bf_ge_bf () { bf = (bf1 >= bf2) ? bf1 : bf2; }
+
+void bf_eq_bf () { bf = (bf1 == bf2) ? bf1 : bf2; }
+
+void bf_lt_const () { bf = (bf1 < 3.14f) ? bf1 : bf2; }
+
+void bf_le_const () { bf = (bf1 <= 3.14f) ? bf1 : bf2; }
+
+void const_gt_bf () { bf = (3.14f > bf2) ? bf1 : bf2; }
+
+void const_ge_bf () { bf = (3.14f >= bf2) ? bf1 : bf2; }
+
+void bf_eq_const () { bf = (bf1 == 3.14f) ? bf1 : bf2; }
+
+/* { dg-final { scan-assembler-times "fcvt.s.bf16" 15 } } */
+
+/* { dg-final { scan-assembler-not "call" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_float_libcall_convert.c b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_float_libcall_convert.c
new file mode 100644
index 00000000000..95e65996e28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_float_libcall_convert.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zfbfmin -mabi=ilp32f -O" { target { rv32 } } } */
+/* { dg-options "-march=rv64i_zfbfmin -mabi=lp64f -O" { target { rv64 } } } */
+
+
+/* 1) float -> BF16
+ * hf -> bf == hf -> sf -> bf fcvt.h.s + fcvt.bf16.s
+ * sf -> bf == sf -> bf fcvt.bf16.s
+ * df -> bf == df -> sf -> bf __truncdfsf2 + fcvt.bf16.s
+ * tf -> bf == tf -> sf -> bf __trunctfsf2 + fcvt.bf16.s
+*/
+
+/* 2) BF16 -> float
+ * bf -> hf == bf -> sf -> hf fcvt.s.bf16 + fcvt.s.h
+ * bf -> sf == bf -> sf fcvt.s.bf16
+ * bf -> df == bf -> sf -> df fcvt.s.bf16 + __extendsfdf2
+ * bf -> tf == bf -> sf -> tf fcvt.s.bf16 + __extendsftf2
+*/
+
+extern __bf16 bf;
+extern _Float16 hf;
+extern float sf;
+extern double df;
+extern long double tf;
+
+void hf_to_bf () { bf = hf; }
+void bf_to_hf () { hf = bf; }
+
+void sf_to_bf () { bf = sf; }
+void bf_to_sf () { sf = bf; }
+
+void df_to_bf () { bf = df; }
+void bf_to_df () { df = bf; }
+
+void tf_to_bf () { bf = tf; }
+void bf_to_tf () { tf = bf; }
+
+/* { dg-final { scan-assembler-times "fcvt.bf16.s" 4 } } */
+/* { dg-final { scan-assembler-times "fcvt.s.bf16" 4 } } */
+/* { dg-final { scan-assembler-times "fcvt.h.s" 1 } } */
+/* { dg-final { scan-assembler-times "fcvt.s.h" 1 } } */
+/* { dg-final { scan-assembler-times "call\t__truncdfsf2" 1 } } */
+/* { dg-final { scan-assembler-times "call\t__trunctfsf2" 1 } } */
+/* { dg-final { scan-assembler-times "call\t__extendsfdf2" 1 } } */
+/* { dg-final { scan-assembler-times "call\t__extendsftf2" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_integer_libcall_convert.c b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_integer_libcall_convert.c
new file mode 100644
index 00000000000..1a998bfe2f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zfbfmin-bf16_integer_libcall_convert.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zfbfmin -mabi=ilp32f -O" { target { rv32 } } } */
+/* { dg-options "-march=rv64i_zfbfmin -mabi=lp64f -O" { target { rv64 } } } */
+
+/* 1) Integer -> BF16
+ * qi/hi -> bf fcvt.s.w + fcvt.bf16.s
+ * uqi/uhi -> bf fcvt.s.wu + fcvt.bf16.s
+ *
+ * si/di/ti -> bf __float[s|d|t]ibf
+ * usi/udi/uti -> bf __floatun[s|d|t]ibf
+*/
+
+/* 2) BF16 -> Integer
+ * bf -> qi/hi/si/di fcvt.s.bf16 + fcvt.[w|l].s
+ * bf -> uqi/uhi/usi/udi fcvt.s.bf16 + fcvt.[w|l]u.s
+ * bf -> ti/uti fcvt.s.bf16 + __fix[uns]sfti
+*/
+
+extern __bf16 bf;
+
+extern signed char qi;
+extern unsigned char uqi;
+extern signed short hi;
+extern unsigned short uhi;
+extern signed int si;
+extern unsigned int usi;
+extern signed long long di;
+extern unsigned long long udi;
+
+void qi_to_bf () { bf = qi; }
+void uqi_to_bf () { bf = uqi; }
+void bf_to_qi () { qi = bf; }
+void bf_to_uqi () { uqi = bf; }
+
+void hi_to_bf () { bf = hi; }
+void uhi_to_bf () { bf = uhi; }
+void bf_to_hi () { hi = bf; }
+void bf_to_uhi () { uhi = bf; }
+
+void si_to_bf () { bf = si; }
+void usi_to_bf () { bf = usi; }
+void bf_to_si () { si = bf; }
+void bf_to_usi () { usi = bf; }
+
+void di_to_bf () { bf = di; }
+void udi_to_bf () { bf = udi; }
+void bf_to_di () { di = bf; }
+void bf_to_udi () { udi = bf; }
+
+#if __riscv_xlen == 64
+extern signed __int128 ti;
+extern unsigned __int128 uti;
+void ti_to_bf () { bf = ti; } /* { dg-final { scan-assembler-times "call\t__floattibf" 1 { target { rv64 } } } } */
+void uti_to_bf () { bf = uti; } /* { dg-final { scan-assembler-times "call\t__floatuntibf" 1 { target { rv64 } } } } */
+void bf_to_ti () { ti = bf; } /* { dg-final { scan-assembler-times "call\t__fixsfti" 1 { target { rv64 } } } } */
+void bf_to_uti () { uti = bf; } /* { dg-final { scan-assembler-times "call\t__fixunssfti" 1 { target { rv64 } } } } */
+#endif
+
+/* { dg-final { scan-assembler-times "fcvt.bf16.s" 4 } } */
+/* { dg-final { scan-assembler-times "fcvt.s.bf16" 8 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times "fcvt.s.bf16" 10 { target { rv64 } } } } */
+
+/* { dg-final { scan-assembler-times "call\t__floatsibf" 1 } } */
+/* { dg-final { scan-assembler-times "call\t__floatunsibf" 1 } } */
+/* { dg-final { scan-assembler-times "call\t__floatdibf" 1 } } */
+/* { dg-final { scan-assembler-times "call\t__floatundibf" 1 } } */
--
2.17.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PING] [PATCH] RISC-V: Add Zfbfmin extension
2024-05-30 11:38 [PING] [PATCH] RISC-V: Add Zfbfmin extension Xiao Zeng
@ 2024-06-01 4:34 ` Jeff Law
2024-06-01 7:41 ` Xiao Zeng
0 siblings, 1 reply; 3+ messages in thread
From: Jeff Law @ 2024-06-01 4:34 UTC (permalink / raw)
To: Xiao Zeng, gcc-patches; +Cc: research_trasio, kito.cheng, palmer, zhengyu
On 5/30/24 5:38 AM, Xiao Zeng wrote:
> 1 In the previous patch, the libcall for BF16 was implemented:
> <https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8c7cee80eb50792e57d514be1418c453ddd1073e>
>
> 2 Riscv provides Zfbfmin extension, which completes the "Scalar BF16 Converts":
> <https://github.com/riscv/riscv-bfloat16/blob/main/doc/riscv-bfloat16-zfbfmin.adoc>
>
> 3 Implemented replacing libcall with Zfbfmin extension instruction.
>
> 4 Reused previous testcases in:
> <https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8c7cee80eb50792e57d514be1418c453ddd1073e>
>
> gcc/ChangeLog:
>
> * config/riscv/riscv.cc (riscv_output_move): Handle BFmode move
> for zfbfmin.
> * config/riscv/riscv.md (truncsfbf2): New pattern for BFmode.
> (trunchfbf2): Dotto.
> (truncdfbf2): Dotto.
> (trunctfbf2): Dotto.
> (extendbfsf2): Dotto.
> (*movhf_hardfloat): Add BFmode.
> (*mov<mode>_hardfloat): Dotto.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/zfbfmin-bf16_arithmetic.c: New test.
> * gcc.target/riscv/zfbfmin-bf16_comparison.c: New test.
> * gcc.target/riscv/zfbfmin-bf16_float_libcall_convert.c: New test.
> * gcc.target/riscv/zfbfmin-bf16_integer_libcall_convert.c: New test.
> ---
>
> +
> +;; The conversion of HF/DF/TF to BF needs to be done with SF if there is a
> +;; chance to generate at least one instruction, otherwise just using
> +;; libfunc __trunc[h|d|t]fbf2.
> +(define_expand "trunchfbf2"
> + [(set (match_operand:BF 0 "register_operand" "=f")
> + (float_truncate:BF
> + (match_operand:HF 1 "register_operand" " f")))]
> + "TARGET_ZFBFMIN"
> + {
> + convert_move (operands[0],
> + convert_modes (SFmode, HFmode, operands[1], 0), 0);
> + DONE;
> + }
> + [(set_attr "type" "fcvt")
> + (set_attr "mode" "BF")])
I would suggest using a mode iterator to avoid explicit pattern duplication.
Essentially a mode iterator allows you to specify that the pattern
should be repeated over a series of modes.
It looks like you've deine a conversion from HF, DF, TF. So you define
an iterator that includes just those modes. You would use the mode
iterator rather than BF, DF or TF in your pattern.
That just fixes the mode in the pattern. You also need to have the name
automagically adjust as well. Use <mode> in the name. so the name
would be somethig like trunc<mode>bf2.
When you want to reference the mode in code you can do something like
E_<MODE>mode
And that will map down to HFmode, BFmode, TFmode appropriately.
I suspect you can do something similar for the extension patterns.
In fact, it looks like you did this for the move<mode>hardfloat pattern.
Jeff
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Re: [PING] [PATCH] RISC-V: Add Zfbfmin extension
2024-06-01 4:34 ` Jeff Law
@ 2024-06-01 7:41 ` Xiao Zeng
0 siblings, 0 replies; 3+ messages in thread
From: Xiao Zeng @ 2024-06-01 7:41 UTC (permalink / raw)
To: jeffreyalaw, gcc-patches; +Cc: research_trasio, kito.cheng, palmer, zhengyu
2024-06-01 12:34 Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
>On 5/30/24 5:38 AM, Xiao Zeng wrote:
>> 1 In the previous patch, the libcall for BF16 was implemented:
>> <https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8c7cee80eb50792e57d514be1418c453ddd1073e>
>>
>> 2 Riscv provides Zfbfmin extension, which completes the "Scalar BF16 Converts":
>> <https://github.com/riscv/riscv-bfloat16/blob/main/doc/riscv-bfloat16-zfbfmin.adoc>
>>
>> 3 Implemented replacing libcall with Zfbfmin extension instruction.
>>
>> 4 Reused previous testcases in:
>> <https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8c7cee80eb50792e57d514be1418c453ddd1073e>
>>
>> gcc/ChangeLog:
>>
>> * config/riscv/riscv.cc (riscv_output_move): Handle BFmode move
>> for zfbfmin.
>> * config/riscv/riscv.md (truncsfbf2): New pattern for BFmode.
>> (trunchfbf2): Dotto.
>> (truncdfbf2): Dotto.
>> (trunctfbf2): Dotto.
>> (extendbfsf2): Dotto.
>> (*movhf_hardfloat): Add BFmode.
>> (*mov<mode>_hardfloat): Dotto.
>>
>> gcc/testsuite/ChangeLog:
>>
>> * gcc.target/riscv/zfbfmin-bf16_arithmetic.c: New test.
>> * gcc.target/riscv/zfbfmin-bf16_comparison.c: New test.
>> * gcc.target/riscv/zfbfmin-bf16_float_libcall_convert.c: New test.
>> * gcc.target/riscv/zfbfmin-bf16_integer_libcall_convert.c: New test.
>> ---
>
>>
>
>
>
>> +
>> +;; The conversion of HF/DF/TF to BF needs to be done with SF if there is a
>> +;; chance to generate at least one instruction, otherwise just using
>> +;; libfunc __trunc[h|d|t]fbf2.
>> +(define_expand "trunchfbf2"
>> + [(set (match_operand:BF 0 "register_operand" "=f")
>> + (float_truncate:BF
>> + (match_operand:HF 1 "register_operand" " f")))]
>> + "TARGET_ZFBFMIN"
>> + {
>> + convert_move (operands[0],
>> + convert_modes (SFmode, HFmode, operands[1], 0), 0);
>> + DONE;
>> + }
>> + [(set_attr "type" "fcvt")
>> + (set_attr "mode" "BF")])
>I would suggest using a mode iterator to avoid explicit pattern duplication.
>
>Essentially a mode iterator allows you to specify that the pattern
>should be repeated over a series of modes.
Yes, this will make the code look more concise and avoid redundancy.
>
>It looks like you've deine a conversion from HF, DF, TF.
Yes.
>So you define an iterator that includes just those modes.
Yes.
>You would use the mode iterator rather than BF, DF or TF in your pattern.
Fixed.
>
>That just fixes the mode in the pattern.
>You also need to have the name automagically adjust as well. Use <mode> in the name. so the name
>would be somethig like trunc<mode>bf2.
Of course, this is necessary.
>
>When you want to reference the mode in code you can do something like
>E_<MODE>mode
Yes.
>
>And that will map down to HFmode, BFmode, TFmode appropriately.
>
>I suspect you can do something similar for the extension patterns.
>
>In fact, it looks like you did this for the move<mode>hardfloat pattern.
>
>Jeff
Thank you for Jeff's suggestion. v2 has already been uploaded.
<https://patchwork.sourceware.org/project/gcc/patch/20240601074547.80271-1-zengxiao@eswincomputing.com/>
Thanks
Xiao Zeng
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-06-01 7:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-30 11:38 [PING] [PATCH] RISC-V: Add Zfbfmin extension Xiao Zeng
2024-06-01 4:34 ` Jeff Law
2024-06-01 7:41 ` Xiao Zeng
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).