[llvm] [RISCV] Move unpaired instruction back in RISCVLoadStoreOptimizer (PR #189912)
Sudharsan Veeravalli via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 01:27:34 PDT 2026
https://github.com/svs-quic created https://github.com/llvm/llvm-project/pull/189912
There are cases when the `Xqcilsm` vendor extension is enabled that we are unable to pair non-adjacent load/store instructions. The `RISCVLoadStoreOptimizer` moves the instruction adjacent to the other before attempting to pair them but does not move them back when it fails. This can sometimes prevent the generation of the `Xqcilsm` load/store multiple instructions. This patch ensures that we move the unpaired instruction back to it's original location.
>From 36f04307e20f689a0d609db0ec7efb4734db011a Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <svs at qti.qualcomm.com>
Date: Wed, 1 Apr 2026 13:34:45 +0530
Subject: [PATCH 1/2] Pre-commit tests
---
.../RISCV/xqcilsm-lwmi-swmi-multiple.mir | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir b/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir
index f7206e8ebb7dc..fe2a994f5b1d3 100644
--- a/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir
+++ b/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir
@@ -21,6 +21,8 @@
ret void
}
+ define void @setwmi_no_pair_move_insn_back() { ret void }
+
...
---
name: lwmi
@@ -186,3 +188,21 @@ body: |
SW $x0, $x10, 12 :: (store (s32) into %ir.d, align 4)
PseudoRET
...
+---
+name: setwmi_no_pair_move_insn_back
+body: |
+ bb.0:
+ liveins: $x1, $x2
+ ; CHECK-LABEL: name: setwmi_no_pair_move_insn_back
+ ; CHECK: liveins: $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: SW $x0, $x2, 8 :: (store (s32))
+ ; CHECK-NEXT: SW killed $x1, $x2, 12 :: (store (s32))
+ ; CHECK-NEXT: QC_SETWMI $x0, $x2, 2, 0 :: (store (s32))
+ ; CHECK-NEXT: PseudoRET
+ SW killed $x1, $x2, 12 :: (store (s32), align 4)
+ SW $x0, $x2, 0 :: (store (s32), align 4)
+ SW $x0, $x2, 4 :: (store (s32), align 4)
+ SW $x0, $x2, 8 :: (store (s32), align 4)
+ PseudoRET
+...
>From dfe5299e93aaa66efff7a1e8e76ef6a0a432ddb7 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <svs at qti.qualcomm.com>
Date: Wed, 1 Apr 2026 13:45:32 +0530
Subject: [PATCH 2/2] Move isntruction back if we don't pair
---
llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp | 15 ++++++++++++---
.../CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir | 5 ++---
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
index 6c80735c5ca73..c4ad82408c232 100644
--- a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
@@ -729,24 +729,33 @@ RISCVLoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
}
}
+ // Remember the original position of the instruction we're moving so we can
+ // restore it if we fail to form a pair.
+ MachineBasicBlock::iterator OrigNext = std::next(DeletionPoint);
+
MachineInstr *ToInsert = DeletionPoint->removeFromParent();
MachineBasicBlock &MBB = *InsertionPoint->getParent();
- MachineBasicBlock::iterator First, Second;
+ MachineBasicBlock::iterator First, Second, Moved;
if (!InsertAfter) {
First = MBB.insert(InsertionPoint, ToInsert);
Second = InsertionPoint;
+ Moved = First;
} else {
Second = MBB.insertAfter(InsertionPoint, ToInsert);
First = InsertionPoint;
+ Moved = Second;
}
if (tryConvertToLdStPair(First, Second)) {
LLVM_DEBUG(dbgs() << "Pairing load/store:\n ");
LLVM_DEBUG(prev_nodbg(NextI, MBB.begin())->print(dbgs()));
} else if (!STI->is64Bit() && STI->hasVendorXqcilsm()) {
- // We were unable to form the pair, so use the next non-debug instruction
- // after the first instruction we had wanted to merge.
+ // We were unable to form the pair, so move the instruction back to it's
+ // original place. Point NextI to the next non-debug instruction after the
+ // first instruction we had wanted to merge.
+ MachineInstr *MovedMI = Moved->removeFromParent();
+ MBB.insert(OrigNext, MovedMI);
NextI = next_nodbg(I, E);
}
diff --git a/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir b/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir
index fe2a994f5b1d3..688719b6cb43d 100644
--- a/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir
+++ b/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir
@@ -72,8 +72,8 @@ body: |
; CHECK: liveins: $x10
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $x28 = LW $x10, 0 :: (load (s32))
- ; CHECK-NEXT: $x30 = LW $x10, 4 :: (load (s32))
; CHECK-NEXT: $x29 = LW $x10, 8 :: (load (s32))
+ ; CHECK-NEXT: $x30 = LW $x10, 4 :: (load (s32))
; CHECK-NEXT: $x31 = LW $x10, 12 :: (load (s32))
; CHECK-NEXT: PseudoRET
$x28 = LW $x10, 0 :: (load (s32), align 4)
@@ -196,9 +196,8 @@ body: |
; CHECK-LABEL: name: setwmi_no_pair_move_insn_back
; CHECK: liveins: $x1, $x2
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: SW $x0, $x2, 8 :: (store (s32))
; CHECK-NEXT: SW killed $x1, $x2, 12 :: (store (s32))
- ; CHECK-NEXT: QC_SETWMI $x0, $x2, 2, 0 :: (store (s32))
+ ; CHECK-NEXT: QC_SETWMI $x0, $x2, 3, 0 :: (store (s32))
; CHECK-NEXT: PseudoRET
SW killed $x1, $x2, 12 :: (store (s32), align 4)
SW $x0, $x2, 0 :: (store (s32), align 4)
More information about the llvm-commits
mailing list