From f22a1e23500b5e8ee17cf1e9d3aefd5a2e98ef1b Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Fri, 21 Nov 2025 15:53:46 +0800 Subject: [PATCH 1/3] Precommit tests --- .../RISCV/rvv/fixed-vectors-vector-splice.ll | 49 +++++++++++++++++ llvm/test/CodeGen/RISCV/rvv/vector-splice.ll | 52 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll new file mode 100644 index 0000000000000..42d1c0321cfd1 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll @@ -0,0 +1,49 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc -mtriple riscv32 -mattr=+v < %s | FileCheck %s +; RUN: llc -mtriple riscv64 -mattr=+v < %s | FileCheck %s +; RUN: llc -mtriple riscv32 -mattr=+v,+vl-dependent-latency < %s | FileCheck %s +; RUN: llc -mtriple riscv64 -mattr=+v,+vl-dependent-latency < %s | FileCheck %s + +define <4 x i32> @splice_v4i32_slidedown(<4 x i32> %a, <4 x i32> %b) #0 { +; CHECK-LABEL: splice_v4i32_slidedown: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vrgather.vi v9, v8, 3 +; CHECK-NEXT: vmv.v.v v8, v9 +; CHECK-NEXT: ret + %res = call <4 x i32> @llvm.vector.splice(<4 x i32> %a, <4 x i32> poison, i32 3) + ret <4 x i32> %res +} + +define <4 x i32> @splice_4i32_slideup(<4 x i32> %a) #0 { +; CHECK-LABEL: splice_4i32_slideup: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vrgather.vi v9, v8, 0 +; CHECK-NEXT: vmv.v.v v8, v9 +; CHECK-NEXT: ret + %res = call <4 x i32> @llvm.vector.splice(<4 x i32> poison, <4 x i32> %a, i32 -3) + ret <4 x i32> %res +} + +define <8 x i32> @splice_v8i32_slidedown(<8 x i32> %a, <8 x i32> %b) #0 { +; CHECK-LABEL: splice_v8i32_slidedown: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 3 +; CHECK-NEXT: ret + %res = call <8 x i32> @llvm.vector.splice(<8 x i32> %a, <8 x i32> poison, i32 3) + ret <8 x i32> %res +} + +define <8 x i32> @splice_v8i32_slideup(<8 x i32> %a) #0 { +; CHECK-LABEL: splice_v8i32_slideup: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vslideup.vi v10, v8, 3 +; CHECK-NEXT: vmv.v.v v8, v10 +; CHECK-NEXT: ret + %res = call <8 x i32> @llvm.vector.splice(<8 x i32> poison, <8 x i32> %a, i32 -3) + ret <8 x i32> %res +} + diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll b/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll index acc2a97dd5d1f..546cf1a1b141d 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll @@ -4247,4 +4247,56 @@ define @splice_nxv8f64_offset_max( %a ret %res } +define @splice_nxv2i32_slidedown( %a) #0 { +; NOVLDEP-LABEL: splice_nxv2i32_slidedown: +; NOVLDEP: # %bb.0: +; NOVLDEP-NEXT: vsetvli a0, zero, e32, m1, ta, ma +; NOVLDEP-NEXT: vslidedown.vi v8, v8, 3 +; NOVLDEP-NEXT: csrr a0, vlenb +; NOVLDEP-NEXT: srli a0, a0, 2 +; NOVLDEP-NEXT: addi a0, a0, -3 +; NOVLDEP-NEXT: vslideup.vx v8, v9, a0 +; NOVLDEP-NEXT: ret +; +; VLDEP-LABEL: splice_nxv2i32_slidedown: +; VLDEP: # %bb.0: +; VLDEP-NEXT: csrr a0, vlenb +; VLDEP-NEXT: srli a0, a0, 2 +; VLDEP-NEXT: addi a0, a0, -3 +; VLDEP-NEXT: vsetvli zero, a0, e32, m1, ta, ma +; VLDEP-NEXT: vslidedown.vi v8, v8, 3 +; VLDEP-NEXT: vsetvli a1, zero, e32, m1, ta, ma +; VLDEP-NEXT: vslideup.vx v8, v9, a0 +; VLDEP-NEXT: ret + %res = call @llvm.vector.splice( %a, poison, i32 3) + ret %res +} + +define @splice_nxv2i32_slideup( %a) #0 { +; NOVLDEP-LABEL: splice_nxv2i32_slideup: +; NOVLDEP: # %bb.0: +; NOVLDEP-NEXT: csrr a0, vlenb +; NOVLDEP-NEXT: srli a0, a0, 2 +; NOVLDEP-NEXT: addi a0, a0, -3 +; NOVLDEP-NEXT: vsetvli a1, zero, e32, m1, ta, ma +; NOVLDEP-NEXT: vslidedown.vx v9, v8, a0 +; NOVLDEP-NEXT: vslideup.vi v9, v8, 3 +; NOVLDEP-NEXT: vmv.v.v v8, v9 +; NOVLDEP-NEXT: ret +; +; VLDEP-LABEL: splice_nxv2i32_slideup: +; VLDEP: # %bb.0: +; VLDEP-NEXT: csrr a0, vlenb +; VLDEP-NEXT: srli a0, a0, 2 +; VLDEP-NEXT: addi a0, a0, -3 +; VLDEP-NEXT: vsetivli zero, 3, e32, m1, ta, ma +; VLDEP-NEXT: vslidedown.vx v9, v8, a0 +; VLDEP-NEXT: vsetvli a0, zero, e32, m1, ta, ma +; VLDEP-NEXT: vslideup.vi v9, v8, 3 +; VLDEP-NEXT: vmv.v.v v8, v9 +; VLDEP-NEXT: ret + %res = call @llvm.vector.splice( poison, %a, i32 -3) + ret %res +} + attributes #0 = { vscale_range(2,0) } From 12ac3337e5dbe93c55d76629186a42a95e380f4f Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Fri, 21 Nov 2025 15:54:47 +0800 Subject: [PATCH 2/3] [RISCV] Combine vslide{up,down} x, poison -> x The motivation for this is that it would be useful to express a vslideup/vslidedown in a target independent way e.g. from the loop vectorizer. We can do this today with @llvm.vector.splice by setting one operand to poison: - A slide down can be achieved with @llvm.vector.splice(%x, poison, slideamt) - A slide up can be done by @llvm.vector.splice(poison, %x, -slideamt) E.g.: splice(, poison, 3) = splice(poison, , -3) = These splices get lowered to a vslideup + vslidedown pair with one of the vs2s being poison. We can optimize this away so that we are just left with a single slideup/slidedown. --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 5 +++ llvm/test/CodeGen/RISCV/rvv/vector-splice.ll | 34 ++++---------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 2d6bb06d689c3..209e2969046c9 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -21834,6 +21834,11 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, return N->getOperand(0); break; } + case RISCVISD::VSLIDEDOWN_VL: + case RISCVISD::VSLIDEUP_VL: + if (N->getOperand(1)->isUndef()) + return N->getOperand(0); + break; case RISCVISD::VSLIDE1UP_VL: case RISCVISD::VFSLIDE1UP_VL: { using namespace SDPatternMatch; diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll b/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll index 546cf1a1b141d..31936d3a084b2 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll @@ -4252,10 +4252,6 @@ define @splice_nxv2i32_slidedown( %a) #0 { ; NOVLDEP: # %bb.0: ; NOVLDEP-NEXT: vsetvli a0, zero, e32, m1, ta, ma ; NOVLDEP-NEXT: vslidedown.vi v8, v8, 3 -; NOVLDEP-NEXT: csrr a0, vlenb -; NOVLDEP-NEXT: srli a0, a0, 2 -; NOVLDEP-NEXT: addi a0, a0, -3 -; NOVLDEP-NEXT: vslideup.vx v8, v9, a0 ; NOVLDEP-NEXT: ret ; ; VLDEP-LABEL: splice_nxv2i32_slidedown: @@ -4265,36 +4261,18 @@ define @splice_nxv2i32_slidedown( %a) #0 { ; VLDEP-NEXT: addi a0, a0, -3 ; VLDEP-NEXT: vsetvli zero, a0, e32, m1, ta, ma ; VLDEP-NEXT: vslidedown.vi v8, v8, 3 -; VLDEP-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; VLDEP-NEXT: vslideup.vx v8, v9, a0 ; VLDEP-NEXT: ret %res = call @llvm.vector.splice( %a, poison, i32 3) ret %res } define @splice_nxv2i32_slideup( %a) #0 { -; NOVLDEP-LABEL: splice_nxv2i32_slideup: -; NOVLDEP: # %bb.0: -; NOVLDEP-NEXT: csrr a0, vlenb -; NOVLDEP-NEXT: srli a0, a0, 2 -; NOVLDEP-NEXT: addi a0, a0, -3 -; NOVLDEP-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; NOVLDEP-NEXT: vslidedown.vx v9, v8, a0 -; NOVLDEP-NEXT: vslideup.vi v9, v8, 3 -; NOVLDEP-NEXT: vmv.v.v v8, v9 -; NOVLDEP-NEXT: ret -; -; VLDEP-LABEL: splice_nxv2i32_slideup: -; VLDEP: # %bb.0: -; VLDEP-NEXT: csrr a0, vlenb -; VLDEP-NEXT: srli a0, a0, 2 -; VLDEP-NEXT: addi a0, a0, -3 -; VLDEP-NEXT: vsetivli zero, 3, e32, m1, ta, ma -; VLDEP-NEXT: vslidedown.vx v9, v8, a0 -; VLDEP-NEXT: vsetvli a0, zero, e32, m1, ta, ma -; VLDEP-NEXT: vslideup.vi v9, v8, 3 -; VLDEP-NEXT: vmv.v.v v8, v9 -; VLDEP-NEXT: ret +; CHECK-LABEL: splice_nxv2i32_slideup: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma +; CHECK-NEXT: vslideup.vi v9, v8, 3 +; CHECK-NEXT: vmv.v.v v8, v9 +; CHECK-NEXT: ret %res = call @llvm.vector.splice( poison, %a, i32 -3) ret %res } From 7187cdf3acf1a550df84f1acf254fe9786c291eb Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Mon, 24 Nov 2025 11:27:53 +0800 Subject: [PATCH 3/3] Remove dangling attributes, add undef tests --- .../RISCV/rvv/fixed-vectors-vector-splice.ll | 50 +++++++++++++++++-- llvm/test/CodeGen/RISCV/rvv/vector-splice.ll | 30 +++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll index 42d1c0321cfd1..b73b4c5150347 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vector-splice.ll @@ -4,7 +4,7 @@ ; RUN: llc -mtriple riscv32 -mattr=+v,+vl-dependent-latency < %s | FileCheck %s ; RUN: llc -mtriple riscv64 -mattr=+v,+vl-dependent-latency < %s | FileCheck %s -define <4 x i32> @splice_v4i32_slidedown(<4 x i32> %a, <4 x i32> %b) #0 { +define <4 x i32> @splice_v4i32_slidedown(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: splice_v4i32_slidedown: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma @@ -15,7 +15,7 @@ define <4 x i32> @splice_v4i32_slidedown(<4 x i32> %a, <4 x i32> %b) #0 { ret <4 x i32> %res } -define <4 x i32> @splice_4i32_slideup(<4 x i32> %a) #0 { +define <4 x i32> @splice_4i32_slideup(<4 x i32> %a) { ; CHECK-LABEL: splice_4i32_slideup: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma @@ -26,7 +26,7 @@ define <4 x i32> @splice_4i32_slideup(<4 x i32> %a) #0 { ret <4 x i32> %res } -define <8 x i32> @splice_v8i32_slidedown(<8 x i32> %a, <8 x i32> %b) #0 { +define <8 x i32> @splice_v8i32_slidedown(<8 x i32> %a, <8 x i32> %b) { ; CHECK-LABEL: splice_v8i32_slidedown: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma @@ -36,7 +36,7 @@ define <8 x i32> @splice_v8i32_slidedown(<8 x i32> %a, <8 x i32> %b) #0 { ret <8 x i32> %res } -define <8 x i32> @splice_v8i32_slideup(<8 x i32> %a) #0 { +define <8 x i32> @splice_v8i32_slideup(<8 x i32> %a) { ; CHECK-LABEL: splice_v8i32_slideup: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma @@ -47,3 +47,45 @@ define <8 x i32> @splice_v8i32_slideup(<8 x i32> %a) #0 { ret <8 x i32> %res } +define <4 x i32> @splice_v4i32_slidedown_undef(<4 x i32> %a, <4 x i32> %b) { +; CHECK-LABEL: splice_v4i32_slidedown_undef: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vrgather.vi v9, v8, 3 +; CHECK-NEXT: vmv.v.v v8, v9 +; CHECK-NEXT: ret + %res = call <4 x i32> @llvm.vector.splice(<4 x i32> %a, <4 x i32> undef, i32 3) + ret <4 x i32> %res +} + +define <4 x i32> @splice_4i32_slideup_undef(<4 x i32> %a) { +; CHECK-LABEL: splice_4i32_slideup_undef: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vrgather.vi v9, v8, 0 +; CHECK-NEXT: vmv.v.v v8, v9 +; CHECK-NEXT: ret + %res = call <4 x i32> @llvm.vector.splice(<4 x i32> undef, <4 x i32> %a, i32 -3) + ret <4 x i32> %res +} + +define <8 x i32> @splice_v8i32_slidedown_undef(<8 x i32> %a, <8 x i32> %b) { +; CHECK-LABEL: splice_v8i32_slidedown_undef: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 3 +; CHECK-NEXT: ret + %res = call <8 x i32> @llvm.vector.splice(<8 x i32> %a, <8 x i32> undef, i32 3) + ret <8 x i32> %res +} + +define <8 x i32> @splice_v8i32_slideup_undef(<8 x i32> %a) { +; CHECK-LABEL: splice_v8i32_slideup_undef: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vslideup.vi v10, v8, 3 +; CHECK-NEXT: vmv.v.v v8, v10 +; CHECK-NEXT: ret + %res = call <8 x i32> @llvm.vector.splice(<8 x i32> undef, <8 x i32> %a, i32 -3) + ret <8 x i32> %res +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll b/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll index 31936d3a084b2..677a0aa712b5d 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vector-splice.ll @@ -4277,4 +4277,34 @@ define @splice_nxv2i32_slideup( %a) #0 { ret %res } +define @splice_nxv2i32_slidedown_undef( %a) #0 { +; NOVLDEP-LABEL: splice_nxv2i32_slidedown_undef: +; NOVLDEP: # %bb.0: +; NOVLDEP-NEXT: vsetvli a0, zero, e32, m1, ta, ma +; NOVLDEP-NEXT: vslidedown.vi v8, v8, 3 +; NOVLDEP-NEXT: ret +; +; VLDEP-LABEL: splice_nxv2i32_slidedown_undef: +; VLDEP: # %bb.0: +; VLDEP-NEXT: csrr a0, vlenb +; VLDEP-NEXT: srli a0, a0, 2 +; VLDEP-NEXT: addi a0, a0, -3 +; VLDEP-NEXT: vsetvli zero, a0, e32, m1, ta, ma +; VLDEP-NEXT: vslidedown.vi v8, v8, 3 +; VLDEP-NEXT: ret + %res = call @llvm.vector.splice( %a, undef, i32 3) + ret %res +} + +define @splice_nxv2i32_slideup_undef( %a) #0 { +; CHECK-LABEL: splice_nxv2i32_slideup_undef: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma +; CHECK-NEXT: vslideup.vi v9, v8, 3 +; CHECK-NEXT: vmv.v.v v8, v9 +; CHECK-NEXT: ret + %res = call @llvm.vector.splice( undef, %a, i32 -3) + ret %res +} + attributes #0 = { vscale_range(2,0) }