[llvm-branch-commits] [llvm] release/23.x: [RISCV] Avoid pre-RA Zilsd pairs with same src/dst registers (#215575) (PR #215602)
Douglas Yung via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Aug 15 08:43:16 PDT 2026
https://github.com/dyung updated https://github.com/llvm/llvm-project/pull/215602
>From 4a94b37026f5b50bcdc7f4711f65a61816514e1d Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <svs at qti.qualcomm.com>
Date: Tue, 11 Aug 2026 21:28:46 +0530
Subject: [PATCH] [RISCV] Avoid pre-RA Zilsd pairs with same src/dst registers
(#215575)
The pre-RA Zilsd optimizer previously allowed a special case for stores
where both source operands were the same vreg if that vreg was defined
by COPY $x0. This assumes register allocation will preserve the value as
x0, but that is not guaranteed. The vreg can be allocated to a normal
GPR, producing an invalid pair.
(cherry picked from commit 4ef2427b4c08fd28e4244c585ae0673711e4c0d6)
---
llvm/lib/Target/RISCV/RISCVZilsdOptimizer.cpp | 16 +-----
.../CodeGen/RISCV/zilsd-ldst-opt-prera.mir | 3 +-
llvm/test/CodeGen/RISCV/zilsd.ll | 55 +++++++++++++++----
3 files changed, 48 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVZilsdOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVZilsdOptimizer.cpp
index 54908b31f6299..1886ccc0b8186 100644
--- a/llvm/lib/Target/RISCV/RISCVZilsdOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVZilsdOptimizer.cpp
@@ -212,22 +212,8 @@ bool RISCVPreAllocZilsdOpt::canFormLdSdPair(MachineInstr *MI0,
// Check that the two destination/source registers are different for
// load/store respectively.
- // The only case two destinations/sources can be same is (x0, x0). This pass
- // is run before register coalescer so it will be the form of:
- // %0 = COPY $x0
- // SW %0, %ptr
- // instead of:
- // SW $x0, %ptr
- Register FirstReg = MI0->getOperand(0).getReg();
- Register SecondReg = MI1->getOperand(0).getReg();
- if (FirstReg == SecondReg) {
- const MachineInstr *FirstOpDefInst = MRI->getUniqueVRegDef(FirstReg);
- if (FirstOpDefInst->isCopy() &&
- FirstOpDefInst->getOperand(1).getReg() == RISCV::X0 &&
- MRI->getRegClass(FirstReg)->contains(RISCV::X0))
- return true;
+ if (MI0->getOperand(0).getReg() == MI1->getOperand(0).getReg())
return false;
- }
return true;
}
diff --git a/llvm/test/CodeGen/RISCV/zilsd-ldst-opt-prera.mir b/llvm/test/CodeGen/RISCV/zilsd-ldst-opt-prera.mir
index 490586430e9b2..09c0f5d00f786 100644
--- a/llvm/test/CodeGen/RISCV/zilsd-ldst-opt-prera.mir
+++ b/llvm/test/CodeGen/RISCV/zilsd-ldst-opt-prera.mir
@@ -363,7 +363,8 @@ body: |
; CHECK-4BYTE-NEXT: {{ $}}
; CHECK-4BYTE-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
; CHECK-4BYTE-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
- ; CHECK-4BYTE-NEXT: PseudoSD_RV32_OPT [[COPY1]], [[COPY1]], [[COPY]], 0 :: (store (s32))
+ ; CHECK-4BYTE-NEXT: SW [[COPY1]], [[COPY]], 0 :: (store (s32))
+ ; CHECK-4BYTE-NEXT: SW [[COPY1]], [[COPY]], 4 :: (store (s32))
; CHECK-4BYTE-NEXT: PseudoRET
%0:gpr = COPY $x10
%1:gpr = COPY $x0
diff --git a/llvm/test/CodeGen/RISCV/zilsd.ll b/llvm/test/CodeGen/RISCV/zilsd.ll
index 40ef659a7ce6c..b2b71da3898a4 100644
--- a/llvm/test/CodeGen/RISCV/zilsd.ll
+++ b/llvm/test/CodeGen/RISCV/zilsd.ll
@@ -276,18 +276,53 @@ entry:
}
define void @basic_store_zero_combine(ptr %0, i32 %1, i32 %2) {
-; SLOW-LABEL: basic_store_zero_combine:
-; SLOW: # %bb.0:
-; SLOW-NEXT: sw zero, 0(a0)
-; SLOW-NEXT: sw zero, 4(a0)
-; SLOW-NEXT: ret
-;
-; FAST-LABEL: basic_store_zero_combine:
-; FAST: # %bb.0:
-; FAST-NEXT: sd zero, 0(a0)
-; FAST-NEXT: ret
+; CHECK-LABEL: basic_store_zero_combine:
+; CHECK: # %bb.0:
+; CHECK-NEXT: sw zero, 0(a0)
+; CHECK-NEXT: sw zero, 4(a0)
+; CHECK-NEXT: ret
store i32 0, ptr %0, align 4
%4 = getelementptr inbounds i32, ptr %0, i32 1
store i32 0, ptr %4, align 4
ret void
}
+
+declare void @llvm.memset.p0.i32(ptr, i8, i32, i1 immarg)
+
+define void @no_coalesce() #0 {
+; CHECK-LABEL: no_coalesce:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: li a1, 0
+; CHECK-NEXT: li a0, 1
+; CHECK-NEXT: j .LBB12_2
+; CHECK-NEXT: .LBB12_1: # %crash
+; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1
+; CHECK-NEXT: sd a0, 0(zero)
+; CHECK-NEXT: sw a1, 8(zero)
+; CHECK-NEXT: sw a1, 0(zero)
+; CHECK-NEXT: sw a1, 4(zero)
+; CHECK-NEXT: .LBB12_2: # %loop
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: bnez a1, .LBB12_1
+; CHECK-NEXT: # %bb.3: # %loop
+; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1
+; CHECK-NEXT: beqz a1, .LBB12_2
+; CHECK-NEXT: # %bb.4: # %exit
+; CHECK-NEXT: ret
+entry:
+ br label %loop
+
+loop:
+ switch i8 0, label %loop [
+ i8 1, label %crash
+ i8 3, label %exit
+ ]
+
+crash:
+ store i64 1, ptr null, align 8
+ call void @llvm.memset.p0.i32(ptr null, i8 0, i32 12, i1 false)
+ br label %loop
+
+exit:
+ ret void
+}
More information about the llvm-branch-commits
mailing list