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

Brandon Wu via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 16 02:10:39 PDT 2026


https://github.com/4vtomat created https://github.com/llvm/llvm-project/pull/192414

None

>From 28a75744bba7e3b62b7b92d48b168c2d98abe667 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Thu, 16 Apr 2026 15:58:13 +0800
Subject: [PATCH 1/2] pre-commit tests

---
 .../CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll | 718 +++++++++++++++++-
 .../CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll | 466 +++++++++++-
 .../CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll | 667 +++++++++++++++-
 llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll  | 621 ++++++++++++++-
 llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll  | 353 ++++++++-
 llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll  | 621 ++++++++++++++-
 6 files changed, 3422 insertions(+), 24 deletions(-)

diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll
index ebb920f0ac42e..ebdb4880a8ab7 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,709 @@ 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 v8, (a0)
+; ZVFBFA-NEXT:    vle16.v v9, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; 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 v8, (a0)
+; ZVFBFA-NEXT:    vle16.v v9, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; 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 v12, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; 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 v16, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; 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 v24, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v16
+; 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 v8, (a1)
+; ZVFBFA-NEXT:    li a0, 32
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
+; ZVFBFA-NEXT:    vslidedown.vx v24, v16, a0
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v16
+; ZVFBFA-NEXT:    addi a1, sp, 16
+; ZVFBFA-NEXT:    vs8r.v v0, (a1) # vscale x 64-byte Folded Spill
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m8, ta, ma
+; ZVFBFA-NEXT:    vslidedown.vx v16, v8, a0
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v8
+; ZVFBFA-NEXT:    vmv4r.v v8, v24
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v24, v8
+; ZVFBFA-NEXT:    vmv4r.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v8
+; ZVFBFA-NEXT:    addi a0, sp, 16
+; ZVFBFA-NEXT:    vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v0
+; ZVFBFA-NEXT:    vfadd.vv v16, v24, v16
+; 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 v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; 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, e16, mf2, 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, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x bfloat>, ptr %x
+  %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <4 x bfloat> %b, <4 x bfloat> poison, <4 x i32> zeroinitializer
+  %d = fpext <4 x bfloat> %a to <4 x float>
+  %e = fpext <4 x bfloat> %c to <4 x float>
+  %f = fadd <4 x float> %d, %e
+  ret <4 x float> %f
+}
+
+define <8 x float> @vfwadd_vf_v8bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_vf_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle16.v v10, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v12, a0
+; 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_vf_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v10, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x bfloat>, ptr %x
+  %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <8 x bfloat> %b, <8 x bfloat> poison, <8 x i32> zeroinitializer
+  %d = fpext <8 x bfloat> %a to <8 x float>
+  %e = fpext <8 x bfloat> %c to <8 x float>
+  %f = fadd <8 x float> %d, %e
+  ret <8 x float> %f
+}
+
+define <16 x float> @vfwadd_vf_v16bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_vf_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle16.v v12, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v16, a0
+; 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_vf_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x bfloat>, ptr %x
+  %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <16 x bfloat> %b, <16 x bfloat> poison, <16 x i32> zeroinitializer
+  %d = fpext <16 x bfloat> %a to <16 x float>
+  %e = fpext <16 x bfloat> %c to <16 x float>
+  %f = fadd <16 x float> %d, %e
+  ret <16 x float> %f
+}
+
+define <32 x float> @vfwadd_vf_v32bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_vf_v32bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    li a1, 32
+; ZVFH-NEXT:    vsetvli zero, a1, e16, m4, ta, ma
+; ZVFH-NEXT:    vle16.v v16, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v24, a0
+; 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_vf_v32bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    li a1, 32
+; ZVFBFA-NEXT:    vsetvli zero, a1, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v16, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v24, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v16
+; ZVFBFA-NEXT:    ret
+  %a = load <32 x bfloat>, ptr %x
+  %b = insertelement <32 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <32 x bfloat> %b, <32 x bfloat> poison, <32 x i32> zeroinitializer
+  %d = fpext <32 x bfloat> %a to <32 x float>
+  %e = fpext <32 x bfloat> %c to <32 x float>
+  %f = fadd <32 x float> %d, %e
+  ret <32 x float> %f
+}
+
+define <2 x float> @vfwadd_wv_v2bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_wv_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a1)
+; ZVFH-NEXT:    vle32.v v9, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v9, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wv_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a1)
+; ZVFBFA-NEXT:    vle32.v v9, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v9, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <2 x float>, ptr %x
+  %b = load <2 x bfloat>, ptr %y
+  %c = fpext <2 x bfloat> %b to <2 x float>
+  %d = fadd <2 x float> %a, %c
+  ret <2 x float> %d
+}
+
+define <4 x float> @vfwadd_wv_v4bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_wv_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a1)
+; ZVFH-NEXT:    vle32.v v9, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v9, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wv_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a1)
+; ZVFBFA-NEXT:    vle32.v v9, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v9, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x float>, ptr %x
+  %b = load <4 x bfloat>, ptr %y
+  %c = fpext <4 x bfloat> %b to <4 x float>
+  %d = fadd <4 x float> %a, %c
+  ret <4 x float> %d
+}
+
+define <8 x float> @vfwadd_wv_v8bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_wv_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle16.v v12, (a1)
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; 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_wv_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a1)
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x float>, ptr %x
+  %b = load <8 x bfloat>, ptr %y
+  %c = fpext <8 x bfloat> %b to <8 x float>
+  %d = fadd <8 x float> %a, %c
+  ret <8 x float> %d
+}
+
+define <16 x float> @vfwadd_wv_v16bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_wv_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle16.v v16, (a1)
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; 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_wv_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v16, (a1)
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x float>, ptr %x
+  %b = load <16 x bfloat>, ptr %y
+  %c = fpext <16 x bfloat> %b to <16 x float>
+  %d = fadd <16 x float> %a, %c
+  ret <16 x float> %d
+}
+
+define <32 x float> @vfwadd_wv_v32bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwadd_wv_v32bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    li a2, 32
+; ZVFH-NEXT:    vsetvli zero, a2, e16, m4, ta, ma
+; ZVFH-NEXT:    vle16.v v24, (a1)
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; 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_wv_v32bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    li a2, 32
+; ZVFBFA-NEXT:    vsetvli zero, a2, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v24, (a1)
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v16
+; ZVFBFA-NEXT:    ret
+  %a = load <32 x float>, ptr %x
+  %b = load <32 x bfloat>, ptr %y
+  %c = fpext <32 x bfloat> %b to <32 x float>
+  %d = fadd <32 x float> %a, %c
+  ret <32 x float> %d
+}
+
+define <2 x float> @vfwadd_wf_v2bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_wf_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v9, a0
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <2 x float>, 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> %c to <2 x float>
+  %e = fadd <2 x float> %a, %d
+  ret <2 x float> %e
+}
+
+define <4 x float> @vfwadd_wf_v4bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_wf_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v9, a0
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x float>, ptr %x
+  %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <4 x bfloat> %b, <4 x bfloat> poison, <4 x i32> zeroinitializer
+  %d = fpext <4 x bfloat> %c to <4 x float>
+  %e = fadd <4 x float> %a, %d
+  ret <4 x float> %e
+}
+
+define <8 x float> @vfwadd_wf_v8bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_wf_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v12, a0
+; 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_wf_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x float>, ptr %x
+  %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <8 x bfloat> %b, <8 x bfloat> poison, <8 x i32> zeroinitializer
+  %d = fpext <8 x bfloat> %c to <8 x float>
+  %e = fadd <8 x float> %a, %d
+  ret <8 x float> %e
+}
+
+define <16 x float> @vfwadd_wf_v16bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_wf_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v16, a0
+; 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_wf_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x float>, ptr %x
+  %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <16 x bfloat> %b, <16 x bfloat> poison, <16 x i32> zeroinitializer
+  %d = fpext <16 x bfloat> %c to <16 x float>
+  %e = fadd <16 x float> %a, %d
+  ret <16 x float> %e
+}
+
+define <2 x float> @vfwadd_vf2_v2bf16(<2 x bfloat> %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_vf2_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf2_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %a = fpext <2 x bfloat> %x to <2 x float>
+  %b = fpext bfloat %y to float
+  %c = insertelement <2 x float> poison, float %b, i32 0
+  %d = shufflevector <2 x float> %c, <2 x float> poison, <2 x i32> zeroinitializer
+  %e = fadd <2 x float> %a, %d
+  ret <2 x float> %e
+}
+
+define <2 x float> @vfwadd_wf2_v2bf16(<2 x float> %x, bfloat %y) {
+; ZVFH-LABEL: vfwadd_wf2_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetivli zero, 2, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf2_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetivli zero, 2, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %b = fpext bfloat %y to float
+  %c = insertelement <2 x float> poison, float %b, i32 0
+  %d = shufflevector <2 x float> %c, <2 x float> poison, <2 x i32> zeroinitializer
+  %e = fadd <2 x float> %x, %d
+  ret <2 x float> %e
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll
index 47ac1c1a88df4..a6cb68eedaece 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.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> @vfwmul_v2f16(ptr %x, ptr %y) {
 ; CHECK-LABEL: vfwmul_v2f16:
@@ -446,3 +450,457 @@ define <2 x float> @vfwmul_vf2_v2f32(<2 x half> %x, half %y) {
   %e = fmul <2 x float> %a, %d
   ret <2 x float> %e
 }
+
+define <2 x float> @vfwmul_v2bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwmul_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:    vfmul.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vle16.v v9, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; 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 = fmul <2 x float> %c, %d
+  ret <2 x float> %e
+}
+
+define <4 x float> @vfwmul_v4bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwmul_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:    vfmul.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vle16.v v9, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; 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 = fmul <4 x float> %c, %d
+  ret <4 x float> %e
+}
+
+define <8 x float> @vfwmul_v8bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwmul_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:    vfmul.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v10, (a0)
+; ZVFBFA-NEXT:    vle16.v v12, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v8, v10
+; 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 = fmul <8 x float> %c, %d
+  ret <8 x float> %e
+}
+
+define <16 x float> @vfwmul_v16bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwmul_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:    vfmul.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a0)
+; ZVFBFA-NEXT:    vle16.v v16, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v8, v12
+; 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 = fmul <16 x float> %c, %d
+  ret <16 x float> %e
+}
+
+define <32 x float> @vfwmul_v32bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwmul_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:    vfmul.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_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 v24, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v8, v16
+; 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 = fmul <32 x float> %c, %d
+  ret <32 x float> %e
+}
+
+define <64 x float> @vfwmul_v64bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwmul_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:    vfmul.vv v8, v8, v0
+; ZVFH-NEXT:    vfmul.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: vfwmul_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 v8, (a1)
+; ZVFBFA-NEXT:    li a0, 32
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
+; ZVFBFA-NEXT:    vslidedown.vx v24, v16, a0
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v16
+; ZVFBFA-NEXT:    addi a1, sp, 16
+; ZVFBFA-NEXT:    vs8r.v v0, (a1) # vscale x 64-byte Folded Spill
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m8, ta, ma
+; ZVFBFA-NEXT:    vslidedown.vx v16, v8, a0
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v8
+; ZVFBFA-NEXT:    vmv4r.v v8, v24
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v24, v8
+; ZVFBFA-NEXT:    vmv4r.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v8
+; ZVFBFA-NEXT:    addi a0, sp, 16
+; ZVFBFA-NEXT:    vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v8, v0
+; ZVFBFA-NEXT:    vfmul.vv v16, v24, v16
+; 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 = fmul <64 x float> %c, %d
+  ret <64 x float> %e
+}
+
+define <2 x float> @vfwmul_vf_v2bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwmul_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:    vfmul.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; 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 = fmul <2 x float> %d, %e
+  ret <2 x float> %f
+}
+
+define <4 x float> @vfwmul_vf_v4bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwmul_vf_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, e16, mf2, 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, m1, ta, ma
+; ZVFH-NEXT:    vfmul.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x bfloat>, ptr %x
+  %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <4 x bfloat> %b, <4 x bfloat> poison, <4 x i32> zeroinitializer
+  %d = fpext <4 x bfloat> %a to <4 x float>
+  %e = fpext <4 x bfloat> %c to <4 x float>
+  %f = fmul <4 x float> %d, %e
+  ret <4 x float> %f
+}
+
+define <8 x float> @vfwmul_vf_v8bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwmul_vf_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle16.v v10, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v12, a0
+; 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:    vfmul.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v10, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x bfloat>, ptr %x
+  %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <8 x bfloat> %b, <8 x bfloat> poison, <8 x i32> zeroinitializer
+  %d = fpext <8 x bfloat> %a to <8 x float>
+  %e = fpext <8 x bfloat> %c to <8 x float>
+  %f = fmul <8 x float> %d, %e
+  ret <8 x float> %f
+}
+
+define <16 x float> @vfwmul_vf_v16bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwmul_vf_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle16.v v12, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v16, a0
+; 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:    vfmul.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x bfloat>, ptr %x
+  %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <16 x bfloat> %b, <16 x bfloat> poison, <16 x i32> zeroinitializer
+  %d = fpext <16 x bfloat> %a to <16 x float>
+  %e = fpext <16 x bfloat> %c to <16 x float>
+  %f = fmul <16 x float> %d, %e
+  ret <16 x float> %f
+}
+
+define <32 x float> @vfwmul_vf_v32bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwmul_vf_v32bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    li a1, 32
+; ZVFH-NEXT:    vsetvli zero, a1, e16, m4, ta, ma
+; ZVFH-NEXT:    vle16.v v16, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v24, a0
+; 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:    vfmul.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_v32bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    li a1, 32
+; ZVFBFA-NEXT:    vsetvli zero, a1, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v16, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v24, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v8, v16
+; ZVFBFA-NEXT:    ret
+  %a = load <32 x bfloat>, ptr %x
+  %b = insertelement <32 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <32 x bfloat> %b, <32 x bfloat> poison, <32 x i32> zeroinitializer
+  %d = fpext <32 x bfloat> %a to <32 x float>
+  %e = fpext <32 x bfloat> %c to <32 x float>
+  %f = fmul <32 x float> %d, %e
+  ret <32 x float> %f
+}
+
+define <2 x float> @vfwmul_squared_v2bf16_v2f32(ptr %x) {
+; ZVFH-LABEL: vfwmul_squared_v2bf16_v2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfmul.vv v8, v9, v9
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_squared_v2bf16_v2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v9, v9
+; ZVFBFA-NEXT:    ret
+  %a = load <2 x bfloat>, ptr %x
+  %b = fpext <2 x bfloat> %a to <2 x float>
+  %c = fmul <2 x float> %b, %b
+  ret <2 x float> %c
+}
+
+define <2 x float> @vfwmul_vf2_v2bf16(<2 x bfloat> %x, bfloat %y) {
+; ZVFH-LABEL: vfwmul_vf2_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf2_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %a = fpext <2 x bfloat> %x to <2 x float>
+  %b = fpext bfloat %y to float
+  %c = insertelement <2 x float> poison, float %b, i32 0
+  %d = shufflevector <2 x float> %c, <2 x float> poison, <2 x i32> zeroinitializer
+  %e = fmul <2 x float> %a, %d
+  ret <2 x float> %e
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll
index 25f6b5ab27411..9f8cf86bd6b6a 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.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> @vfwsub_v2f16(ptr %x, ptr %y) {
 ; CHECK-LABEL: vfwsub_v2f16:
@@ -646,3 +650,658 @@ define <16 x double> @vfwsub_wf_v16f32(ptr %x, float %y) {
   %e = fsub <16 x double> %a, %d
   ret <16 x double> %e
 }
+
+define <2 x float> @vfwsub_v2bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_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:    vfsub.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vle16.v v9, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; 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 = fsub <2 x float> %c, %d
+  ret <2 x float> %e
+}
+
+define <4 x float> @vfwsub_v4bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_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:    vfsub.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vle16.v v9, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; 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 = fsub <4 x float> %c, %d
+  ret <4 x float> %e
+}
+
+define <8 x float> @vfwsub_v8bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_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:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v10, (a0)
+; ZVFBFA-NEXT:    vle16.v v12, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; 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 = fsub <8 x float> %c, %d
+  ret <8 x float> %e
+}
+
+define <16 x float> @vfwsub_v16bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_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:    vfsub.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a0)
+; ZVFBFA-NEXT:    vle16.v v16, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; 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 = fsub <16 x float> %c, %d
+  ret <16 x float> %e
+}
+
+define <32 x float> @vfwsub_v32bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_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:    vfsub.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_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 v24, (a1)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v16
+; 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 = fsub <32 x float> %c, %d
+  ret <32 x float> %e
+}
+
+define <64 x float> @vfwsub_v64bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_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:    vfsub.vv v8, v8, v0
+; ZVFH-NEXT:    vfsub.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: vfwsub_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 v8, (a1)
+; ZVFBFA-NEXT:    li a0, 32
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
+; ZVFBFA-NEXT:    vslidedown.vx v24, v16, a0
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v16
+; ZVFBFA-NEXT:    addi a1, sp, 16
+; ZVFBFA-NEXT:    vs8r.v v0, (a1) # vscale x 64-byte Folded Spill
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m8, ta, ma
+; ZVFBFA-NEXT:    vslidedown.vx v16, v8, a0
+; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v8
+; ZVFBFA-NEXT:    vmv4r.v v8, v24
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v24, v8
+; ZVFBFA-NEXT:    vmv4r.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v8
+; ZVFBFA-NEXT:    addi a0, sp, 16
+; ZVFBFA-NEXT:    vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v0
+; ZVFBFA-NEXT:    vfsub.vv v16, v24, v16
+; 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 = fsub <64 x float> %c, %d
+  ret <64 x float> %e
+}
+
+define <2 x float> @vfwsub_vf_v2bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_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:    vfsub.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; 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 = fsub <2 x float> %d, %e
+  ret <2 x float> %f
+}
+
+define <4 x float> @vfwsub_vf_v4bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_vf_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, e16, mf2, 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, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x bfloat>, ptr %x
+  %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <4 x bfloat> %b, <4 x bfloat> poison, <4 x i32> zeroinitializer
+  %d = fpext <4 x bfloat> %a to <4 x float>
+  %e = fpext <4 x bfloat> %c to <4 x float>
+  %f = fsub <4 x float> %d, %e
+  ret <4 x float> %f
+}
+
+define <8 x float> @vfwsub_vf_v8bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_vf_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle16.v v10, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v12, a0
+; 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:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v10, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x bfloat>, ptr %x
+  %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <8 x bfloat> %b, <8 x bfloat> poison, <8 x i32> zeroinitializer
+  %d = fpext <8 x bfloat> %a to <8 x float>
+  %e = fpext <8 x bfloat> %c to <8 x float>
+  %f = fsub <8 x float> %d, %e
+  ret <8 x float> %f
+}
+
+define <16 x float> @vfwsub_vf_v16bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_vf_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle16.v v12, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v16, a0
+; 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:    vfsub.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x bfloat>, ptr %x
+  %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <16 x bfloat> %b, <16 x bfloat> poison, <16 x i32> zeroinitializer
+  %d = fpext <16 x bfloat> %a to <16 x float>
+  %e = fpext <16 x bfloat> %c to <16 x float>
+  %f = fsub <16 x float> %d, %e
+  ret <16 x float> %f
+}
+
+define <32 x float> @vfwsub_vf_v32bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_vf_v32bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    li a1, 32
+; ZVFH-NEXT:    vsetvli zero, a1, e16, m4, ta, ma
+; ZVFH-NEXT:    vle16.v v16, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v24, a0
+; 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:    vfsub.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_v32bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    li a1, 32
+; ZVFBFA-NEXT:    vsetvli zero, a1, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v16, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v24, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v16
+; ZVFBFA-NEXT:    ret
+  %a = load <32 x bfloat>, ptr %x
+  %b = insertelement <32 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <32 x bfloat> %b, <32 x bfloat> poison, <32 x i32> zeroinitializer
+  %d = fpext <32 x bfloat> %a to <32 x float>
+  %e = fpext <32 x bfloat> %c to <32 x float>
+  %f = fsub <32 x float> %d, %e
+  ret <32 x float> %f
+}
+
+define <2 x float> @vfwsub_wv_v2bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_wv_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a1)
+; ZVFH-NEXT:    vle32.v v9, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v9, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a1)
+; ZVFBFA-NEXT:    vle32.v v9, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v9, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <2 x float>, ptr %x
+  %b = load <2 x bfloat>, ptr %y
+  %c = fpext <2 x bfloat> %b to <2 x float>
+  %d = fsub <2 x float> %a, %c
+  ret <2 x float> %d
+}
+
+define <4 x float> @vfwsub_wv_v4bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_wv_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFH-NEXT:    vle16.v v8, (a1)
+; ZVFH-NEXT:    vle32.v v9, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v9, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a1)
+; ZVFBFA-NEXT:    vle32.v v9, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v9, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x float>, ptr %x
+  %b = load <4 x bfloat>, ptr %y
+  %c = fpext <4 x bfloat> %b to <4 x float>
+  %d = fsub <4 x float> %a, %c
+  ret <4 x float> %d
+}
+
+define <8 x float> @vfwsub_wv_v8bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_wv_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle16.v v12, (a1)
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v12
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle16.v v12, (a1)
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x float>, ptr %x
+  %b = load <8 x bfloat>, ptr %y
+  %c = fpext <8 x bfloat> %b to <8 x float>
+  %d = fsub <8 x float> %a, %c
+  ret <8 x float> %d
+}
+
+define <16 x float> @vfwsub_wv_v16bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_wv_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle16.v v16, (a1)
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v16
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle16.v v16, (a1)
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x float>, ptr %x
+  %b = load <16 x bfloat>, ptr %y
+  %c = fpext <16 x bfloat> %b to <16 x float>
+  %d = fsub <16 x float> %a, %c
+  ret <16 x float> %d
+}
+
+define <32 x float> @vfwsub_wv_v32bf16(ptr %x, ptr %y) {
+; ZVFH-LABEL: vfwsub_wv_v32bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    li a2, 32
+; ZVFH-NEXT:    vsetvli zero, a2, e16, m4, ta, ma
+; ZVFH-NEXT:    vle16.v v24, (a1)
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v24
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_v32bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    li a2, 32
+; ZVFBFA-NEXT:    vsetvli zero, a2, e16alt, m4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v24, (a1)
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v16
+; ZVFBFA-NEXT:    ret
+  %a = load <32 x float>, ptr %x
+  %b = load <32 x bfloat>, ptr %y
+  %c = fpext <32 x bfloat> %b to <32 x float>
+  %d = fsub <32 x float> %a, %c
+  ret <32 x float> %d
+}
+
+define <2 x float> @vfwsub_wf_v2bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_wf_v2bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v9, a0
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <2 x float>, 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> %c to <2 x float>
+  %e = fsub <2 x float> %a, %d
+  ret <2 x float> %e
+}
+
+define <4 x float> @vfwsub_wf_v4bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_wf_v4bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v9, a0
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <4 x float>, ptr %x
+  %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <4 x bfloat> %b, <4 x bfloat> poison, <4 x i32> zeroinitializer
+  %d = fpext <4 x bfloat> %c to <4 x float>
+  %e = fsub <4 x float> %a, %d
+  ret <4 x float> %e
+}
+
+define <8 x float> @vfwsub_wf_v8bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_wf_v8bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v12, a0
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v12
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_v8bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %a = load <8 x float>, ptr %x
+  %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <8 x bfloat> %b, <8 x bfloat> poison, <8 x i32> zeroinitializer
+  %d = fpext <8 x bfloat> %c to <8 x float>
+  %e = fsub <8 x float> %a, %d
+  ret <8 x float> %e
+}
+
+define <16 x float> @vfwsub_wf_v16bf16(ptr %x, bfloat %y) {
+; ZVFH-LABEL: vfwsub_wf_v16bf16:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetivli zero, 16, e16, m2, ta, ma
+; ZVFH-NEXT:    vle32.v v8, (a0)
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vmv.v.x v16, a0
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v16
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_v16bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vle32.v v8, (a0)
+; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %a = load <16 x float>, ptr %x
+  %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
+  %c = shufflevector <16 x bfloat> %b, <16 x bfloat> poison, <16 x i32> zeroinitializer
+  %d = fpext <16 x bfloat> %c to <16 x float>
+  %e = fsub <16 x float> %a, %d
+  ret <16 x float> %e
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
index 8d41514161c61..73c1b57a30971 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
@@ -1,8 +1,12 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v -target-abi=ilp32d \
-; RUN:     -verify-machineinstrs < %s | FileCheck %s
-; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v -target-abi=lp64d \
-; RUN:     -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v,+zvfbfmin -target-abi=ilp32d \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v,+zvfbfmin -target-abi=lp64d \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v,+experimental-zvfbfa \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v,+experimental-zvfbfa \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
 
 define <vscale x 1 x double> @vfwadd_vv_nxv1f64(<vscale x 1 x float> %va, <vscale x 1 x float> %vb) {
 ; CHECK-LABEL: vfwadd_vv_nxv1f64:
@@ -338,3 +342,612 @@ define <vscale x 1 x double> @vfwadd_vv_nxv1f64_same_op(<vscale x 1 x float> %va
   %vc = fadd <vscale x 1 x double> %vb, %vb
   ret <vscale x 1 x double> %vc
 }
+
+define <vscale x 1 x float> @vfwadd_vv_nxv1f32(<vscale x 1 x bfloat> %va, <vscale x 1 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_vv_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; 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_vv_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vd = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
+  %ve = fadd <vscale x 1 x float> %vc, %vd
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwadd_vf_nxv1f32(<vscale x 1 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vd = fpext <vscale x 1 x bfloat> %splat to <vscale x 1 x float>
+  %ve = fadd <vscale x 1 x float> %vc, %vd
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwadd_vf_nxv1f32_2(<vscale x 1 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv1f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv1f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 1 x float> %head, <vscale x 1 x float> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %ve = fadd <vscale x 1 x float> %vc, %splat
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwadd_wv_nxv1f32(<vscale x 1 x float> %va, <vscale x 1 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_wv_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wv_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
+  %vd = fadd <vscale x 1 x float> %va, %vc
+  ret <vscale x 1 x float> %vd
+}
+
+define <vscale x 1 x float> @vfwadd_wf_nxv1f32(<vscale x 1 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %splat to <vscale x 1 x float>
+  %vd = fadd <vscale x 1 x float> %va, %vc
+  ret <vscale x 1 x float> %vd
+}
+
+define <vscale x 1 x float> @vfwadd_wf_nxv1f32_2(<vscale x 1 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv1f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv1f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 1 x float> %head, <vscale x 1 x float> poison, <vscale x 1 x i32> zeroinitializer
+  %vd = fadd <vscale x 1 x float> %va, %splat
+  ret <vscale x 1 x float> %vd
+}
+
+define <vscale x 2 x float> @vfwadd_vv_nxv2f32(<vscale x 2 x bfloat> %va, <vscale x 2 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_vv_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; 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_vv_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %vd = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
+  %ve = fadd <vscale x 2 x float> %vc, %vd
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwadd_vf_nxv2f32(<vscale x 2 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %vd = fpext <vscale x 2 x bfloat> %splat to <vscale x 2 x float>
+  %ve = fadd <vscale x 2 x float> %vc, %vd
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwadd_vf_nxv2f32_2(<vscale x 2 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv2f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv2f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %ve = fadd <vscale x 2 x float> %vc, %splat
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwadd_wv_nxv2f32(<vscale x 2 x float> %va, <vscale x 2 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_wv_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wv_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
+  %vd = fadd <vscale x 2 x float> %va, %vc
+  ret <vscale x 2 x float> %vd
+}
+
+define <vscale x 2 x float> @vfwadd_wf_nxv2f32(<vscale x 2 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %splat to <vscale x 2 x float>
+  %vd = fadd <vscale x 2 x float> %va, %vc
+  ret <vscale x 2 x float> %vd
+}
+
+define <vscale x 2 x float> @vfwadd_wf_nxv2f32_2(<vscale x 2 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv2f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv2f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
+  %vd = fadd <vscale x 2 x float> %va, %splat
+  ret <vscale x 2 x float> %vd
+}
+
+define <vscale x 4 x float> @vfwadd_vv_nxv4f32(<vscale x 4 x bfloat> %va, <vscale x 4 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_vv_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v10, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vv_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v10, v12
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %vd = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
+  %ve = fadd <vscale x 4 x float> %vc, %vd
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwadd_vf_nxv4f32(<vscale x 4 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v10, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v10, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %vd = fpext <vscale x 4 x bfloat> %splat to <vscale x 4 x float>
+  %ve = fadd <vscale x 4 x float> %vc, %vd
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwadd_vf_nxv4f32_2(<vscale x 4 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv4f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v10, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv4f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v10, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 4 x float> %head, <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %ve = fadd <vscale x 4 x float> %vc, %splat
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwadd_wv_nxv4f32(<vscale x 4 x float> %va, <vscale x 4 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_wv_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v10
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wv_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v10
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
+  %vd = fadd <vscale x 4 x float> %va, %vc
+  ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 4 x float> @vfwadd_wf_nxv4f32(<vscale x 4 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %splat to <vscale x 4 x float>
+  %vd = fadd <vscale x 4 x float> %va, %vc
+  ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 4 x float> @vfwadd_wf_nxv4f32_2(<vscale x 4 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv4f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv4f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 4 x float> %head, <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
+  %vd = fadd <vscale x 4 x float> %va, %splat
+  ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 8 x float> @vfwadd_vv_nxv8f32(<vscale x 8 x bfloat> %va, <vscale x 8 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_vv_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v10
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v12, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vv_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v10
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v12, v16
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %vd = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
+  %ve = fadd <vscale x 8 x float> %vc, %vd
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwadd_vf_nxv8f32(<vscale x 8 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v12, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v12, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %vd = fpext <vscale x 8 x bfloat> %splat to <vscale x 8 x float>
+  %ve = fadd <vscale x 8 x float> %vc, %vd
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwadd_vf_nxv8f32_2(<vscale x 8 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_vf_nxv8f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v12, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vf_nxv8f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v12, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 8 x float> %head, <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %ve = fadd <vscale x 8 x float> %vc, %splat
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwadd_wv_nxv8f32(<vscale x 8 x float> %va, <vscale x 8 x bfloat> %vb) {
+; ZVFH-LABEL: vfwadd_wv_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v12
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wv_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v8, v16
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
+  %vd = fadd <vscale x 8 x float> %va, %vc
+  ret <vscale x 8 x float> %vd
+}
+
+define <vscale x 8 x float> @vfwadd_wf_nxv8f32(<vscale x 8 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %splat to <vscale x 8 x float>
+  %vd = fadd <vscale x 8 x float> %va, %vc
+  ret <vscale x 8 x float> %vd
+}
+
+define <vscale x 8 x float> @vfwadd_wf_nxv8f32_2(<vscale x 8 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwadd_wf_nxv8f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_wf_nxv8f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 8 x float> %head, <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer
+  %vd = fadd <vscale x 8 x float> %va, %splat
+  ret <vscale x 8 x float> %vd
+}
+
+define <vscale x 1 x float> @vfwadd_vv_nxv1f32_same_op(<vscale x 1 x bfloat> %va) {
+; ZVFH-LABEL: vfwadd_vv_nxv1f32_same_op:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfadd.vv v8, v9, v9
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwadd_vv_nxv1f32_same_op:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfadd.vv v8, v9, v9
+; ZVFBFA-NEXT:    ret
+  %vb = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vc = fadd <vscale x 1 x float> %vb, %vb
+  ret <vscale x 1 x float> %vc
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
index 41f2c26c15808..e708ab44d8a48 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
@@ -1,8 +1,12 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v -target-abi=ilp32d \
-; RUN:     -verify-machineinstrs < %s | FileCheck %s
-; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v -target-abi=lp64d \
-; RUN:     -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v,+zvfbfmin -target-abi=ilp32d \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v,+zvfbfmin -target-abi=lp64d \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v,+experimental-zvfbfa \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v,+experimental-zvfbfa \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
 
 define <vscale x 1 x double> @vfwmul_vv_nxv1f64(<vscale x 1 x float> %va, <vscale x 1 x float> %vb) {
 ; CHECK-LABEL: vfwmul_vv_nxv1f64:
@@ -190,3 +194,344 @@ define <vscale x 1 x double> @vfwmul_vv_nxv1f64_same_op(<vscale x 1 x float> %va
   %vc = fmul <vscale x 1 x double> %vb, %vb
   ret <vscale x 1 x double> %vc
 }
+
+define <vscale x 1 x float> @vfwmul_vv_nxv1f32(<vscale x 1 x bfloat> %va, <vscale x 1 x bfloat> %vb) {
+; ZVFH-LABEL: vfwmul_vv_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; 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:    vfmul.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vv_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vd = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
+  %ve = fmul <vscale x 1 x float> %vc, %vd
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwmul_vf_nxv1f32(<vscale x 1 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vd = fpext <vscale x 1 x bfloat> %splat to <vscale x 1 x float>
+  %ve = fmul <vscale x 1 x float> %vc, %vd
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwmul_vf_nxv1f32_2(<vscale x 1 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv1f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv1f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 1 x float> %head, <vscale x 1 x float> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %ve = fmul <vscale x 1 x float> %vc, %splat
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwmul_vv_nxv2f32(<vscale x 2 x bfloat> %va, <vscale x 2 x bfloat> %vb) {
+; ZVFH-LABEL: vfwmul_vv_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; 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:    vfmul.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vv_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %vd = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
+  %ve = fmul <vscale x 2 x float> %vc, %vd
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwmul_vf_nxv2f32(<vscale x 2 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %vd = fpext <vscale x 2 x bfloat> %splat to <vscale x 2 x float>
+  %ve = fmul <vscale x 2 x float> %vc, %vd
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwmul_vf_nxv2f32_2(<vscale x 2 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv2f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv2f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %ve = fmul <vscale x 2 x float> %vc, %splat
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwmul_vv_nxv4f32(<vscale x 4 x bfloat> %va, <vscale x 4 x bfloat> %vb) {
+; ZVFH-LABEL: vfwmul_vv_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfmul.vv v8, v10, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vv_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v10, v12
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %vd = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
+  %ve = fmul <vscale x 4 x float> %vc, %vd
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwmul_vf_nxv4f32(<vscale x 4 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v10, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v10, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %vd = fpext <vscale x 4 x bfloat> %splat to <vscale x 4 x float>
+  %ve = fmul <vscale x 4 x float> %vc, %vd
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwmul_vf_nxv4f32_2(<vscale x 4 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv4f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v10, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv4f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v10, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 4 x float> %head, <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %ve = fmul <vscale x 4 x float> %vc, %splat
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwmul_vv_nxv8f32(<vscale x 8 x bfloat> %va, <vscale x 8 x bfloat> %vb) {
+; ZVFH-LABEL: vfwmul_vv_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v10
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfmul.vv v8, v12, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vv_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v10
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v12, v16
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %vd = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
+  %ve = fmul <vscale x 8 x float> %vc, %vd
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwmul_vf_nxv8f32(<vscale x 8 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v12, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v12, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %vd = fpext <vscale x 8 x bfloat> %splat to <vscale x 8 x float>
+  %ve = fmul <vscale x 8 x float> %vc, %vd
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwmul_vf_nxv8f32_2(<vscale x 8 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwmul_vf_nxv8f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfmul.vf v8, v12, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vf_nxv8f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfmul.vf v8, v12, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 8 x float> %head, <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %ve = fmul <vscale x 8 x float> %vc, %splat
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwmul_vv_nxv1f32_same_op(<vscale x 1 x bfloat> %va) {
+; ZVFH-LABEL: vfwmul_vv_nxv1f32_same_op:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfmul.vv v8, v9, v9
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwmul_vv_nxv1f32_same_op:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfmul.vv v8, v9, v9
+; ZVFBFA-NEXT:    ret
+  %vb = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vc = fmul <vscale x 1 x float> %vb, %vb
+  ret <vscale x 1 x float> %vc
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
index 9393cbd4ccafc..d251315064efd 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
@@ -1,8 +1,12 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v -target-abi=ilp32d \
-; RUN:     -verify-machineinstrs < %s | FileCheck %s
-; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v -target-abi=lp64d \
-; RUN:     -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v,+zvfbfmin -target-abi=ilp32d \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v,+zvfbfmin -target-abi=lp64d \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
+; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v,+experimental-zvfbfa \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v,+experimental-zvfbfa \
+; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
 
 define <vscale x 1 x double> @vfwsub_vv_nxv1f64(<vscale x 1 x float> %va, <vscale x 1 x float> %vb) {
 ; CHECK-LABEL: vfwsub_vv_nxv1f64:
@@ -338,3 +342,612 @@ define <vscale x 1 x double> @vfwsub_vv_nxv1f64_same_op(<vscale x 1 x float> %va
   %vc = fsub <vscale x 1 x double> %vb, %vb
   ret <vscale x 1 x double> %vc
 }
+
+define <vscale x 1 x float> @vfwsub_vv_nxv1f32(<vscale x 1 x bfloat> %va, <vscale x 1 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_vv_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; 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:    vfsub.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vv_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vd = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
+  %ve = fsub <vscale x 1 x float> %vc, %vd
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwsub_vf_nxv1f32(<vscale x 1 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vd = fpext <vscale x 1 x bfloat> %splat to <vscale x 1 x float>
+  %ve = fsub <vscale x 1 x float> %vc, %vd
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwsub_vf_nxv1f32_2(<vscale x 1 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv1f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv1f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 1 x float> %head, <vscale x 1 x float> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %ve = fsub <vscale x 1 x float> %vc, %splat
+  ret <vscale x 1 x float> %ve
+}
+
+define <vscale x 1 x float> @vfwsub_wv_nxv1f32(<vscale x 1 x float> %va, <vscale x 1 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_wv_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
+  %vd = fsub <vscale x 1 x float> %va, %vc
+  ret <vscale x 1 x float> %vd
+}
+
+define <vscale x 1 x float> @vfwsub_wf_nxv1f32(<vscale x 1 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv1f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv1f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
+  %vc = fpext <vscale x 1 x bfloat> %splat to <vscale x 1 x float>
+  %vd = fsub <vscale x 1 x float> %va, %vc
+  ret <vscale x 1 x float> %vd
+}
+
+define <vscale x 1 x float> @vfwsub_wf_nxv1f32_2(<vscale x 1 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv1f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv1f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 1 x float> %head, <vscale x 1 x float> poison, <vscale x 1 x i32> zeroinitializer
+  %vd = fsub <vscale x 1 x float> %va, %splat
+  ret <vscale x 1 x float> %vd
+}
+
+define <vscale x 2 x float> @vfwsub_vv_nxv2f32(<vscale x 2 x bfloat> %va, <vscale x 2 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_vv_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; 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:    vfsub.vv v8, v10, v8
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vv_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %vd = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
+  %ve = fsub <vscale x 2 x float> %vc, %vd
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwsub_vf_nxv2f32(<vscale x 2 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %vd = fpext <vscale x 2 x bfloat> %splat to <vscale x 2 x float>
+  %ve = fsub <vscale x 2 x float> %vc, %vd
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwsub_vf_nxv2f32_2(<vscale x 2 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv2f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv2f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
+  %ve = fsub <vscale x 2 x float> %vc, %splat
+  ret <vscale x 2 x float> %ve
+}
+
+define <vscale x 2 x float> @vfwsub_wv_nxv2f32(<vscale x 2 x float> %va, <vscale x 2 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_wv_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v10
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
+  %vd = fsub <vscale x 2 x float> %va, %vc
+  ret <vscale x 2 x float> %vd
+}
+
+define <vscale x 2 x float> @vfwsub_wf_nxv2f32(<vscale x 2 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv2f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv2f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
+  %vc = fpext <vscale x 2 x bfloat> %splat to <vscale x 2 x float>
+  %vd = fsub <vscale x 2 x float> %va, %vc
+  ret <vscale x 2 x float> %vd
+}
+
+define <vscale x 2 x float> @vfwsub_wf_nxv2f32_2(<vscale x 2 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv2f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv2f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
+  %vd = fsub <vscale x 2 x float> %va, %splat
+  ret <vscale x 2 x float> %vd
+}
+
+define <vscale x 4 x float> @vfwsub_vv_nxv4f32(<vscale x 4 x bfloat> %va, <vscale x 4 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_vv_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v9
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v10, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vv_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v9
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v10, v12
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %vd = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
+  %ve = fsub <vscale x 4 x float> %vc, %vd
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwsub_vf_nxv4f32(<vscale x 4 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v10, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v10, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %vd = fpext <vscale x 4 x bfloat> %splat to <vscale x 4 x float>
+  %ve = fsub <vscale x 4 x float> %vc, %vd
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwsub_vf_nxv4f32_2(<vscale x 4 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv4f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v10, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v10, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv4f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v10, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 4 x float> %head, <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
+  %ve = fsub <vscale x 4 x float> %vc, %splat
+  ret <vscale x 4 x float> %ve
+}
+
+define <vscale x 4 x float> @vfwsub_wv_nxv4f32(<vscale x 4 x float> %va, <vscale x 4 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_wv_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v10
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v12
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v10
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
+  %vd = fsub <vscale x 4 x float> %va, %vc
+  ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 4 x float> @vfwsub_wf_nxv4f32(<vscale x 4 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv4f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv4f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
+  %vc = fpext <vscale x 4 x bfloat> %splat to <vscale x 4 x float>
+  %vd = fsub <vscale x 4 x float> %va, %vc
+  ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 4 x float> @vfwsub_wf_nxv4f32_2(<vscale x 4 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv4f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv4f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 4 x float> %head, <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
+  %vd = fsub <vscale x 4 x float> %va, %splat
+  ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 8 x float> @vfwsub_vv_nxv8f32(<vscale x 8 x bfloat> %va, <vscale x 8 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_vv_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v10
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v12, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vv_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v10
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v12, v16
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %vd = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
+  %ve = fsub <vscale x 8 x float> %vc, %vd
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwsub_vf_nxv8f32(<vscale x 8 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    vsetvli a1, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v12, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v12, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %vd = fpext <vscale x 8 x bfloat> %splat to <vscale x 8 x float>
+  %ve = fsub <vscale x 8 x float> %vc, %vd
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwsub_vf_nxv8f32_2(<vscale x 8 x bfloat> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_vf_nxv8f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v12, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v12, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vf_nxv8f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v12, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 8 x float> %head, <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
+  %ve = fsub <vscale x 8 x float> %vc, %splat
+  ret <vscale x 8 x float> %ve
+}
+
+define <vscale x 8 x float> @vfwsub_wv_nxv8f32(<vscale x 8 x float> %va, <vscale x 8 x bfloat> %vb) {
+; ZVFH-LABEL: vfwsub_wv_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v16, v12
+; ZVFH-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v8, v16
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wv_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v12
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v8, v16
+; ZVFBFA-NEXT:    ret
+  %vc = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
+  %vd = fsub <vscale x 8 x float> %va, %vc
+  ret <vscale x 8 x float> %vd
+}
+
+define <vscale x 8 x float> @vfwsub_wf_nxv8f32(<vscale x 8 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv8f32:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv8f32:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
+  %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
+  %vc = fpext <vscale x 8 x bfloat> %splat to <vscale x 8 x float>
+  %vd = fsub <vscale x 8 x float> %va, %vc
+  ret <vscale x 8 x float> %vd
+}
+
+define <vscale x 8 x float> @vfwsub_wf_nxv8f32_2(<vscale x 8 x float> %va, bfloat %b) {
+; ZVFH-LABEL: vfwsub_wf_nxv8f32_2:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    fmv.x.w a0, fa0
+; ZVFH-NEXT:    slli a0, a0, 16
+; ZVFH-NEXT:    fmv.w.x fa5, a0
+; ZVFH-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFH-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_wf_nxv8f32_2:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
+; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
+; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    ret
+  %fpext = fpext bfloat %b to float
+  %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
+  %splat = shufflevector <vscale x 8 x float> %head, <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer
+  %vd = fsub <vscale x 8 x float> %va, %splat
+  ret <vscale x 8 x float> %vd
+}
+
+define <vscale x 1 x float> @vfwsub_vv_nxv1f32_same_op(<vscale x 1 x bfloat> %va) {
+; ZVFH-LABEL: vfwsub_vv_nxv1f32_same_op:
+; ZVFH:       # %bb.0:
+; ZVFH-NEXT:    vsetvli a0, zero, e16, mf4, ta, ma
+; ZVFH-NEXT:    vfwcvtbf16.f.f.v v9, v8
+; ZVFH-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFH-NEXT:    vfsub.vv v8, v9, v9
+; ZVFH-NEXT:    ret
+;
+; ZVFBFA-LABEL: vfwsub_vv_nxv1f32_same_op:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT:    vfsub.vv v8, v9, v9
+; ZVFBFA-NEXT:    ret
+  %vb = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
+  %vc = fsub <vscale x 1 x float> %vb, %vb
+  ret <vscale x 1 x float> %vc
+}

>From 25f1afdfd1ed71ae2faca108b5f4155e45868beb Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Thu, 16 Apr 2026 16:04:59 +0800
Subject: [PATCH 2/2] [RISCV][llvm] Support widening fadd, fsub and fmul
 codegen for zvfbfa

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |   7 +-
 .../Target/RISCV/RISCVInstrInfoVSDPatterns.td |  18 +--
 .../Target/RISCV/RISCVInstrInfoVVLPatterns.td |  16 ++-
 .../CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll | 102 ++++---------
 .../CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll | 108 ++++----------
 .../CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll |  96 ++++---------
 llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll  | 135 +++++++-----------
 llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll  |  79 ++++------
 llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll  | 135 +++++++-----------
 9 files changed, 231 insertions(+), 465 deletions(-)

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 ebdb4880a8ab7..e1f156f99c1d5 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwadd.ll
@@ -694,12 +694,9 @@ define <2 x float> @vfwadd_v2bf16(ptr %x, ptr %y) {
 ; ZVFBFA-LABEL: vfwadd_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vle16.v v9, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; 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
@@ -724,12 +721,9 @@ define <4 x float> @vfwadd_v4bf16(ptr %x, ptr %y) {
 ; ZVFBFA-LABEL: vfwadd_v4bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vle16.v v9, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; 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
@@ -755,11 +749,8 @@ define <8 x float> @vfwadd_v8bf16(ptr %x, ptr %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v10, (a0)
-; ZVFBFA-NEXT:    vle16.v v12, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; 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
@@ -785,11 +776,8 @@ define <16 x float> @vfwadd_v16bf16(ptr %x, ptr %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v12, (a0)
-; ZVFBFA-NEXT:    vle16.v v16, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; 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
@@ -817,11 +805,8 @@ define <32 x float> @vfwadd_v32bf16(ptr %x, ptr %y) {
 ; ZVFBFA-NEXT:    li a2, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a2, e16alt, m4, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vle16.v v24, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v16
+; 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
@@ -883,27 +868,18 @@ define <64 x float> @vfwadd_v64bf16(ptr %x, ptr %y) {
 ; ZVFBFA-NEXT:    li a2, 64
 ; ZVFBFA-NEXT:    vsetvli zero, a2, e16, m8, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vle16.v v8, (a1)
+; ZVFBFA-NEXT:    vle16.v v24, (a1)
 ; ZVFBFA-NEXT:    li a0, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
-; ZVFBFA-NEXT:    vslidedown.vx v24, v16, a0
-; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v16
+; ZVFBFA-NEXT:    vslidedown.vx v8, v16, a0
 ; ZVFBFA-NEXT:    addi a1, sp, 16
-; ZVFBFA-NEXT:    vs8r.v v0, (a1) # vscale x 64-byte Folded Spill
-; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m8, ta, ma
-; ZVFBFA-NEXT:    vslidedown.vx v16, v8, a0
+; 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:    vfwcvt.f.f.v v0, v8
-; ZVFBFA-NEXT:    vmv4r.v v8, v24
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v24, v8
-; ZVFBFA-NEXT:    vmv4r.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v8
+; ZVFBFA-NEXT:    vfwadd.vv v8, v16, v24
 ; ZVFBFA-NEXT:    addi a0, sp, 16
-; ZVFBFA-NEXT:    vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v0
-; ZVFBFA-NEXT:    vfadd.vv v16, v24, v16
+; 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
@@ -935,12 +911,8 @@ define <2 x float> @vfwadd_vf_v2bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwadd_vf_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; 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
@@ -967,12 +939,8 @@ define <4 x float> @vfwadd_vf_v4bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwadd_vf_v4bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vfwadd.vf v8, v9, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <4 x bfloat>, ptr %x
   %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
@@ -1000,11 +968,7 @@ define <8 x float> @vfwadd_vf_v8bf16(ptr %x, bfloat %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v10, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    vfwadd.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <8 x bfloat>, ptr %x
   %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
@@ -1032,11 +996,7 @@ define <16 x float> @vfwadd_vf_v16bf16(ptr %x, bfloat %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v12, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; ZVFBFA-NEXT:    vfwadd.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <16 x bfloat>, ptr %x
   %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
@@ -1066,11 +1026,7 @@ define <32 x float> @vfwadd_vf_v32bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-NEXT:    li a1, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a1, e16alt, m4, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v24, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v16
+; ZVFBFA-NEXT:    vfwadd.vf v8, v16, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <32 x bfloat>, ptr %x
   %b = insertelement <32 x bfloat> poison, bfloat %y, i32 0
@@ -1349,10 +1305,8 @@ define <2 x float> @vfwadd_vf2_v2bf16(<2 x bfloat> %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwadd_vf2_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwadd.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %a = fpext <2 x bfloat> %x to <2 x float>
   %b = fpext bfloat %y to float
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll
index a6cb68eedaece..0f649870f76c4 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwmul.ll
@@ -466,12 +466,9 @@ define <2 x float> @vfwmul_v2bf16(ptr %x, ptr %y) {
 ; ZVFBFA-LABEL: vfwmul_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vle16.v v9, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vle16.v v10, (a1)
+; ZVFBFA-NEXT:    vfwmul.vv v8, v9, v10
 ; ZVFBFA-NEXT:    ret
   %a = load <2 x bfloat>, ptr %x
   %b = load <2 x bfloat>, ptr %y
@@ -496,12 +493,9 @@ define <4 x float> @vfwmul_v4bf16(ptr %x, ptr %y) {
 ; ZVFBFA-LABEL: vfwmul_v4bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vle16.v v9, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vle16.v v10, (a1)
+; ZVFBFA-NEXT:    vfwmul.vv v8, v9, v10
 ; ZVFBFA-NEXT:    ret
   %a = load <4 x bfloat>, ptr %x
   %b = load <4 x bfloat>, ptr %y
@@ -527,11 +521,8 @@ define <8 x float> @vfwmul_v8bf16(ptr %x, ptr %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v10, (a0)
-; ZVFBFA-NEXT:    vle16.v v12, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v8, v10
+; ZVFBFA-NEXT:    vle16.v v11, (a1)
+; ZVFBFA-NEXT:    vfwmul.vv v8, v10, v11
 ; ZVFBFA-NEXT:    ret
   %a = load <8 x bfloat>, ptr %x
   %b = load <8 x bfloat>, ptr %y
@@ -557,11 +548,8 @@ define <16 x float> @vfwmul_v16bf16(ptr %x, ptr %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v12, (a0)
-; ZVFBFA-NEXT:    vle16.v v16, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v8, v12
+; ZVFBFA-NEXT:    vle16.v v14, (a1)
+; ZVFBFA-NEXT:    vfwmul.vv v8, v12, v14
 ; ZVFBFA-NEXT:    ret
   %a = load <16 x bfloat>, ptr %x
   %b = load <16 x bfloat>, ptr %y
@@ -589,11 +577,8 @@ define <32 x float> @vfwmul_v32bf16(ptr %x, ptr %y) {
 ; ZVFBFA-NEXT:    li a2, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a2, e16alt, m4, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vle16.v v24, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v8, v16
+; ZVFBFA-NEXT:    vle16.v v20, (a1)
+; ZVFBFA-NEXT:    vfwmul.vv v8, v16, v20
 ; ZVFBFA-NEXT:    ret
   %a = load <32 x bfloat>, ptr %x
   %b = load <32 x bfloat>, ptr %y
@@ -655,27 +640,18 @@ define <64 x float> @vfwmul_v64bf16(ptr %x, ptr %y) {
 ; ZVFBFA-NEXT:    li a2, 64
 ; ZVFBFA-NEXT:    vsetvli zero, a2, e16, m8, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vle16.v v8, (a1)
+; ZVFBFA-NEXT:    vle16.v v24, (a1)
 ; ZVFBFA-NEXT:    li a0, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
-; ZVFBFA-NEXT:    vslidedown.vx v24, v16, a0
-; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v16
+; ZVFBFA-NEXT:    vslidedown.vx v8, v16, a0
 ; ZVFBFA-NEXT:    addi a1, sp, 16
-; ZVFBFA-NEXT:    vs8r.v v0, (a1) # vscale x 64-byte Folded Spill
-; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m8, ta, ma
-; ZVFBFA-NEXT:    vslidedown.vx v16, v8, a0
+; 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:    vfwcvt.f.f.v v0, v8
-; ZVFBFA-NEXT:    vmv4r.v v8, v24
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v24, v8
-; ZVFBFA-NEXT:    vmv4r.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v8
+; ZVFBFA-NEXT:    vfwmul.vv v8, v16, v24
 ; ZVFBFA-NEXT:    addi a0, sp, 16
-; ZVFBFA-NEXT:    vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v8, v0
-; ZVFBFA-NEXT:    vfmul.vv v16, v24, v16
+; ZVFBFA-NEXT:    vl8r.v v24, (a0) # vscale x 64-byte Folded Reload
+; ZVFBFA-NEXT:    vfwmul.vv v16, v24, v0
 ; ZVFBFA-NEXT:    csrr a0, vlenb
 ; ZVFBFA-NEXT:    slli a0, a0, 3
 ; ZVFBFA-NEXT:    add sp, sp, a0
@@ -707,12 +683,8 @@ define <2 x float> @vfwmul_vf_v2bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwmul_vf_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vfwmul.vf v8, v9, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <2 x bfloat>, ptr %x
   %b = insertelement <2 x bfloat> poison, bfloat %y, i32 0
@@ -739,12 +711,8 @@ define <4 x float> @vfwmul_vf_v4bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwmul_vf_v4bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vfwmul.vf v8, v9, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <4 x bfloat>, ptr %x
   %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
@@ -772,11 +740,7 @@ define <8 x float> @vfwmul_vf_v8bf16(ptr %x, bfloat %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v10, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v8, v10
+; ZVFBFA-NEXT:    vfwmul.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <8 x bfloat>, ptr %x
   %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
@@ -804,11 +768,7 @@ define <16 x float> @vfwmul_vf_v16bf16(ptr %x, bfloat %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v12, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v8, v12
+; ZVFBFA-NEXT:    vfwmul.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <16 x bfloat>, ptr %x
   %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
@@ -838,11 +798,7 @@ define <32 x float> @vfwmul_vf_v32bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-NEXT:    li a1, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a1, e16alt, m4, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v24, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v8, v16
+; ZVFBFA-NEXT:    vfwmul.vf v8, v16, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <32 x bfloat>, ptr %x
   %b = insertelement <32 x bfloat> poison, bfloat %y, i32 0
@@ -866,10 +822,8 @@ define <2 x float> @vfwmul_squared_v2bf16_v2f32(ptr %x) {
 ; ZVFBFA-LABEL: vfwmul_squared_v2bf16_v2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v9, v9
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vfwmul.vv v8, v9, v9
 ; ZVFBFA-NEXT:    ret
   %a = load <2 x bfloat>, ptr %x
   %b = fpext <2 x bfloat> %a to <2 x float>
@@ -892,10 +846,8 @@ define <2 x float> @vfwmul_vf2_v2bf16(<2 x bfloat> %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwmul_vf2_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwmul.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %a = fpext <2 x bfloat> %x to <2 x float>
   %b = fpext bfloat %y to float
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll
index 9f8cf86bd6b6a..ec4d7dc315b18 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfwsub.ll
@@ -666,12 +666,9 @@ define <2 x float> @vfwsub_v2bf16(ptr %x, ptr %y) {
 ; ZVFBFA-LABEL: vfwsub_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vle16.v v9, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vle16.v v10, (a1)
+; ZVFBFA-NEXT:    vfwsub.vv v8, v9, v10
 ; ZVFBFA-NEXT:    ret
   %a = load <2 x bfloat>, ptr %x
   %b = load <2 x bfloat>, ptr %y
@@ -696,12 +693,9 @@ define <4 x float> @vfwsub_v4bf16(ptr %x, ptr %y) {
 ; ZVFBFA-LABEL: vfwsub_v4bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vle16.v v9, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vle16.v v10, (a1)
+; ZVFBFA-NEXT:    vfwsub.vv v8, v9, v10
 ; ZVFBFA-NEXT:    ret
   %a = load <4 x bfloat>, ptr %x
   %b = load <4 x bfloat>, ptr %y
@@ -727,11 +721,8 @@ define <8 x float> @vfwsub_v8bf16(ptr %x, ptr %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v10, (a0)
-; ZVFBFA-NEXT:    vle16.v v12, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    vle16.v v11, (a1)
+; ZVFBFA-NEXT:    vfwsub.vv v8, v10, v11
 ; ZVFBFA-NEXT:    ret
   %a = load <8 x bfloat>, ptr %x
   %b = load <8 x bfloat>, ptr %y
@@ -757,11 +748,8 @@ define <16 x float> @vfwsub_v16bf16(ptr %x, ptr %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v12, (a0)
-; ZVFBFA-NEXT:    vle16.v v16, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; ZVFBFA-NEXT:    vle16.v v14, (a1)
+; ZVFBFA-NEXT:    vfwsub.vv v8, v12, v14
 ; ZVFBFA-NEXT:    ret
   %a = load <16 x bfloat>, ptr %x
   %b = load <16 x bfloat>, ptr %y
@@ -789,11 +777,8 @@ define <32 x float> @vfwsub_v32bf16(ptr %x, ptr %y) {
 ; ZVFBFA-NEXT:    li a2, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a2, e16alt, m4, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vle16.v v24, (a1)
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v16
+; ZVFBFA-NEXT:    vle16.v v20, (a1)
+; ZVFBFA-NEXT:    vfwsub.vv v8, v16, v20
 ; ZVFBFA-NEXT:    ret
   %a = load <32 x bfloat>, ptr %x
   %b = load <32 x bfloat>, ptr %y
@@ -855,27 +840,18 @@ define <64 x float> @vfwsub_v64bf16(ptr %x, ptr %y) {
 ; ZVFBFA-NEXT:    li a2, 64
 ; ZVFBFA-NEXT:    vsetvli zero, a2, e16, m8, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vle16.v v8, (a1)
+; ZVFBFA-NEXT:    vle16.v v24, (a1)
 ; ZVFBFA-NEXT:    li a0, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a0, e16, m8, ta, ma
-; ZVFBFA-NEXT:    vslidedown.vx v24, v16, a0
-; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v0, v16
+; ZVFBFA-NEXT:    vslidedown.vx v8, v16, a0
 ; ZVFBFA-NEXT:    addi a1, sp, 16
-; ZVFBFA-NEXT:    vs8r.v v0, (a1) # vscale x 64-byte Folded Spill
-; ZVFBFA-NEXT:    vsetvli zero, a0, e16alt, m8, ta, ma
-; ZVFBFA-NEXT:    vslidedown.vx v16, v8, a0
+; 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:    vfwcvt.f.f.v v0, v8
-; ZVFBFA-NEXT:    vmv4r.v v8, v24
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v24, v8
-; ZVFBFA-NEXT:    vmv4r.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v8
+; ZVFBFA-NEXT:    vfwsub.vv v8, v16, v24
 ; ZVFBFA-NEXT:    addi a0, sp, 16
-; ZVFBFA-NEXT:    vl8r.v v8, (a0) # vscale x 64-byte Folded Reload
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v0
-; ZVFBFA-NEXT:    vfsub.vv v16, v24, v16
+; ZVFBFA-NEXT:    vl8r.v v24, (a0) # vscale x 64-byte Folded Reload
+; ZVFBFA-NEXT:    vfwsub.vv v16, v24, v0
 ; ZVFBFA-NEXT:    csrr a0, vlenb
 ; ZVFBFA-NEXT:    slli a0, a0, 3
 ; ZVFBFA-NEXT:    add sp, sp, a0
@@ -907,12 +883,8 @@ define <2 x float> @vfwsub_vf_v2bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwsub_vf_v2bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vfwsub.vf v8, v9, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <2 x bfloat>, ptr %x
   %b = insertelement <2 x bfloat> poison, bfloat %y, i32 0
@@ -939,12 +911,8 @@ define <4 x float> @vfwsub_vf_v4bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-LABEL: vfwsub_vf_v4bf16:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vle16.v v8, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v9, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    vle16.v v9, (a0)
+; ZVFBFA-NEXT:    vfwsub.vf v8, v9, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <4 x bfloat>, ptr %x
   %b = insertelement <4 x bfloat> poison, bfloat %y, i32 0
@@ -972,11 +940,7 @@ define <8 x float> @vfwsub_vf_v8bf16(ptr %x, bfloat %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 8, e16alt, m1, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v10, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v12, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v10
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    vfwsub.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <8 x bfloat>, ptr %x
   %b = insertelement <8 x bfloat> poison, bfloat %y, i32 0
@@ -1004,11 +968,7 @@ define <16 x float> @vfwsub_vf_v16bf16(ptr %x, bfloat %y) {
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetivli zero, 16, e16alt, m2, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v12, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v16, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v12
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v16
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; ZVFBFA-NEXT:    vfwsub.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <16 x bfloat>, ptr %x
   %b = insertelement <16 x bfloat> poison, bfloat %y, i32 0
@@ -1038,11 +998,7 @@ define <32 x float> @vfwsub_vf_v32bf16(ptr %x, bfloat %y) {
 ; ZVFBFA-NEXT:    li a1, 32
 ; ZVFBFA-NEXT:    vsetvli zero, a1, e16alt, m4, ta, ma
 ; ZVFBFA-NEXT:    vle16.v v16, (a0)
-; ZVFBFA-NEXT:    vfmv.v.f v24, fa0
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v16
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v24
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m8, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v16
+; ZVFBFA-NEXT:    vfwsub.vf v8, v16, fa0
 ; ZVFBFA-NEXT:    ret
   %a = load <32 x bfloat>, ptr %x
   %b = insertelement <32 x bfloat> poison, bfloat %y, i32 0
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
index 73c1b57a30971..e2e45a0bf5487 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
@@ -356,10 +356,8 @@ define <vscale x 1 x float> @vfwadd_vv_nxv1f32(<vscale x 1 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwadd_vv_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; ZVFBFA-NEXT:    vfwadd.vv v10, v8, v9
+; ZVFBFA-NEXT:    vmv1r.v v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
   %vd = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
@@ -382,10 +380,8 @@ define <vscale x 1 x float> @vfwadd_vf_nxv1f32(<vscale x 1 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwadd_vf_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwadd.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
@@ -409,11 +405,9 @@ define <vscale x 1 x float> @vfwadd_vf_nxv1f32_2(<vscale x 1 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwadd_vf_nxv1f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwadd.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
@@ -435,9 +429,7 @@ define <vscale x 1 x float> @vfwadd_wv_nxv1f32(<vscale x 1 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwadd_wv_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    vfwadd.wv v8, v8, v9
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
   %vd = fadd <vscale x 1 x float> %va, %vc
@@ -456,9 +448,8 @@ define <vscale x 1 x float> @vfwadd_wf_nxv1f32(<vscale x 1 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv1f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
@@ -479,9 +470,8 @@ define <vscale x 1 x float> @vfwadd_wf_nxv1f32_2(<vscale x 1 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv1f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
@@ -503,10 +493,8 @@ define <vscale x 2 x float> @vfwadd_vv_nxv2f32(<vscale x 2 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwadd_vv_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v10, v8
+; ZVFBFA-NEXT:    vfwadd.vv v10, v8, v9
+; ZVFBFA-NEXT:    vmv1r.v v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
   %vd = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
@@ -529,10 +517,8 @@ define <vscale x 2 x float> @vfwadd_vf_nxv2f32(<vscale x 2 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwadd_vf_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwadd.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
@@ -556,11 +542,9 @@ define <vscale x 2 x float> @vfwadd_vf_nxv2f32_2(<vscale x 2 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwadd_vf_nxv2f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwadd.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
@@ -582,9 +566,7 @@ define <vscale x 2 x float> @vfwadd_wv_nxv2f32(<vscale x 2 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwadd_wv_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v10
+; ZVFBFA-NEXT:    vfwadd.wv v8, v8, v9
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
   %vd = fadd <vscale x 2 x float> %va, %vc
@@ -603,9 +585,8 @@ define <vscale x 2 x float> @vfwadd_wf_nxv2f32(<vscale x 2 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv2f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
@@ -626,9 +607,8 @@ define <vscale x 2 x float> @vfwadd_wf_nxv2f32_2(<vscale x 2 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv2f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
@@ -650,10 +630,9 @@ define <vscale x 4 x float> @vfwadd_vv_nxv4f32(<vscale x 4 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwadd_vv_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v10, v12
+; ZVFBFA-NEXT:    vmv1r.v v10, v9
+; ZVFBFA-NEXT:    vmv1r.v v11, v8
+; ZVFBFA-NEXT:    vfwadd.vv v8, v11, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
   %vd = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
@@ -676,10 +655,8 @@ define <vscale x 4 x float> @vfwadd_vf_nxv4f32(<vscale x 4 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwadd_vf_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v10, fa5
+; ZVFBFA-NEXT:    vmv1r.v v10, v8
+; ZVFBFA-NEXT:    vfwadd.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
@@ -703,11 +680,9 @@ define <vscale x 4 x float> @vfwadd_vf_nxv4f32_2(<vscale x 4 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwadd_vf_nxv4f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v10, fa5
+; ZVFBFA-NEXT:    vmv1r.v v10, v8
+; ZVFBFA-NEXT:    vfwadd.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
@@ -729,9 +704,7 @@ define <vscale x 4 x float> @vfwadd_wv_nxv4f32(<vscale x 4 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwadd_wv_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v10
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v12
+; ZVFBFA-NEXT:    vfwadd.wv v8, v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
   %vd = fadd <vscale x 4 x float> %va, %vc
@@ -750,9 +723,8 @@ define <vscale x 4 x float> @vfwadd_wf_nxv4f32(<vscale x 4 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv4f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
@@ -773,9 +745,8 @@ define <vscale x 4 x float> @vfwadd_wf_nxv4f32_2(<vscale x 4 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv4f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
@@ -797,10 +768,9 @@ define <vscale x 8 x float> @vfwadd_vv_nxv8f32(<vscale x 8 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwadd_vv_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v10
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v12, v16
+; ZVFBFA-NEXT:    vmv2r.v v12, v10
+; ZVFBFA-NEXT:    vmv2r.v v14, v8
+; ZVFBFA-NEXT:    vfwadd.vv v8, v14, v12
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
   %vd = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
@@ -823,10 +793,8 @@ define <vscale x 8 x float> @vfwadd_vf_nxv8f32(<vscale x 8 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwadd_vf_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v12, fa5
+; ZVFBFA-NEXT:    vmv2r.v v12, v8
+; ZVFBFA-NEXT:    vfwadd.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
@@ -850,11 +818,9 @@ define <vscale x 8 x float> @vfwadd_vf_nxv8f32_2(<vscale x 8 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwadd_vf_nxv8f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v12, fa5
+; ZVFBFA-NEXT:    vmv2r.v v12, v8
+; ZVFBFA-NEXT:    vfwadd.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
@@ -876,9 +842,7 @@ define <vscale x 8 x float> @vfwadd_wv_nxv8f32(<vscale x 8 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwadd_wv_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v8, v16
+; ZVFBFA-NEXT:    vfwadd.wv v8, v8, v12
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
   %vd = fadd <vscale x 8 x float> %va, %vc
@@ -897,9 +861,8 @@ define <vscale x 8 x float> @vfwadd_wf_nxv8f32(<vscale x 8 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv8f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
@@ -920,9 +883,8 @@ define <vscale x 8 x float> @vfwadd_wf_nxv8f32_2(<vscale x 8 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwadd_wf_nxv8f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfadd.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwadd.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
@@ -943,9 +905,8 @@ define <vscale x 1 x float> @vfwadd_vv_nxv1f32_same_op(<vscale x 1 x bfloat> %va
 ; ZVFBFA-LABEL: vfwadd_vv_nxv1f32_same_op:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfadd.vv v8, v9, v9
+; ZVFBFA-NEXT:    vfwadd.vv v9, v8, v8
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %vb = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
   %vc = fadd <vscale x 1 x float> %vb, %vb
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
index e708ab44d8a48..688f6e26c4291 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
@@ -208,10 +208,8 @@ define <vscale x 1 x float> @vfwmul_vv_nxv1f32(<vscale x 1 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwmul_vv_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    vfwmul.vv v10, v8, v9
+; ZVFBFA-NEXT:    vmv1r.v v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
   %vd = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
@@ -234,10 +232,8 @@ define <vscale x 1 x float> @vfwmul_vf_nxv1f32(<vscale x 1 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwmul_vf_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwmul.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
@@ -261,11 +257,9 @@ define <vscale x 1 x float> @vfwmul_vf_nxv1f32_2(<vscale x 1 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwmul_vf_nxv1f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwmul.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
@@ -288,10 +282,8 @@ define <vscale x 2 x float> @vfwmul_vv_nxv2f32(<vscale x 2 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwmul_vv_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v10, v8
+; ZVFBFA-NEXT:    vfwmul.vv v10, v8, v9
+; ZVFBFA-NEXT:    vmv1r.v v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
   %vd = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
@@ -314,10 +306,8 @@ define <vscale x 2 x float> @vfwmul_vf_nxv2f32(<vscale x 2 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwmul_vf_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwmul.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
@@ -341,11 +331,9 @@ define <vscale x 2 x float> @vfwmul_vf_nxv2f32_2(<vscale x 2 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwmul_vf_nxv2f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwmul.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
@@ -368,10 +356,9 @@ define <vscale x 4 x float> @vfwmul_vv_nxv4f32(<vscale x 4 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwmul_vv_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v10, v12
+; ZVFBFA-NEXT:    vmv1r.v v10, v9
+; ZVFBFA-NEXT:    vmv1r.v v11, v8
+; ZVFBFA-NEXT:    vfwmul.vv v8, v11, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
   %vd = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
@@ -394,10 +381,8 @@ define <vscale x 4 x float> @vfwmul_vf_nxv4f32(<vscale x 4 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwmul_vf_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v10, fa5
+; ZVFBFA-NEXT:    vmv1r.v v10, v8
+; ZVFBFA-NEXT:    vfwmul.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
@@ -421,11 +406,9 @@ define <vscale x 4 x float> @vfwmul_vf_nxv4f32_2(<vscale x 4 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwmul_vf_nxv4f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v10, fa5
+; ZVFBFA-NEXT:    vmv1r.v v10, v8
+; ZVFBFA-NEXT:    vfwmul.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
@@ -448,10 +431,9 @@ define <vscale x 8 x float> @vfwmul_vv_nxv8f32(<vscale x 8 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwmul_vv_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v10
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v12, v16
+; ZVFBFA-NEXT:    vmv2r.v v12, v10
+; ZVFBFA-NEXT:    vmv2r.v v14, v8
+; ZVFBFA-NEXT:    vfwmul.vv v8, v14, v12
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
   %vd = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
@@ -474,10 +456,8 @@ define <vscale x 8 x float> @vfwmul_vf_nxv8f32(<vscale x 8 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwmul_vf_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v12, fa5
+; ZVFBFA-NEXT:    vmv2r.v v12, v8
+; ZVFBFA-NEXT:    vfwmul.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
@@ -501,11 +481,9 @@ define <vscale x 8 x float> @vfwmul_vf_nxv8f32_2(<vscale x 8 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwmul_vf_nxv8f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfmul.vf v8, v12, fa5
+; ZVFBFA-NEXT:    vmv2r.v v12, v8
+; ZVFBFA-NEXT:    vfwmul.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
@@ -527,9 +505,8 @@ define <vscale x 1 x float> @vfwmul_vv_nxv1f32_same_op(<vscale x 1 x bfloat> %va
 ; ZVFBFA-LABEL: vfwmul_vv_nxv1f32_same_op:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfmul.vv v8, v9, v9
+; ZVFBFA-NEXT:    vfwmul.vv v9, v8, v8
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %vb = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
   %vc = fmul <vscale x 1 x float> %vb, %vb
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
index d251315064efd..28b093de3389a 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
@@ -356,10 +356,8 @@ define <vscale x 1 x float> @vfwsub_vv_nxv1f32(<vscale x 1 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwsub_vv_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    vfwsub.vv v10, v8, v9
+; ZVFBFA-NEXT:    vmv1r.v v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
   %vd = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
@@ -382,10 +380,8 @@ define <vscale x 1 x float> @vfwsub_vf_nxv1f32(<vscale x 1 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwsub_vf_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwsub.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
@@ -409,11 +405,9 @@ define <vscale x 1 x float> @vfwsub_vf_nxv1f32_2(<vscale x 1 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwsub_vf_nxv1f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwsub.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
@@ -435,9 +429,7 @@ define <vscale x 1 x float> @vfwsub_wv_nxv1f32(<vscale x 1 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwsub_wv_nxv1f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    vfwsub.wv v8, v8, v9
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 1 x bfloat> %vb to <vscale x 1 x float>
   %vd = fsub <vscale x 1 x float> %va, %vc
@@ -456,9 +448,8 @@ define <vscale x 1 x float> @vfwsub_wf_nxv1f32(<vscale x 1 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv1f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 1 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 1 x bfloat> %head, <vscale x 1 x bfloat> poison, <vscale x 1 x i32> zeroinitializer
@@ -479,9 +470,8 @@ define <vscale x 1 x float> @vfwsub_wf_nxv1f32_2(<vscale x 1 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv1f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 1 x float> poison, float %fpext, i32 0
@@ -503,10 +493,8 @@ define <vscale x 2 x float> @vfwsub_vv_nxv2f32(<vscale x 2 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwsub_vv_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v8, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v10, v8
+; ZVFBFA-NEXT:    vfwsub.vv v10, v8, v9
+; ZVFBFA-NEXT:    vmv1r.v v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 2 x bfloat> %va to <vscale x 2 x float>
   %vd = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
@@ -529,10 +517,8 @@ define <vscale x 2 x float> @vfwsub_vf_nxv2f32(<vscale x 2 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwsub_vf_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwsub.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
@@ -556,11 +542,9 @@ define <vscale x 2 x float> @vfwsub_vf_nxv2f32_2(<vscale x 2 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwsub_vf_nxv2f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v9, fa5
+; ZVFBFA-NEXT:    vfwsub.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
@@ -582,9 +566,7 @@ define <vscale x 2 x float> @vfwsub_wv_nxv2f32(<vscale x 2 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwsub_wv_nxv2f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v10
+; ZVFBFA-NEXT:    vfwsub.wv v8, v8, v9
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 2 x bfloat> %vb to <vscale x 2 x float>
   %vd = fsub <vscale x 2 x float> %va, %vc
@@ -603,9 +585,8 @@ define <vscale x 2 x float> @vfwsub_wf_nxv2f32(<vscale x 2 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv2f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 2 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 2 x bfloat> %head, <vscale x 2 x bfloat> poison, <vscale x 2 x i32> zeroinitializer
@@ -626,9 +607,8 @@ define <vscale x 2 x float> @vfwsub_wf_nxv2f32_2(<vscale x 2 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv2f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 2 x float> poison, float %fpext, i32 0
@@ -650,10 +630,9 @@ define <vscale x 4 x float> @vfwsub_vv_nxv4f32(<vscale x 4 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwsub_vv_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v9
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v10, v12
+; ZVFBFA-NEXT:    vmv1r.v v10, v9
+; ZVFBFA-NEXT:    vmv1r.v v11, v8
+; ZVFBFA-NEXT:    vfwsub.vv v8, v11, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 4 x bfloat> %va to <vscale x 4 x float>
   %vd = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
@@ -676,10 +655,8 @@ define <vscale x 4 x float> @vfwsub_vf_nxv4f32(<vscale x 4 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwsub_vf_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v10, fa5
+; ZVFBFA-NEXT:    vmv1r.v v10, v8
+; ZVFBFA-NEXT:    vfwsub.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
@@ -703,11 +680,9 @@ define <vscale x 4 x float> @vfwsub_vf_nxv4f32_2(<vscale x 4 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwsub_vf_nxv4f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v10, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v10, fa5
+; ZVFBFA-NEXT:    vmv1r.v v10, v8
+; ZVFBFA-NEXT:    vfwsub.vf v8, v10, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
@@ -729,9 +704,7 @@ define <vscale x 4 x float> @vfwsub_wv_nxv4f32(<vscale x 4 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwsub_wv_nxv4f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v10
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v12
+; ZVFBFA-NEXT:    vfwsub.wv v8, v8, v10
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 4 x bfloat> %vb to <vscale x 4 x float>
   %vd = fsub <vscale x 4 x float> %va, %vc
@@ -750,9 +723,8 @@ define <vscale x 4 x float> @vfwsub_wf_nxv4f32(<vscale x 4 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv4f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 4 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 4 x bfloat> %head, <vscale x 4 x bfloat> poison, <vscale x 4 x i32> zeroinitializer
@@ -773,9 +745,8 @@ define <vscale x 4 x float> @vfwsub_wf_nxv4f32_2(<vscale x 4 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv4f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m1, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 4 x float> poison, float %fpext, i32 0
@@ -797,10 +768,9 @@ define <vscale x 8 x float> @vfwsub_vv_nxv8f32(<vscale x 8 x bfloat> %va, <vscal
 ; ZVFBFA-LABEL: vfwsub_vv_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v10
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v12, v16
+; ZVFBFA-NEXT:    vmv2r.v v12, v10
+; ZVFBFA-NEXT:    vmv2r.v v14, v8
+; ZVFBFA-NEXT:    vfwsub.vv v8, v14, v12
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 8 x bfloat> %va to <vscale x 8 x float>
   %vd = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
@@ -823,10 +793,8 @@ define <vscale x 8 x float> @vfwsub_vf_nxv8f32(<vscale x 8 x bfloat> %va, bfloat
 ; ZVFBFA-LABEL: vfwsub_vf_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v12, fa5
+; ZVFBFA-NEXT:    vmv2r.v v12, v8
+; ZVFBFA-NEXT:    vfwsub.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
@@ -850,11 +818,9 @@ define <vscale x 8 x float> @vfwsub_vf_nxv8f32_2(<vscale x 8 x bfloat> %va, bflo
 ;
 ; ZVFBFA-LABEL: vfwsub_vf_nxv8f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v12, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v12, fa5
+; ZVFBFA-NEXT:    vmv2r.v v12, v8
+; ZVFBFA-NEXT:    vfwsub.vf v8, v12, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
@@ -876,9 +842,7 @@ define <vscale x 8 x float> @vfwsub_wv_nxv8f32(<vscale x 8 x float> %va, <vscale
 ; ZVFBFA-LABEL: vfwsub_wv_nxv8f32:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v16, v12
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v8, v16
+; ZVFBFA-NEXT:    vfwsub.wv v8, v8, v12
 ; ZVFBFA-NEXT:    ret
   %vc = fpext <vscale x 8 x bfloat> %vb to <vscale x 8 x float>
   %vd = fsub <vscale x 8 x float> %va, %vc
@@ -897,9 +861,8 @@ define <vscale x 8 x float> @vfwsub_wf_nxv8f32(<vscale x 8 x float> %va, bfloat
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv8f32:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %head = insertelement <vscale x 8 x bfloat> poison, bfloat %b, i32 0
   %splat = shufflevector <vscale x 8 x bfloat> %head, <vscale x 8 x bfloat> poison, <vscale x 8 x i32> zeroinitializer
@@ -920,9 +883,8 @@ define <vscale x 8 x float> @vfwsub_wf_nxv8f32_2(<vscale x 8 x float> %va, bfloa
 ;
 ; ZVFBFA-LABEL: vfwsub_wf_nxv8f32_2:
 ; ZVFBFA:       # %bb.0:
-; ZVFBFA-NEXT:    fcvt.s.bf16 fa5, fa0
-; ZVFBFA-NEXT:    vsetvli a0, zero, e32, m4, ta, ma
-; ZVFBFA-NEXT:    vfsub.vf v8, v8, fa5
+; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, m2, ta, ma
+; ZVFBFA-NEXT:    vfwsub.wf v8, v8, fa0
 ; ZVFBFA-NEXT:    ret
   %fpext = fpext bfloat %b to float
   %head = insertelement <vscale x 8 x float> poison, float %fpext, i32 0
@@ -943,9 +905,8 @@ define <vscale x 1 x float> @vfwsub_vv_nxv1f32_same_op(<vscale x 1 x bfloat> %va
 ; ZVFBFA-LABEL: vfwsub_vv_nxv1f32_same_op:
 ; ZVFBFA:       # %bb.0:
 ; ZVFBFA-NEXT:    vsetvli a0, zero, e16alt, mf4, ta, ma
-; ZVFBFA-NEXT:    vfwcvt.f.f.v v9, v8
-; ZVFBFA-NEXT:    vsetvli zero, zero, e32, mf2, ta, ma
-; ZVFBFA-NEXT:    vfsub.vv v8, v9, v9
+; ZVFBFA-NEXT:    vfwsub.vv v9, v8, v8
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
 ; ZVFBFA-NEXT:    ret
   %vb = fpext <vscale x 1 x bfloat> %va to <vscale x 1 x float>
   %vc = fsub <vscale x 1 x float> %vb, %vb



More information about the llvm-commits mailing list