[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