[llvm] [RISCV][llvm] Support widening fadd, fsub and fmul codegen for zvfbfa (PR #192414)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 16 02:11:14 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Brandon Wu (4vtomat)

<details>
<summary>Changes</summary>



---

Patch is 133.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/192414.diff


9 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+4-3) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td (+10-8) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td (+9-7) 
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll (+668-4) 
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll (+414-4) 
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll (+619-4) 
- (modified) llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll (+578-4) 
- (modified) llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll (+326-4) 
- (modified) llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll (+578-4) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 1148b801530a0..c1211b02b8f9c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -18428,9 +18428,10 @@ static std::optional<CombineResult>
 canFoldToVWWithSameExtension(SDNode *Root, const NodeExtensionHelper &LHS,
                              const NodeExtensionHelper &RHS, SelectionDAG &DAG,
                              const RISCVSubtarget &Subtarget) {
-  return canFoldToVWWithSameExtensionImpl(
-      Root, LHS, RHS, ExtKind::ZExt | ExtKind::SExt | ExtKind::FPExt, DAG,
-      Subtarget);
+  return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS,
+                                          ExtKind::ZExt | ExtKind::SExt |
+                                              ExtKind::FPExt | ExtKind::BF16Ext,
+                                          DAG, Subtarget);
 }
 
 /// Check if \p Root follows a pattern Root(zext(LHS), zext(RHS))
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
index 4c558c4524c5b..a0a2ded36b2a0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
@@ -591,10 +591,11 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF<SDNode op, string instruction_name> {
 }
 
 multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name> {
-  foreach vtiToWti = AllWidenableFloatVectors in {
+  foreach vtiToWti = AllWidenableFloatAndBF16Vectors in {
     defvar vti = vtiToWti.Vti;
     defvar wti = vtiToWti.Wti;
     defvar suffix = vti.LMul.MX#"_E"#vti.SEW;
+    defvar alt = !if(!eq(vti.Scalar, bf16), "_ALT", "");
     let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
                                  GetVTypePredicates<wti>.Predicates) in {
       def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser
@@ -603,7 +604,7 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name>
                     (wti.Vector (riscv_fpextend_vl_sameuser
                                      (vti.Vector vti.RegClass:$rs1),
                                      (vti.Mask true_mask), (XLenVT srcvalue)))),
-                (!cast<Instruction>(instruction_name#"_VV_"#suffix)
+                (!cast<Instruction>(instruction_name#alt#"_VV_"#suffix)
                   (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,
                   vti.RegClass:$rs1,
                    // Value to indicate no rounding mode change in
@@ -616,7 +617,7 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name>
                     (wti.Vector (riscv_fpextend_vl_sameuser
                                      (vti.Vector (SplatFPOp (vti.Scalar vti.ScalarRegClass:$rs1))),
                                      (vti.Mask true_mask), (XLenVT srcvalue)))),
-                (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)
+                (!cast<Instruction>(instruction_name#alt#"_V"#vti.ScalarSuffix#"_"#suffix)
                    (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,
                    vti.ScalarRegClass:$rs1,
                    // Value to indicate no rounding mode change in
@@ -627,7 +628,7 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name>
                                      (vti.Vector vti.RegClass:$rs2),
                                      (vti.Mask true_mask), (XLenVT srcvalue))),
                     (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))),
-                (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)
+                (!cast<Instruction>(instruction_name#alt#"_V"#vti.ScalarSuffix#"_"#suffix)
                    (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,
                    vti.ScalarRegClass:$rs1,
                    // Value to indicate no rounding mode change in
@@ -639,17 +640,18 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name>
 }
 
 multiclass VPatWidenBinaryFPSDNode_WV_WF_RM<SDNode op, string instruction_name> {
-  foreach vtiToWti = AllWidenableFloatVectors in {
+  foreach vtiToWti = AllWidenableFloatAndBF16Vectors in {
     defvar vti = vtiToWti.Vti;
     defvar wti = vtiToWti.Wti;
     defvar suffix = vti.LMul.MX#"_E"#vti.SEW;
+    defvar alt = !if(!eq(vti.Scalar, bf16), "_ALT", "");
     let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
                                  GetVTypePredicates<wti>.Predicates) in {
       def : Pat<(op (wti.Vector wti.RegClass:$rs2),
                     (wti.Vector (riscv_fpextend_vl_oneuse
                                      (vti.Vector vti.RegClass:$rs1),
                                      (vti.Mask true_mask), (XLenVT srcvalue)))),
-                (!cast<Instruction>(instruction_name#"_WV_"#suffix#"_TIED")
+                (!cast<Instruction>(instruction_name#alt#"_WV_"#suffix#"_TIED")
                    wti.RegClass:$rs2, vti.RegClass:$rs1,
                    // Value to indicate no rounding mode change in
                    // RISCVInsertReadWriteCSR
@@ -660,7 +662,7 @@ multiclass VPatWidenBinaryFPSDNode_WV_WF_RM<SDNode op, string instruction_name>
                     (wti.Vector (riscv_fpextend_vl_oneuse
                                      (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)),
                                      (vti.Mask true_mask), (XLenVT srcvalue)))),
-                (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#suffix)
+                (!cast<Instruction>(instruction_name#alt#"_W"#vti.ScalarSuffix#"_"#suffix)
                    (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2,
                    vti.ScalarRegClass:$rs1,
                    // Value to indicate no rounding mode change in
@@ -669,7 +671,7 @@ multiclass VPatWidenBinaryFPSDNode_WV_WF_RM<SDNode op, string instruction_name>
                    vti.AVL, vti.Log2SEW, TA_MA)>;
       def : Pat<(op (wti.Vector wti.RegClass:$rs2),
                     (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))),
-                (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#suffix)
+                (!cast<Instruction>(instruction_name#alt#"_W"#vti.ScalarSuffix#"_"#suffix)
                    (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2,
                    vti.ScalarRegClass:$rs1,
                    // Value to indicate no rounding mode change in
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
index 2a99492bc5596..9cd4edb97c7e0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
@@ -1619,16 +1619,17 @@ multiclass VPatBinaryFPWVL_VV_VF<SDNode vop, string instruction_name> {
 
 multiclass VPatBinaryFPWVL_VV_VF_RM<SDNode vop, string instruction_name,
                                     bit isSEWAware = 0> {
-  foreach fvtiToFWti = AllWidenableFloatVectors in {
+  foreach fvtiToFWti = AllWidenableFloatAndBF16Vectors in {
     defvar vti = fvtiToFWti.Vti;
     defvar wti = fvtiToFWti.Wti;
+    defvar alt = !if(!eq(vti.Scalar, bf16), "_ALT", "");
     let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
                                  GetVTypePredicates<wti>.Predicates) in {
-      def : VPatBinaryVL_V_RM<vop, instruction_name, "VV",
+      def : VPatBinaryVL_V_RM<vop, instruction_name#alt, "VV",
                                        wti.Vector, vti.Vector, vti.Vector, vti.Mask,
                                        vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass,
                                        vti.RegClass, isSEWAware>;
-      def : VPatBinaryVL_VF_RM<vop, instruction_name#"_V"#vti.ScalarSuffix,
+      def : VPatBinaryVL_VF_RM<vop, instruction_name#alt#"_V"#vti.ScalarSuffix,
                                         wti.Vector, vti.Vector, vti.Vector, vti.Mask,
                                         vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass,
                                         vti.ScalarRegClass, isSEWAware>;
@@ -1661,20 +1662,21 @@ multiclass VPatBinaryFPWVL_VV_VF_WV_WF<SDNode vop, SDNode vop_w, string instruct
 multiclass VPatBinaryFPWVL_VV_VF_WV_WF_RM<
     SDNode vop, SDNode vop_w, string instruction_name, bit isSEWAware = 0>
     : VPatBinaryFPWVL_VV_VF_RM<vop, instruction_name, isSEWAware> {
-  foreach fvtiToFWti = AllWidenableFloatVectors in {
+  foreach fvtiToFWti = AllWidenableFloatAndBF16Vectors in {
     defvar vti = fvtiToFWti.Vti;
     defvar wti = fvtiToFWti.Wti;
+    defvar alt = !if(!eq(vti.Scalar, bf16), "_ALT", "");
     let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
                                  GetVTypePredicates<wti>.Predicates) in {
-      defm : VPatTiedBinaryNoMaskVL_V_RM<vop_w, instruction_name, "WV",
+      defm : VPatTiedBinaryNoMaskVL_V_RM<vop_w, instruction_name#alt, "WV",
                                          wti.Vector, vti.Vector, vti.Log2SEW,
                                          vti.LMul, wti.RegClass, vti.RegClass,
                                          isSEWAware>;
-      def : VPatBinaryVL_V_RM<vop_w, instruction_name, "WV",
+      def : VPatBinaryVL_V_RM<vop_w, instruction_name#alt, "WV",
                                        wti.Vector, wti.Vector, vti.Vector, vti.Mask,
                                        vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass,
                                        vti.RegClass, isSEWAware>;
-      def : VPatBinaryVL_VF_RM<vop_w, instruction_name#"_W"#vti.ScalarSuffix,
+      def : VPatBinaryVL_VF_RM<vop_w, instruction_name#alt#"_W"#vti.ScalarSuffix,
                                         wti.Vector, wti.Vector, vti.Vector, vti.Mask,
                                         vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass,
                                         vti.ScalarRegClass, isSEWAware>;
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll
index ebb920f0ac42e..e1f156f99c1d5 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll
@@ -1,8 +1,12 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv32 -mattr=+v,+zvfh,+f,+d -target-abi=ilp32d \
-; RUN:   -verify-machineinstrs < %s | FileCheck %s
-; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfh,+f,+d -target-abi=lp64d \
-; RUN:   -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=riscv32 -mattr=+v,+zvfh,+zvfbfmin,+f,+d -target-abi=ilp32d \
+; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfh,+zvfbfmin,+f,+d -target-abi=lp64d \
+; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv32 -mattr=+v,+zvfh,+experimental-zvfbfa,+f,+d \
+; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfh,+experimental-zvfbfa,+f,+d \
+; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
 
 define <2 x float> @vfwadd_v2f16(ptr %x, ptr %y) {
 ; CHECK-LABEL: vfwadd_v2f16:
@@ -674,3 +678,663 @@ define <2 x float> @vfwadd_wf2_v2f32(<2 x float> %x, half %y) {
   %e = fadd <2 x float> %x, %d
   ret <2 x float> %e
 }
+
+define <2 x float> @vfwadd_v2bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a0)
+; ZVFH-NEXT:    vle16.v v9, (a1)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v8, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vle16.v v10, (a1)
+; ZVFBFA-NEXT:    vfwadd.vv v8, v9, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <2 x bfloat>, ptr %x
+  %b = load <2 x bfloat>, ptr %y
+  %c = fpext <2 x bfloat> %a to <2 x float>
+  %d = fpext <2 x bfloat> %b to <2 x float>
+  %e = fadd <2 x float> %c, %d
+  ret <2 x float> %e
+}
+
+define <4 x float> @vfwadd_v4bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a0)
+; ZVFH-NEXT:    vle16.v v9, (a1)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v8, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vle16.v v10, (a1)
+; ZVFBFA-NEXT:    vfwadd.vv v8, v9, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x bfloat>, ptr %x
+  %b = load <4 x bfloat>, ptr %y
+  %c = fpext <4 x bfloat> %a to <4 x float>
+  %d = fpext <4 x bfloat> %b to <4 x float>
+  %e = fadd <4 x float> %c, %d
+  ret <4 x float> %e
+}
+
+define <8 x float> @vfwadd_v8bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle16.v v10, (a0)
+; ZVFH-NEXT:    vle16.v v12, (a1)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v8, v10
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v12
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v10, (a0)
+; ZVFBFA-NEXT:    vle16.v v11, (a1)
+; ZVFBFA-NEXT:    vfwadd.vv v8, v10, v11
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x bfloat>, ptr %x
+  %b = load <8 x bfloat>, ptr %y
+  %c = fpext <8 x bfloat> %a to <8 x float>
+  %d = fpext <8 x bfloat> %b to <8 x float>
+  %e = fadd <8 x float> %c, %d
+  ret <8 x float> %e
+}
+
+define <16 x float> @vfwadd_v16bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle16.v v12, (a0)
+; ZVFH-NEXT:    vle16.v v16, (a1)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v8, v12
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v16
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a0)
+; ZVFBFA-NEXT:    vle16.v v14, (a1)
+; ZVFBFA-NEXT:    vfwadd.vv v8, v12, v14
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x bfloat>, ptr %x
+  %b = load <16 x bfloat>, ptr %y
+  %c = fpext <16 x bfloat> %a to <16 x float>
+  %d = fpext <16 x bfloat> %b to <16 x float>
+  %e = fadd <16 x float> %c, %d
+  ret <16 x float> %e
+}
+
+define <32 x float> @vfwadd_v32bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_v32bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    li a2, 32
+; ZVFH-NEXT:    vsetvli zero, a2, e16, m4, ta, ma
+; ZVFH-NEXT:    vle16.v v16, (a0)
+; ZVFH-NEXT:    vle16.v v24, (a1)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v8, v16
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v24
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_v32bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    li a2, 32
+; ZVFBFA-NEXT:    vsetvli zero, a2, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v16, (a0)
+; ZVFBFA-NEXT:    vle16.v v20, (a1)
+; ZVFBFA-NEXT:    vfwadd.vv v8, v16, v20
+; ZVFBFA-NEXT:    ret
+  %a = load <32 x bfloat>, ptr %x
+  %b = load <32 x bfloat>, ptr %y
+  %c = fpext <32 x bfloat> %a to <32 x float>
+  %d = fpext <32 x bfloat> %b to <32 x float>
+  %e = fadd <32 x float> %c, %d
+  ret <32 x float> %e
+}
+
+define <64 x float> @vfwadd_v64bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_v64bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    addi sp, sp, -16
+; ZVFH-NEXT:    .cfi_def_cfa_offset 16
+; ZVFH-NEXT:    csrr a2, vlenb
+; ZVFH-NEXT:    slli a2, a2, 3
+; ZVFH-NEXT:    sub sp, sp, a2
+; ZVFH-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 8 * vlenb
+; ZVFH-NEXT:    li a2, 64
+; ZVFH-NEXT:    vsetvli zero, a2, e16, m8, ta, ma
+; ZVFH-NEXT:    vle16.v v16, (a0)
+; ZVFH-NEXT:    vle16.v v8, (a1)
+; ZVFH-NEXT:    li a0, 32
+; ZVFH-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
+; ZVFH-NEXT:    vslidedown.vx v24, v16, a0
+; ZVFH-NEXT:    vsetvli zero, a0, e16, m4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v0, v16
+; ZVFH-NEXT:    addi a1, sp, 16
+; ZVFH-NEXT:    vs8r.v v0, (a1) # vscale x 64-byte Folded Spill
+; ZVFH-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
+; ZVFH-NEXT:    vslidedown.vx v16, v8, a0
+; ZVFH-NEXT:    vsetvli zero, a0, e16, m4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v0, v8
+; ZVFH-NEXT:    vmv4r.v v8, v24
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v24, v8
+; ZVFH-NEXT:    vmv4r.v v8, v16
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v8
+; ZVFH-NEXT:    addi a0, sp, 16
+; ZVFH-NEXT:    vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v0
+; ZVFH-NEXT:    vfadd.vv v16, v24, v16
+; ZVFH-NEXT:    csrr a0, vlenb
+; ZVFH-NEXT:    slli a0, a0, 3
+; ZVFH-NEXT:    add sp, sp, a0
+; ZVFH-NEXT:    .cfi_def_cfa sp, 16
+; ZVFH-NEXT:    addi sp, sp, 16
+; ZVFH-NEXT:    .cfi_def_cfa_offset 0
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_v64bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    addi sp, sp, -16
+; ZVFBFA-NEXT:    .cfi_def_cfa_offset 16
+; ZVFBFA-NEXT:    csrr a2, vlenb
+; ZVFBFA-NEXT:    slli a2, a2, 3
+; ZVFBFA-NEXT:    sub sp, sp, a2
+; ZVFBFA-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 8 * vlenb
+; ZVFBFA-NEXT:    li a2, 64
+; ZVFBFA-NEXT:    vsetvli zero, a2, e16, m8, ta, ma
+; ZVFBFA-NEXT:    vle16.v v16, (a0)
+; ZVFBFA-NEXT:    vle16.v v24, (a1)
+; ZVFBFA-NEXT:    li a0, 32
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
+; ZVFBFA-NEXT:    vslidedown.vx v8, v16, a0
+; ZVFBFA-NEXT:    addi a1, sp, 16
+; ZVFBFA-NEXT:    vs8r.v v8, (a1) # vscale x 64-byte Folded Spill
+; ZVFBFA-NEXT:    vslidedown.vx v0, v24, a0
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vfwadd.vv v8, v16, v24
+; ZVFBFA-NEXT:    addi a0, sp, 16
+; ZVFBFA-NEXT:    vl8r.v v24, (a0) # vscale x 64-byte Folded Reload
+; ZVFBFA-NEXT:    vfwadd.vv v16, v24, v0
+; ZVFBFA-NEXT:    csrr a0, vlenb
+; ZVFBFA-NEXT:    slli a0, a0, 3
+; ZVFBFA-NEXT:    add sp, sp, a0
+; ZVFBFA-NEXT:    .cfi_def_cfa sp, 16
+; ZVFBFA-NEXT:    addi sp, sp, 16
+; ZVFBFA-NEXT:    .cfi_def_cfa_offset 0
+; ZVFBFA-NEXT:    ret
+  %a = load <64 x bfloat>, ptr %x
+  %b = load <64 x bfloat>, ptr %y
+  %c = fpext <64 x bfloat> %a to <64 x float>
+  %d = fpext <64 x bfloat> %b to <64 x float>
+  %e = fadd <64 x float> %c, %d
+  ret <64 x float> %e
+}
+
+define <2 x float> @vfwadd_vf_v2bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_vf_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v9, a0
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v8, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vfwadd.vf v8, v9, fa0
+; ZVFBFA-NEXT:    ret
+  %a = load <2 x bfloat>, ptr %x
+  %b = insertelement <2 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <2 x bfloat> %b, <2 x bfloat> poison, <2 x i32> zeroinitializer
+  %d = fpext <2 x bfloat> %a to <2 x float>
+  %e = fpext <2 x bfloat> %c to <2 x float>
+  %f = fadd <2 x float> %d, %e
+  ret <2 x float> %f
+}
+
+define <4 x float> @vfwadd_vf_v4bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_vf_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/192414


More information about the llvm-commits mailing list