[llvm] 18a0657 - [RISCV] Move unpaired instruction back in RISCVLoadStoreOptimizer (#189912)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 1 20:49:02 PDT 2026


Author: Sudharsan Veeravalli
Date: 2026-04-02T09:18:58+05:30
New Revision: 18a065763d267354bafe1d0a41325f50500d5b29

URL: https://github.com/llvm/llvm-project/commit/18a065763d267354bafe1d0a41325f50500d5b29
DIFF: https://github.com/llvm/llvm-project/commit/18a065763d267354bafe1d0a41325f50500d5b29.diff

LOG: [RISCV] Move unpaired instruction back in RISCVLoadStoreOptimizer (#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.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
    llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi-multiple.mir

Removed: 
    


################################################################################
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 f7206e8ebb7dc..688719b6cb43d 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
@@ -70,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)
@@ -186,3 +188,20 @@ 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 killed $x1, $x2, 12 :: (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)
+    SW $x0, $x2, 4 :: (store (s32), align 4)
+    SW $x0, $x2, 8 :: (store (s32), align 4)
+    PseudoRET
+...


        


More information about the llvm-commits mailing list