[llvm] [RISCV] Merge zeroing stores into wider LMUL vector stores (PR #223908)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 15 21:05:30 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Pengcheng Wang (wangpc-pp)
<details>
<summary>Changes</summary>
memset lowers to LMUL1 vector stores (v2i64 for e64) that we rely on
store merging to widen. `storeOfVectorConstantIsCheap` counted the
number of MemVT-sized stores, so a v2i64 MemVT needed 4 stores before
merging kicked in, leaving two VL=2 m1 stores for a 32B zero region.
Use the total element count for zeroing stores so two v2i64 stores
merge into one VL=4 e64 m2 store.
Partially fixes #<!-- -->223906
Assisted-by: TRAE CLI (Opus 4.8)
---
Full diff: https://github.com/llvm/llvm-project/pull/223908.diff
4 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+10-2)
- (modified) llvm/test/CodeGen/RISCV/rvv/memset-inline.ll (+16-34)
- (modified) llvm/test/CodeGen/RISCV/rvv/pr83017.ll (+3-5)
- (modified) llvm/test/CodeGen/RISCV/rvv/pr90559.ll (+4-6)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index a7f5a1304863e..661e2f041236b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -217,8 +217,16 @@ class RISCVTargetLowering : public TargetLowering {
bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT, unsigned NumElem,
unsigned AddrSpace) const override {
- // If we can replace 4 or more scalar stores, there will be a reduction
- // in instructions even after we add a vector constant load.
+ // A zero splat is free to materialize, so merging is a win once it
+ // covers 4 or more elements. MemVT may already be a vector, since
+ // memset lowers to LMUL1 stores that we want to merge into a larger
+ // LMUL, so use the total element count.
+ unsigned NumMemElts = MemVT.isVector() ? MemVT.getVectorNumElements() : 1;
+ if (IsZero)
+ return NumElem * NumMemElts >= 4;
+
+ // Non-zero vector constants aren't always cheap to materialize; only
+ // merge when replacing 4 or more scalar stores.
return NumElem >= 4;
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/memset-inline.ll b/llvm/test/CodeGen/RISCV/rvv/memset-inline.ll
index 0417b36fd9db5..d3e8de8b1730e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/memset-inline.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/memset-inline.ll
@@ -501,38 +501,32 @@ define void @memset_zero_16(ptr %a) nounwind {
define void @memset_zero_32(ptr %a) nounwind {
; RV32-LABEL: memset_zero_32:
; RV32: # %bb.0:
-; RV32-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; RV32-NEXT: li a1, 32
+; RV32-NEXT: vsetvli zero, a1, e8, m2, ta, ma
; RV32-NEXT: vmv.v.i v8, 0
-; RV32-NEXT: addi a1, a0, 16
; RV32-NEXT: vse8.v v8, (a0)
-; RV32-NEXT: vse8.v v8, (a1)
; RV32-NEXT: ret
;
; RV64-LABEL: memset_zero_32:
; RV64: # %bb.0:
-; RV64-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; RV64-NEXT: li a1, 32
+; RV64-NEXT: vsetvli zero, a1, e8, m2, ta, ma
; RV64-NEXT: vmv.v.i v8, 0
-; RV64-NEXT: addi a1, a0, 16
; RV64-NEXT: vse8.v v8, (a0)
-; RV64-NEXT: vse8.v v8, (a1)
; RV64-NEXT: ret
;
; RV32-FAST-LABEL: memset_zero_32:
; RV32-FAST: # %bb.0:
-; RV32-FAST-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; RV32-FAST-NEXT: vsetivli zero, 4, e64, m2, ta, ma
; RV32-FAST-NEXT: vmv.v.i v8, 0
-; RV32-FAST-NEXT: addi a1, a0, 16
; RV32-FAST-NEXT: vse64.v v8, (a0)
-; RV32-FAST-NEXT: vse64.v v8, (a1)
; RV32-FAST-NEXT: ret
;
; RV64-FAST-LABEL: memset_zero_32:
; RV64-FAST: # %bb.0:
-; RV64-FAST-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; RV64-FAST-NEXT: vsetivli zero, 4, e64, m2, ta, ma
; RV64-FAST-NEXT: vmv.v.i v8, 0
-; RV64-FAST-NEXT: addi a1, a0, 16
; RV64-FAST-NEXT: vse64.v v8, (a0)
-; RV64-FAST-NEXT: vse64.v v8, (a1)
; RV64-FAST-NEXT: ret
tail call void @llvm.memset.inline.p0.i64(ptr %a, i8 0, i64 32, i1 0)
ret void
@@ -638,20 +632,16 @@ define void @aligned_memset_zero_16(ptr %a) nounwind {
define void @aligned_memset_zero_32(ptr %a) nounwind {
; RV32-BOTH-LABEL: aligned_memset_zero_32:
; RV32-BOTH: # %bb.0:
-; RV32-BOTH-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; RV32-BOTH-NEXT: vsetivli zero, 4, e64, m2, ta, ma
; RV32-BOTH-NEXT: vmv.v.i v8, 0
-; RV32-BOTH-NEXT: addi a1, a0, 16
; RV32-BOTH-NEXT: vse64.v v8, (a0)
-; RV32-BOTH-NEXT: vse64.v v8, (a1)
; RV32-BOTH-NEXT: ret
;
; RV64-BOTH-LABEL: aligned_memset_zero_32:
; RV64-BOTH: # %bb.0:
-; RV64-BOTH-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; RV64-BOTH-NEXT: vsetivli zero, 4, e64, m2, ta, ma
; RV64-BOTH-NEXT: vmv.v.i v8, 0
-; RV64-BOTH-NEXT: addi a1, a0, 16
; RV64-BOTH-NEXT: vse64.v v8, (a0)
-; RV64-BOTH-NEXT: vse64.v v8, (a1)
; RV64-BOTH-NEXT: ret
tail call void @llvm.memset.inline.p0.i64(ptr align 32 %a, i8 0, i64 32, i1 0)
ret void
@@ -698,31 +688,23 @@ define void @aligned_memset_zero_66(ptr %a) nounwind {
define void @aligned_memset_zero_96(ptr %a) nounwind {
; RV32-BOTH-LABEL: aligned_memset_zero_96:
; RV32-BOTH: # %bb.0:
-; RV32-BOTH-NEXT: vsetivli zero, 2, e64, m1, ta, ma
-; RV32-BOTH-NEXT: vmv.v.i v12, 0
; RV32-BOTH-NEXT: vsetivli zero, 8, e64, m4, ta, ma
; RV32-BOTH-NEXT: vmv.v.i v8, 0
-; RV32-BOTH-NEXT: addi a1, a0, 80
-; RV32-BOTH-NEXT: vsetivli zero, 2, e64, m1, ta, ma
-; RV32-BOTH-NEXT: vse64.v v12, (a1)
-; RV32-BOTH-NEXT: addi a1, a0, 64
-; RV32-BOTH-NEXT: vse64.v v12, (a1)
-; RV32-BOTH-NEXT: vsetivli zero, 8, e64, m4, ta, ma
+; RV32-BOTH-NEXT: vse64.v v8, (a0)
+; RV32-BOTH-NEXT: vsetivli zero, 4, e64, m2, ta, ma
+; RV32-BOTH-NEXT: vmv.v.i v8, 0
+; RV32-BOTH-NEXT: addi a0, a0, 64
; RV32-BOTH-NEXT: vse64.v v8, (a0)
; RV32-BOTH-NEXT: ret
;
; RV64-BOTH-LABEL: aligned_memset_zero_96:
; RV64-BOTH: # %bb.0:
-; RV64-BOTH-NEXT: vsetivli zero, 2, e64, m1, ta, ma
-; RV64-BOTH-NEXT: vmv.v.i v12, 0
; RV64-BOTH-NEXT: vsetivli zero, 8, e64, m4, ta, ma
; RV64-BOTH-NEXT: vmv.v.i v8, 0
-; RV64-BOTH-NEXT: addi a1, a0, 80
-; RV64-BOTH-NEXT: vsetivli zero, 2, e64, m1, ta, ma
-; RV64-BOTH-NEXT: vse64.v v12, (a1)
-; RV64-BOTH-NEXT: addi a1, a0, 64
-; RV64-BOTH-NEXT: vse64.v v12, (a1)
-; RV64-BOTH-NEXT: vsetivli zero, 8, e64, m4, ta, ma
+; RV64-BOTH-NEXT: vse64.v v8, (a0)
+; RV64-BOTH-NEXT: vsetivli zero, 4, e64, m2, ta, ma
+; RV64-BOTH-NEXT: vmv.v.i v8, 0
+; RV64-BOTH-NEXT: addi a0, a0, 64
; RV64-BOTH-NEXT: vse64.v v8, (a0)
; RV64-BOTH-NEXT: ret
tail call void @llvm.memset.inline.p0.i64(ptr align 64 %a, i8 0, i64 96, i1 0)
diff --git a/llvm/test/CodeGen/RISCV/rvv/pr83017.ll b/llvm/test/CodeGen/RISCV/rvv/pr83017.ll
index fc509deb63236..47124ee314e19 100644
--- a/llvm/test/CodeGen/RISCV/rvv/pr83017.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/pr83017.ll
@@ -30,15 +30,13 @@
define void @aliasing(ptr %p) {
; CHECK-LABEL: aliasing:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma
; CHECK-NEXT: vmv.v.i v12, 0
; CHECK-NEXT: vsetvli a1, zero, e8, m4, ta, ma
; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: addi a1, a0, 80
-; CHECK-NEXT: lw a2, 84(a0)
-; CHECK-NEXT: vs1r.v v12, (a1)
; CHECK-NEXT: addi a1, a0, 64
-; CHECK-NEXT: vs1r.v v12, (a1)
+; CHECK-NEXT: lw a2, 84(a0)
+; CHECK-NEXT: vs2r.v v12, (a1)
; CHECK-NEXT: vs4r.v v8, (a0)
; CHECK-NEXT: sw a2, 84(a0)
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rvv/pr90559.ll b/llvm/test/CodeGen/RISCV/rvv/pr90559.ll
index 1632244abafbc..818bdb800ca60 100644
--- a/llvm/test/CodeGen/RISCV/rvv/pr90559.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/pr90559.ll
@@ -27,17 +27,15 @@
define void @f(ptr %p) vscale_range(2,2) {
; CHECK-LABEL: f:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma
; CHECK-NEXT: vmv.v.i v12, 0
; CHECK-NEXT: vsetvli a1, zero, e8, m4, ta, ma
; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: addi a1, a0, 80
-; CHECK-NEXT: lw a2, 84(a0)
-; CHECK-NEXT: vs1r.v v12, (a1)
; CHECK-NEXT: addi a1, a0, 64
-; CHECK-NEXT: vs1r.v v12, (a1)
-; CHECK-NEXT: sw a2, 84(a0)
+; CHECK-NEXT: lw a2, 84(a0)
+; CHECK-NEXT: vs2r.v v12, (a1)
; CHECK-NEXT: vs4r.v v8, (a0)
+; CHECK-NEXT: sw a2, 84(a0)
; CHECK-NEXT: ret
%q = getelementptr inbounds i8, ptr %p, i64 84
%x = load i32, ptr %q
``````````
</details>
https://github.com/llvm/llvm-project/pull/223908
More information about the llvm-commits
mailing list