[llvm] [RISCV] Enable vfslide1up/down for bf16 shuffles with Zvfbfa. (PR #191608)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 11 18:46:42 PDT 2026


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/191608

>From 8c548a511063c8507462e9921f5529de1cd9ee95 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 10 Apr 2026 17:14:14 -0700
Subject: [PATCH 1/3] [RISCV] Add missing Zvfbfa isel patterns for
 VFSLIDE1UP/DOWN.

---
 .../Target/RISCV/RISCVInstrInfoVVLPatterns.td |  6 ++-
 .../rvv/fixed-vectors-fp-buildvec-bf16.ll     | 53 +++++++++++++++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
index 0d5ba476cc88a..2a99492bc5596 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
@@ -1943,12 +1943,14 @@ multiclass VPatSlide1VL_VX<SDNode vop, string instruction_name> {
 }
 
 multiclass VPatSlide1VL_VF<SDNode vop, string instruction_name> {
-  foreach vti = AllFloatVectors in {
+  foreach vti = AllFloatAndBF16Vectors in {
     let Predicates = GetVTypePredicates<vti>.Predicates in {
       def : Pat<(vti.Vector (vop (vti.Vector vti.RegClass:$rs3),
                                  (vti.Vector vti.RegClass:$rs1),
                                  vti.Scalar:$rs2, (vti.Mask VMV0:$vm), VLOpFrag)),
-                (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_MASK")
+                (!cast<Instruction>(instruction_name#
+                                    !if(!eq(vti.Scalar, bf16), "_ALT", "")#
+                                    "_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_MASK")
                     vti.RegClass:$rs3, vti.RegClass:$rs1, vti.Scalar:$rs2,
                     (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TU_MU)>;
     }
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp-buildvec-bf16.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp-buildvec-bf16.ll
index 9bb3f4a976ab0..85f9fc990ec2c 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp-buildvec-bf16.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp-buildvec-bf16.ll
@@ -3,6 +3,8 @@
 ; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64,RV64ZVFBFMIN,RV64-NO-ZFBFMIN
 ; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+v,+zfbfmin,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV32,RV32ZVFBFMIN,RV32-ZFBFMIN
 ; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+zfbfmin,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64,RV64ZVFBFMIN,RV64-ZFBFMIN
+; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+v,+experimental-zvfbfa -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ZVFBFA
+; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+experimental-zvfbfa -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ZVFBFA
 
 define <4 x bfloat> @splat_idx_v4bf16(<4 x bfloat> %v, i64 %idx) {
 ; RV32-NO-ZFBFMIN-LABEL: splat_idx_v4bf16:
@@ -34,6 +36,13 @@ define <4 x bfloat> @splat_idx_v4bf16(<4 x bfloat> %v, i64 %idx) {
 ; RV64-ZFBFMIN-NEXT:    vmv.x.s a0, v8
 ; RV64-ZFBFMIN-NEXT:    vmv.v.x v8, a0
 ; RV64-ZFBFMIN-NEXT:    ret
+;
+; ZVFBFA-LABEL: splat_idx_v4bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFBFA-NEXT:    vrgather.vx v9, v8, a0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
+; ZVFBFA-NEXT:    ret
   %x = extractelement <4 x bfloat> %v, i64 %idx
   %ins = insertelement <4 x bfloat> poison, bfloat %x, i32 0
   %splat = shufflevector <4 x bfloat> %ins, <4 x bfloat> poison, <4 x i32> zeroinitializer
@@ -76,6 +85,13 @@ define <2 x bfloat> @buildvec_v2bf16(bfloat %a, bfloat %b) {
 ; RV64-ZFBFMIN-NEXT:    vmv.v.x v8, a1
 ; RV64-ZFBFMIN-NEXT:    vslide1down.vx v8, v8, a0
 ; RV64-ZFBFMIN-NEXT:    ret
+;
+; ZVFBFA-LABEL: buildvec_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfmv.v.f v8, fa0
+; ZVFBFA-NEXT:    vfslide1down.vf v8, v8, fa1
+; ZVFBFA-NEXT:    ret
   %v1 = insertelement <2 x bfloat> poison, bfloat %a, i64 0
   %v2 = insertelement <2 x bfloat> %v1, bfloat %b, i64 1
   ret <2 x bfloat> %v2
@@ -88,6 +104,15 @@ define <2 x bfloat> @vid_v2bf16() {
 ; CHECK-NEXT:    vsetivli zero, 2, e32, m1, ta, ma
 ; CHECK-NEXT:    vmv.s.x v8, a0
 ; CHECK-NEXT:    ret
+;
+; ZVFBFA-LABEL: vid_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFA-NEXT:    vid.v v8
+; ZVFBFA-NEXT:    vfwcvt.f.x.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfncvt.f.f.w v8, v9
+; ZVFBFA-NEXT:    ret
   ret <2 x bfloat> <bfloat 0.0, bfloat 1.0>
 }
 
@@ -101,6 +126,16 @@ define <2 x bfloat> @vid_addend1_v2bf16() {
 ; CHECK-NEXT:    addi a0, a0, -128
 ; CHECK-NEXT:    vadd.vx v8, v8, a0
 ; CHECK-NEXT:    ret
+;
+; ZVFBFA-LABEL: vid_addend1_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFA-NEXT:    vid.v v8
+; ZVFBFA-NEXT:    vadd.vi v8, v8, 1
+; ZVFBFA-NEXT:    vfwcvt.f.x.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfncvt.f.f.w v8, v9
+; ZVFBFA-NEXT:    ret
   ret <2 x bfloat> <bfloat 1.0, bfloat 2.0>
 }
 
@@ -114,6 +149,14 @@ define <2 x bfloat> @vid_denominator2_v2bf16() {
 ; CHECK-NEXT:    addi a0, a0, -256
 ; CHECK-NEXT:    vadd.vx v8, v8, a0
 ; CHECK-NEXT:    ret
+;
+; ZVFBFA-LABEL: vid_denominator2_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    lui a0, %hi(.LCPI4_0)
+; ZVFBFA-NEXT:    addi a0, a0, %lo(.LCPI4_0)
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFA-NEXT:    vle16.v v8, (a0)
+; ZVFBFA-NEXT:    ret
   ret <2 x bfloat> <bfloat 0.5, bfloat 1.0>
 }
 
@@ -124,6 +167,16 @@ define <2 x bfloat> @vid_step2_v2bf16() {
 ; CHECK-NEXT:    vid.v v8
 ; CHECK-NEXT:    vsll.vi v8, v8, 14
 ; CHECK-NEXT:    ret
+;
+; ZVFBFA-LABEL: vid_step2_v2bf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFA-NEXT:    vid.v v8
+; ZVFBFA-NEXT:    vadd.vv v8, v8, v8
+; ZVFBFA-NEXT:    vfwcvt.f.x.v v9, v8
+; ZVFBFA-NEXT:    vsetvli zero, zero, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfncvt.f.f.w v8, v9
+; ZVFBFA-NEXT:    ret
   ret <2 x bfloat> <bfloat 0.0, bfloat 2.0>
 }
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:

>From 9d2deb2d7d2a6872d5313cc4600d71be12338e8d Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Sat, 11 Apr 2026 00:00:26 -0700
Subject: [PATCH 2/3] Pre-commit tests

---
 .../fixed-vectors-shuffle-vslide1down-bf16.ll | 34 ++++++++++++++++++
 .../rvv/fixed-vectors-shuffle-vslide1down.ll  | 32 +++--------------
 .../fixed-vectors-shuffle-vslide1up-bf16.ll   | 36 +++++++++++++++++++
 .../rvv/fixed-vectors-shuffle-vslide1up.ll    | 34 +++---------------
 4 files changed, 78 insertions(+), 58 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll
 create mode 100644 llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll

diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll
new file mode 100644
index 0000000000000..dc464bb221fd8
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+experimental-zvfbfa -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+experimental-zvfbfa -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFMIN
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFMIN
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+
+define <2 x bfloat> @vslide1down_2xbf16(<2 x bfloat> %v, bfloat %b) {
+; CHECK-LABEL: vslide1down_2xbf16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmv.x.h a0, fa0
+; CHECK-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; CHECK-NEXT:    vslide1down.vx v8, v8, a0
+; CHECK-NEXT:    ret
+  %vb = insertelement <2 x bfloat> poison, bfloat %b, i64 0
+  %v1 = shufflevector <2 x bfloat> %v, <2 x bfloat> %vb, <2 x i32> <i32 1, i32 2>
+  ret <2 x bfloat> %v1
+}
+
+define <4 x bfloat> @vslide1down_4xbf16(<4 x bfloat> %v, bfloat %b) {
+; CHECK-LABEL: vslide1down_4xbf16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmv.x.h a0, fa0
+; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; CHECK-NEXT:    vslide1down.vx v8, v8, a0
+; CHECK-NEXT:    ret
+  %vb = insertelement <4 x bfloat> poison, bfloat %b, i64 0
+  %v1 = shufflevector <4 x bfloat> %v, <4 x bfloat> %vb, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
+  ret <4 x bfloat> %v1
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; ZVFBFA: {{.*}}
+; ZVFBFMIN: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down.ll
index 620aca12d69d7..54c0aa8b45729 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down.ll
@@ -1,8 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zvfh,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV32
-; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zvfh,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV64
-; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV32
-; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV64
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zvfh -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV32
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zvfh -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV64
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV32
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV64
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 
@@ -135,30 +135,6 @@ define <4 x i64> @vslide1down_4xi64(<4 x i64> %v, i64 %b) {
   ret <4 x i64> %v1
 }
 
-define <2 x bfloat> @vslide1down_2xbf16(<2 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1down_2xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT:    vslide1down.vx v8, v8, a0
-; CHECK-NEXT:    ret
-  %vb = insertelement <2 x bfloat> poison, bfloat %b, i64 0
-  %v1 = shufflevector <2 x bfloat> %v, <2 x bfloat> %vb, <2 x i32> <i32 1, i32 2>
-  ret <2 x bfloat> %v1
-}
-
-define <4 x bfloat> @vslide1down_4xbf16(<4 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1down_4xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
-; CHECK-NEXT:    vslide1down.vx v8, v8, a0
-; CHECK-NEXT:    ret
-  %vb = insertelement <4 x bfloat> poison, bfloat %b, i64 0
-  %v1 = shufflevector <4 x bfloat> %v, <4 x bfloat> %vb, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
-  ret <4 x bfloat> %v1
-}
-
 define <2 x half> @vslide1down_2xf16(<2 x half> %v, half %b) {
 ; ZVFH-LABEL: vslide1down_2xf16:
 ; ZVFH:       # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll
new file mode 100644
index 0000000000000..e82ff1bb1a6a5
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+experimental-zvfbfa -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+experimental-zvfbfa -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFA
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFMIN
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFBFMIN
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+
+define <2 x bfloat> @vslide1up_2xbf16(<2 x bfloat> %v, bfloat %b) {
+; CHECK-LABEL: vslide1up_2xbf16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmv.x.h a0, fa0
+; CHECK-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; CHECK-NEXT:    vslide1up.vx v9, v8, a0
+; CHECK-NEXT:    vmv1r.v v8, v9
+; CHECK-NEXT:    ret
+  %vb = insertelement <2 x bfloat> poison, bfloat %b, i64 0
+  %v1 = shufflevector <2 x bfloat> %v, <2 x bfloat> %vb, <2 x i32> <i32 2, i32 0>
+  ret <2 x bfloat> %v1
+}
+
+define <4 x bfloat> @vslide1up_4xbf16(<4 x bfloat> %v, bfloat %b) {
+; CHECK-LABEL: vslide1up_4xbf16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmv.x.h a0, fa0
+; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; CHECK-NEXT:    vslide1up.vx v9, v8, a0
+; CHECK-NEXT:    vmv1r.v v8, v9
+; CHECK-NEXT:    ret
+  %vb = insertelement <4 x bfloat> poison, bfloat %b, i64 0
+  %v1 = shufflevector <4 x bfloat> %v, <4 x bfloat> %vb, <4 x i32> <i32 4, i32 0, i32 1, i32 2>
+  ret <4 x bfloat> %v1
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; ZVFBFA: {{.*}}
+; ZVFBFMIN: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up.ll
index 348c221c9dcea..0cff246ea9a6f 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up.ll
@@ -1,8 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zvfh,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV32
-; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zvfh,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV64
-; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV32
-; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin,+zfbfmin,+zvfbfmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV64
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zvfh -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV32
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zvfh -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,RV64
+; RUN: llc -mtriple=riscv32 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV32
+; RUN: llc -mtriple=riscv64 -mattr=+m,+v,+f,+d,+zfhmin,+zvfhmin -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,RV64
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 
@@ -144,32 +144,6 @@ define <4 x i64> @vslide1up_4xi64(<4 x i64> %v, i64 %b) {
   ret <4 x i64> %v1
 }
 
-define <2 x bfloat> @vslide1up_2xbf16(<2 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1up_2xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT:    vslide1up.vx v9, v8, a0
-; CHECK-NEXT:    vmv1r.v v8, v9
-; CHECK-NEXT:    ret
-  %vb = insertelement <2 x bfloat> poison, bfloat %b, i64 0
-  %v1 = shufflevector <2 x bfloat> %v, <2 x bfloat> %vb, <2 x i32> <i32 2, i32 0>
-  ret <2 x bfloat> %v1
-}
-
-define <4 x bfloat> @vslide1up_4xbf16(<4 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1up_4xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
-; CHECK-NEXT:    vslide1up.vx v9, v8, a0
-; CHECK-NEXT:    vmv1r.v v8, v9
-; CHECK-NEXT:    ret
-  %vb = insertelement <4 x bfloat> poison, bfloat %b, i64 0
-  %v1 = shufflevector <4 x bfloat> %v, <4 x bfloat> %vb, <4 x i32> <i32 4, i32 0, i32 1, i32 2>
-  ret <4 x bfloat> %v1
-}
-
 define <2 x half> @vslide1up_2xf16(<2 x half> %v, half %b) {
 ; ZVFH-LABEL: vslide1up_2xf16:
 ; ZVFH:       # %bb.0:

>From b97ba90cf9db48918242f1069271d4d4cb4869b6 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Sat, 11 Apr 2026 00:08:27 -0700
Subject: [PATCH 3/3] [RISCV] Enable vfslide1up/down for bf16 shuffles with
 Zvfbfa.

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  3 +-
 .../fixed-vectors-shuffle-vslide1down-bf16.ll | 39 ++++++++++------
 .../fixed-vectors-shuffle-vslide1up-bf16.ll   | 45 ++++++++++++-------
 3 files changed, 56 insertions(+), 31 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 73210f3743aa6..e4e97864b4322 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -5560,7 +5560,8 @@ static SDValue lowerVECTOR_SHUFFLEAsVSlide1(const SDLoc &DL, MVT VT,
 
   // zvfhmin and zvfbfmin don't have vfslide1{down,up}.vf so use fmv.x.h +
   // vslide1{down,up}.vx instead.
-  if (VT.getVectorElementType() == MVT::bf16 ||
+  if ((VT.getVectorElementType() == MVT::bf16 &&
+       !Subtarget.hasVInstructionsBF16()) ||
       (VT.getVectorElementType() == MVT::f16 &&
        !Subtarget.hasVInstructionsF16())) {
     MVT IntVT = ContainerVT.changeVectorElementTypeToInteger();
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll
index dc464bb221fd8..9a3e5ed3637b2 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1down-bf16.ll
@@ -7,28 +7,39 @@
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 
 define <2 x bfloat> @vslide1down_2xbf16(<2 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1down_2xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT:    vslide1down.vx v8, v8, a0
-; CHECK-NEXT:    ret
+; ZVFBFA-LABEL: vslide1down_2xbf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfslide1down.vf v8, v8, fa0
+; ZVFBFA-NEXT:    ret
+;
+; ZVFBFMIN-LABEL: vslide1down_2xbf16:
+; ZVFBFMIN:       # %bb.0:
+; ZVFBFMIN-NEXT:    fmv.x.h a0, fa0
+; ZVFBFMIN-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFMIN-NEXT:    vslide1down.vx v8, v8, a0
+; ZVFBFMIN-NEXT:    ret
   %vb = insertelement <2 x bfloat> poison, bfloat %b, i64 0
   %v1 = shufflevector <2 x bfloat> %v, <2 x bfloat> %vb, <2 x i32> <i32 1, i32 2>
   ret <2 x bfloat> %v1
 }
 
 define <4 x bfloat> @vslide1down_4xbf16(<4 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1down_4xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
-; CHECK-NEXT:    vslide1down.vx v8, v8, a0
-; CHECK-NEXT:    ret
+; ZVFBFA-LABEL: vslide1down_4xbf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfslide1down.vf v8, v8, fa0
+; ZVFBFA-NEXT:    ret
+;
+; ZVFBFMIN-LABEL: vslide1down_4xbf16:
+; ZVFBFMIN:       # %bb.0:
+; ZVFBFMIN-NEXT:    fmv.x.h a0, fa0
+; ZVFBFMIN-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFBFMIN-NEXT:    vslide1down.vx v8, v8, a0
+; ZVFBFMIN-NEXT:    ret
   %vb = insertelement <4 x bfloat> poison, bfloat %b, i64 0
   %v1 = shufflevector <4 x bfloat> %v, <4 x bfloat> %vb, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
   ret <4 x bfloat> %v1
 }
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; ZVFBFA: {{.*}}
-; ZVFBFMIN: {{.*}}
+; CHECK: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll
index e82ff1bb1a6a5..3e274f57f9d55 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-vslide1up-bf16.ll
@@ -7,30 +7,43 @@
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 
 define <2 x bfloat> @vslide1up_2xbf16(<2 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1up_2xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT:    vslide1up.vx v9, v8, a0
-; CHECK-NEXT:    vmv1r.v v8, v9
-; CHECK-NEXT:    ret
+; ZVFBFA-LABEL: vslide1up_2xbf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT:    vfslide1up.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
+; ZVFBFA-NEXT:    ret
+;
+; ZVFBFMIN-LABEL: vslide1up_2xbf16:
+; ZVFBFMIN:       # %bb.0:
+; ZVFBFMIN-NEXT:    fmv.x.h a0, fa0
+; ZVFBFMIN-NEXT:    vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFMIN-NEXT:    vslide1up.vx v9, v8, a0
+; ZVFBFMIN-NEXT:    vmv1r.v v8, v9
+; ZVFBFMIN-NEXT:    ret
   %vb = insertelement <2 x bfloat> poison, bfloat %b, i64 0
   %v1 = shufflevector <2 x bfloat> %v, <2 x bfloat> %vb, <2 x i32> <i32 2, i32 0>
   ret <2 x bfloat> %v1
 }
 
 define <4 x bfloat> @vslide1up_4xbf16(<4 x bfloat> %v, bfloat %b) {
-; CHECK-LABEL: vslide1up_4xbf16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    fmv.x.h a0, fa0
-; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
-; CHECK-NEXT:    vslide1up.vx v9, v8, a0
-; CHECK-NEXT:    vmv1r.v v8, v9
-; CHECK-NEXT:    ret
+; ZVFBFA-LABEL: vslide1up_4xbf16:
+; ZVFBFA:       # %bb.0:
+; ZVFBFA-NEXT:    vsetivli zero, 4, e16alt, mf2, ta, ma
+; ZVFBFA-NEXT:    vfslide1up.vf v9, v8, fa0
+; ZVFBFA-NEXT:    vmv1r.v v8, v9
+; ZVFBFA-NEXT:    ret
+;
+; ZVFBFMIN-LABEL: vslide1up_4xbf16:
+; ZVFBFMIN:       # %bb.0:
+; ZVFBFMIN-NEXT:    fmv.x.h a0, fa0
+; ZVFBFMIN-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
+; ZVFBFMIN-NEXT:    vslide1up.vx v9, v8, a0
+; ZVFBFMIN-NEXT:    vmv1r.v v8, v9
+; ZVFBFMIN-NEXT:    ret
   %vb = insertelement <4 x bfloat> poison, bfloat %b, i64 0
   %v1 = shufflevector <4 x bfloat> %v, <4 x bfloat> %vb, <4 x i32> <i32 4, i32 0, i32 1, i32 2>
   ret <4 x bfloat> %v1
 }
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; ZVFBFA: {{.*}}
-; ZVFBFMIN: {{.*}}
+; CHECK: {{.*}}



More information about the llvm-commits mailing list