[llvm] [PowerPC][CodeGen] Exploit STMW and LMW in 32-bit big-endian mode. (PR #74415)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 3 21:44:11 PST 2024


https://github.com/EsmeYi updated https://github.com/llvm/llvm-project/pull/74415

>From c46a2f6708f72c279aea92eed68b51205824e823 Mon Sep 17 00:00:00 2001
From: esmeyi <esme.yi at ibm.com>
Date: Tue, 26 Dec 2023 01:01:18 -0500
Subject: [PATCH 1/3] Squash commits.

---
 llvm/lib/Target/PowerPC/PPCFrameLowering.cpp  | 104 +++++++++++++++++-
 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp   |  12 +-
 llvm/test/CodeGen/PowerPC/aix-stm-lm-merge.ll |  16 +++
 3 files changed, 123 insertions(+), 9 deletions(-)
 create mode 100644 llvm/test/CodeGen/PowerPC/aix-stm-lm-merge.ll

diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index 245e78641ed654..daedcb643f84b6 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -40,6 +40,12 @@ EnablePEVectorSpills("ppc-enable-pe-vector-spills",
                      cl::desc("Enable spills in prologue to vector registers."),
                      cl::init(false), cl::Hidden);
 
+static cl::opt<bool>
+    EnableLoadStoreMultiple("ppc-enable-load-store-multiple",
+                            cl::desc("Enable load/store multiple (only "
+                                     "support on 32-bit AIX)."),
+                            cl::init(false), cl::Hidden);
+
 static unsigned computeReturnSaveOffset(const PPCSubtarget &STI) {
   if (STI.isAIXABI())
     return STI.isPPC64() ? 16 : 8;
@@ -2399,6 +2405,43 @@ bool PPCFrameLowering::assignCalleeSavedSpillSlots(
   return AllSpilledToReg;
 }
 
+static void findContinuousLoadStore(const MachineFunction *MF,
+                                    ArrayRef<CalleeSavedInfo> CSI,
+                                    Register &MergeFrom) {
+  const MachineFrameInfo &MFI = MF->getFrameInfo();
+  int64_t Offset = MFI.estimateStackSize(*MF);
+  Register LastReg = PPC::R0;
+  for (unsigned I = 0, E = CSI.size(); I + 1 < E; ++I) {
+    Register CurrReg = CSI[I].getReg();
+    Offset += MFI.getObjectOffset(CSI[I].getFrameIdx());
+    if (CurrReg < PPC::R13 || CSI[I].isSpilledToReg() ||
+        CSI[I].getFrameIdx() >= 0 || !isInt<16>(Offset))
+      continue;
+
+    // Check memory operand type.
+    if (MFI.getObjectSize(CSI[I].getFrameIdx()) != 4)
+      continue;
+
+    // Record the first reg that STMW/LMW are going to merge since STMW/LMW save
+    // from rN to r31, where rN >= r13.
+    if (MergeFrom == PPC::R0)
+      MergeFrom = CurrReg;
+
+    // Check continuous store/load.
+    if ((CSI[I].getFrameIdx() - CSI[I + 1].getFrameIdx() != 1) ||
+        (CSI[I + 1].getReg().id() - CurrReg.id() != 1))
+      MergeFrom = PPC::R0;
+
+    LastReg = CSI[I + 1].getReg();
+    if (LastReg >= PPC::R31)
+      break;
+  }
+
+  // Make sure the last register is r31.
+  if (LastReg != PPC::R31)
+    MergeFrom = PPC::R0;
+}
+
 bool PPCFrameLowering::spillCalleeSavedRegisters(
     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
@@ -2407,6 +2450,7 @@ bool PPCFrameLowering::spillCalleeSavedRegisters(
   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
   PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
   bool MustSaveTOC = FI->mustSaveTOC();
+  const MachineFrameInfo &MFI = MF->getFrameInfo();
   DebugLoc DL;
   bool CRSpilled = false;
   MachineInstrBuilder CRMIB;
@@ -2429,6 +2473,10 @@ bool PPCFrameLowering::spillCalleeSavedRegisters(
     }
   }
 
+  Register MergeFrom = PPC::R0;
+  if (EnableLoadStoreMultiple && Subtarget.isAIXABI() && !Subtarget.isPPC64())
+    findContinuousLoadStore(MF, CSI, MergeFrom);
+
   for (const CalleeSavedInfo &I : CSI) {
     Register Reg = I.getReg();
 
@@ -2511,9 +2559,30 @@ bool PPCFrameLowering::spillCalleeSavedRegisters(
         // saved vector registers.
         if (Subtarget.needsSwapsForVSXMemOps() &&
             !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
-          TII.storeRegToStackSlotNoUpd(MBB, MI, Reg, !IsLiveIn,
-                                       I.getFrameIdx(), RC, TRI);
-        else
+          TII.storeRegToStackSlotNoUpd(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(),
+                                       RC, TRI);
+        else if (MergeFrom >= PPC::R13 && MergeFrom < PPC::R31 &&
+                 Reg >= MergeFrom && Reg <= PPC::R31) {
+          if (Reg == MergeFrom) {
+            // Build an STMW instruction.
+            int FrameIdx = I.getFrameIdx();
+            MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(PPC::STMW));
+            MIB.addReg(Reg, getKillRegState(!IsLiveIn));
+            // Add frame reference.
+            MIB.addImm(0).addFrameIndex(FrameIdx);
+            MachineMemOperand *MMO = MF->getMachineMemOperand(
+                MachinePointerInfo::getFixedStack(*MF, FrameIdx),
+                MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
+                MFI.getObjectAlign(FrameIdx));
+            MIB.addMemOperand(MMO);
+            FI->setHasSpills();
+            // Add implicit uses.
+            Register MergeEnd = PPC::R31;
+            for (unsigned I = MergeFrom.id(); I <= MergeEnd.id(); ++I)
+              MIB.addUse(Register(I), RegState::Implicit);
+          } else
+            continue;
+        } else
           TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(), RC,
                                   TRI, Register());
       }
@@ -2600,6 +2669,7 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(
   MachineFunction *MF = MBB.getParent();
   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
   PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
+  const MachineFrameInfo &MFI = MF->getFrameInfo();
   bool MustSaveTOC = FI->mustSaveTOC();
   bool CR2Spilled = false;
   bool CR3Spilled = false;
@@ -2607,6 +2677,10 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(
   unsigned CSIIndex = 0;
   BitVector Restored(TRI->getNumRegs());
 
+  Register MergeFrom = PPC::R0;
+  if (EnableLoadStoreMultiple && Subtarget.isAIXABI() && !Subtarget.isPPC64())
+    findContinuousLoadStore(MF, CSI, MergeFrom);
+
   // Initialize insertion-point logic; we will be restoring in reverse
   // order of spill.
   MachineBasicBlock::iterator I = MI, BeforeI = I;
@@ -2686,7 +2760,29 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(
             !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
           TII.loadRegFromStackSlotNoUpd(MBB, I, Reg, CSI[i].getFrameIdx(), RC,
                                         TRI);
-        else
+        else if (MergeFrom >= PPC::R13 && MergeFrom < PPC::R31 &&
+                 Reg >= MergeFrom && Reg <= PPC::R31) {
+          if (Reg == MergeFrom) {
+            // Build an LMW instruction.
+            int FrameIdx = CSI[i].getFrameIdx();
+            DebugLoc DL;
+            MachineInstrBuilder MIB =
+                BuildMI(MBB, I, DL, TII.get(PPC::LMW), MergeFrom);
+            // Add frame reference.
+            MIB.addImm(0).addFrameIndex(FrameIdx);
+            MachineMemOperand *MMO = MF->getMachineMemOperand(
+                MachinePointerInfo::getFixedStack(*MF, FrameIdx),
+                MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
+                MFI.getObjectAlign(FrameIdx));
+            MIB.addMemOperand(MMO);
+            FI->setHasSpills();
+            // Add implicit defs.
+            Register MergeEnd = PPC::R31;
+            for (unsigned I = MergeFrom.id(); I <= MergeEnd.id(); ++I)
+              MIB.addDef(Register(I), RegState::Implicit);
+          } else
+            continue;
+        } else
           TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), RC, TRI,
                                    Register());
 
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 7d913a77cc7155..21ec25b2e93dd9 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -1673,8 +1673,10 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
 
   // If the instruction is not present in ImmToIdxMap, then it has no immediate
   // form (and must be r+r).
+  // STMW and LMW only have immediate form.
   bool noImmForm = !MI.isInlineAsm() && OpC != TargetOpcode::STACKMAP &&
-                   OpC != TargetOpcode::PATCHPOINT && !ImmToIdxMap.count(OpC);
+                   OpC != TargetOpcode::PATCHPOINT && !ImmToIdxMap.count(OpC) &&
+                   OpC != PPC::STMW && OpC != PPC::LMW;
 
   // Now add the frame object offset to the offset from r1.
   int64_t Offset = MFI.getObjectOffset(FrameIndex);
@@ -1716,10 +1718,10 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
                             isInt<16>(Offset);
   if (TII.isPrefixed(MI.getOpcode()))
     OffsetFitsMnemonic = isInt<34>(Offset);
-  if (!noImmForm && ((OffsetFitsMnemonic &&
-                      ((Offset % offsetMinAlign(MI)) == 0)) ||
-                     OpC == TargetOpcode::STACKMAP ||
-                     OpC == TargetOpcode::PATCHPOINT)) {
+  if (!noImmForm &&
+      ((OffsetFitsMnemonic && ((Offset % offsetMinAlign(MI)) == 0)) ||
+       OpC == TargetOpcode::STACKMAP || OpC == TargetOpcode::PATCHPOINT ||
+       OpC == PPC::STMW || OpC == PPC::LMW)) {
     MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
     return false;
   }
diff --git a/llvm/test/CodeGen/PowerPC/aix-stm-lm-merge.ll b/llvm/test/CodeGen/PowerPC/aix-stm-lm-merge.ll
new file mode 100644
index 00000000000000..9a5d9466ae4596
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-stm-lm-merge.ll
@@ -0,0 +1,16 @@
+; RUN: llc  -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mattr=-altivec \
+; RUN:      -mcpu=pwr4 --ppc-enable-load-store-multiple < %s | FileCheck %s
+
+target triple = "powerpc-ibm-aix7.2.0.0"
+
+define dso_local void @test_simple() #0 {
+entry:
+  call void asm sideeffect "nop", "~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"()
+  ret void
+}
+
+; CHECK:        stmw 16, -64(1)                         # 4-byte Folded Spill
+; CHECK-NEXT:   #APP
+; CHECK-NEXT:   nop
+; CHECK-NEXT:   #NO_APP
+; CHECK-NEXT:   lmw 16, -64(1)                          # 4-byte Folded Reload

>From 5fde37e1813cc1533ac0f981f556be62d73a7b1f Mon Sep 17 00:00:00 2001
From: esmeyi <esme.yi at ibm.com>
Date: Wed, 3 Jan 2024 05:21:53 -0500
Subject: [PATCH 2/3] Address comments.

---
 llvm/lib/Target/PowerPC/PPCFrameLowering.cpp | 138 ++++++++++---------
 1 file changed, 73 insertions(+), 65 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index daedcb643f84b6..fcd36c8e935b30 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -2405,41 +2405,51 @@ bool PPCFrameLowering::assignCalleeSavedSpillSlots(
   return AllSpilledToReg;
 }
 
-static void findContinuousLoadStore(const MachineFunction *MF,
-                                    ArrayRef<CalleeSavedInfo> CSI,
-                                    Register &MergeFrom) {
-  const MachineFrameInfo &MFI = MF->getFrameInfo();
-  int64_t Offset = MFI.estimateStackSize(*MF);
+static bool findConsecutiveLoadStore(const MachineFrameInfo &MFI,
+                                     ArrayRef<CalleeSavedInfo> CSI,
+                                     Register &MergeFrom, int64_t FrameSize) {
   Register LastReg = PPC::R0;
   for (unsigned I = 0, E = CSI.size(); I + 1 < E; ++I) {
     Register CurrReg = CSI[I].getReg();
-    Offset += MFI.getObjectOffset(CSI[I].getFrameIdx());
-    if (CurrReg < PPC::R13 || CSI[I].isSpilledToReg() ||
-        CSI[I].getFrameIdx() >= 0 || !isInt<16>(Offset))
-      continue;
+    if (LastReg >= PPC::R31)
+      break;
 
-    // Check memory operand type.
-    if (MFI.getObjectSize(CSI[I].getFrameIdx()) != 4)
+    if (CurrReg < PPC::R13 || CurrReg >= PPC::R31 || CSI[I].isSpilledToReg())
       continue;
 
-    // Record the first reg that STMW/LMW are going to merge since STMW/LMW save
-    // from rN to r31, where rN >= r13.
-    if (MergeFrom == PPC::R0)
+    assert((CSI[I].getFrameIdx() < 0 &&
+            MFI.getObjectSize(CSI[I].getFrameIdx()) == 4) &&
+           "Register is illegal!");
+
+    if (MergeFrom == PPC::R0) {
+      // STMW/LMW only have the immediate form. The offset must fit in int16
+      // otherwise it will be truncated in
+      // PPCRegisterInfo::eliminateFrameIndex().
+      int64_t Offset = FrameSize + MFI.getObjectOffset(CSI[I].getFrameIdx());
+      if (!isInt<16>(Offset))
+        continue;
+
+      // Record the first GPR that STMW/LMW are going to merge since STMW/LMW
+      // save from rN to r31, where rN >= r13.
       MergeFrom = CurrReg;
+    }
 
-    // Check continuous store/load.
-    if ((CSI[I].getFrameIdx() - CSI[I + 1].getFrameIdx() != 1) ||
-        (CSI[I + 1].getReg().id() - CurrReg.id() != 1))
+    // Check registers are consecutive.
+    if (CSI[I + 1].getReg().id() - CurrReg.id() != 1) {
       MergeFrom = PPC::R0;
+      continue;
+    }
+
+    // Frame indexes must be consecutive.
+    assert((CSI[I].getFrameIdx() - CSI[I + 1].getFrameIdx() == 1) &&
+           "Frame index is illegal!");
 
     LastReg = CSI[I + 1].getReg();
-    if (LastReg >= PPC::R31)
-      break;
   }
 
-  // Make sure the last register is r31.
-  if (LastReg != PPC::R31)
-    MergeFrom = PPC::R0;
+  return (LastReg == PPC::R31 && MergeFrom >= PPC::R13 && MergeFrom < PPC::R31)
+             ? true
+             : false;
 }
 
 bool PPCFrameLowering::spillCalleeSavedRegisters(
@@ -2473,9 +2483,12 @@ bool PPCFrameLowering::spillCalleeSavedRegisters(
     }
   }
 
+  // STMW save from rN to r31, where r13 <= rN < r31.
   Register MergeFrom = PPC::R0;
+  bool UseSTMW = false;
   if (EnableLoadStoreMultiple && Subtarget.isAIXABI() && !Subtarget.isPPC64())
-    findContinuousLoadStore(MF, CSI, MergeFrom);
+    UseSTMW = findConsecutiveLoadStore(MFI, CSI, MergeFrom,
+                                       determineFrameLayout(*MF, true));
 
   for (const CalleeSavedInfo &I : CSI) {
     Register Reg = I.getReg();
@@ -2561,27 +2574,24 @@ bool PPCFrameLowering::spillCalleeSavedRegisters(
             !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
           TII.storeRegToStackSlotNoUpd(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(),
                                        RC, TRI);
-        else if (MergeFrom >= PPC::R13 && MergeFrom < PPC::R31 &&
-                 Reg >= MergeFrom && Reg <= PPC::R31) {
-          if (Reg == MergeFrom) {
-            // Build an STMW instruction.
-            int FrameIdx = I.getFrameIdx();
-            MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(PPC::STMW));
-            MIB.addReg(Reg, getKillRegState(!IsLiveIn));
-            // Add frame reference.
-            MIB.addImm(0).addFrameIndex(FrameIdx);
-            MachineMemOperand *MMO = MF->getMachineMemOperand(
-                MachinePointerInfo::getFixedStack(*MF, FrameIdx),
-                MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
-                MFI.getObjectAlign(FrameIdx));
-            MIB.addMemOperand(MMO);
-            FI->setHasSpills();
-            // Add implicit uses.
-            Register MergeEnd = PPC::R31;
-            for (unsigned I = MergeFrom.id(); I <= MergeEnd.id(); ++I)
-              MIB.addUse(Register(I), RegState::Implicit);
-          } else
+        else if (UseSTMW && Reg >= MergeFrom && Reg <= PPC::R31) {
+          // Consecutive stores where registers are from MergeFrom to r31 will
+          // be merged into a single STMW.
+          if (Reg != MergeFrom)
             continue;
+          int FrameIdx = I.getFrameIdx();
+          MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(PPC::STMW));
+          MIB.addReg(Reg, getKillRegState(!IsLiveIn));
+          MIB.addImm(0).addFrameIndex(FrameIdx);
+          MachineMemOperand *MMO = MF->getMachineMemOperand(
+              MachinePointerInfo::getFixedStack(*MF, FrameIdx),
+              MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
+              MFI.getObjectAlign(FrameIdx));
+          MIB.addMemOperand(MMO);
+          FI->setHasSpills();
+          Register MergeEnd = PPC::R31;
+          for (unsigned I = MergeFrom.id(); I <= MergeEnd.id(); ++I)
+            MIB.addUse(Register(I), RegState::Implicit);
         } else
           TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(), RC,
                                   TRI, Register());
@@ -2678,8 +2688,10 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(
   BitVector Restored(TRI->getNumRegs());
 
   Register MergeFrom = PPC::R0;
+  bool UseLMW = false;
   if (EnableLoadStoreMultiple && Subtarget.isAIXABI() && !Subtarget.isPPC64())
-    findContinuousLoadStore(MF, CSI, MergeFrom);
+    UseLMW = findConsecutiveLoadStore(MFI, CSI, MergeFrom,
+                                      determineFrameLayout(*MF, true));
 
   // Initialize insertion-point logic; we will be restoring in reverse
   // order of spill.
@@ -2760,28 +2772,24 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(
             !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
           TII.loadRegFromStackSlotNoUpd(MBB, I, Reg, CSI[i].getFrameIdx(), RC,
                                         TRI);
-        else if (MergeFrom >= PPC::R13 && MergeFrom < PPC::R31 &&
-                 Reg >= MergeFrom && Reg <= PPC::R31) {
-          if (Reg == MergeFrom) {
-            // Build an LMW instruction.
-            int FrameIdx = CSI[i].getFrameIdx();
-            DebugLoc DL;
-            MachineInstrBuilder MIB =
-                BuildMI(MBB, I, DL, TII.get(PPC::LMW), MergeFrom);
-            // Add frame reference.
-            MIB.addImm(0).addFrameIndex(FrameIdx);
-            MachineMemOperand *MMO = MF->getMachineMemOperand(
-                MachinePointerInfo::getFixedStack(*MF, FrameIdx),
-                MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
-                MFI.getObjectAlign(FrameIdx));
-            MIB.addMemOperand(MMO);
-            FI->setHasSpills();
-            // Add implicit defs.
-            Register MergeEnd = PPC::R31;
-            for (unsigned I = MergeFrom.id(); I <= MergeEnd.id(); ++I)
-              MIB.addDef(Register(I), RegState::Implicit);
-          } else
+        else if (UseLMW && Reg >= MergeFrom && Reg <= PPC::R31) {
+          // Consecutive loads where registers are from MergeFrom to r31 will
+          // be merged into a single LMW.
+          if (Reg != MergeFrom)
             continue;
+          int FrameIdx = CSI[i].getFrameIdx();
+          DebugLoc DL;
+          MachineInstrBuilder MIB =
+              BuildMI(MBB, I, DL, TII.get(PPC::LMW), MergeFrom);
+          MIB.addImm(0).addFrameIndex(FrameIdx);
+          MachineMemOperand *MMO = MF->getMachineMemOperand(
+              MachinePointerInfo::getFixedStack(*MF, FrameIdx),
+              MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
+              MFI.getObjectAlign(FrameIdx));
+          MIB.addMemOperand(MMO);
+          FI->setHasSpills();
+          for (unsigned I = MergeFrom.id(); I <= Register(PPC::R31).id(); ++I)
+            MIB.addDef(Register(I), RegState::Implicit);
         } else
           TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), RC, TRI,
                                    Register());

>From f17ec663ee8ce16d2c5a82851951a360e6539a0a Mon Sep 17 00:00:00 2001
From: esmeyi <esme.yi at ibm.com>
Date: Thu, 4 Jan 2024 00:41:54 -0500
Subject: [PATCH 3/3] declare variable_ops for stmw/lmw in td.

---
 llvm/lib/Target/PowerPC/PPCFrameLowering.cpp | 3 +--
 llvm/lib/Target/PowerPC/PPCInstrInfo.td      | 4 ++--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index fcd36c8e935b30..84ca7c508c8303 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -2589,8 +2589,7 @@ bool PPCFrameLowering::spillCalleeSavedRegisters(
               MFI.getObjectAlign(FrameIdx));
           MIB.addMemOperand(MMO);
           FI->setHasSpills();
-          Register MergeEnd = PPC::R31;
-          for (unsigned I = MergeFrom.id(); I <= MergeEnd.id(); ++I)
+          for (unsigned I = MergeFrom.id(); I <= Register(PPC::R31).id(); ++I)
             MIB.addUse(Register(I), RegState::Implicit);
         } else
           TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(), RC,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index b1601739fd4569..d4487de6ffaea3 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2084,7 +2084,7 @@ def LFIWZX : XForm_25_memOp<31, 887, (outs f8rc:$RST), (ins (memrr $RA, $RB):$ad
 
 // Load Multiple
 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
-def LMW : DForm_1<46, (outs gprc:$RST), (ins (memri $D, $RA):$src),
+def LMW : DForm_1<46, (outs gprc:$RST), (ins (memri $D, $RA):$src, variable_ops),
                   "lmw $RST, $src", IIC_LdStLMW, []>;
 
 //===----------------------------------------------------------------------===//
@@ -2239,7 +2239,7 @@ def : Pat<(pre_store f64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
 
 // Store Multiple
 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
-def STMW : DForm_1<47, (outs), (ins gprc:$RST, (memri $D, $RA):$dst),
+def STMW : DForm_1<47, (outs), (ins gprc:$RST, (memri $D, $RA):$dst, variable_ops),
                    "stmw $RST, $dst", IIC_LdStLMW, []>;
 
 def SYNC : XForm_24_sync<31, 598, (outs), (ins u2imm:$L),



More information about the llvm-commits mailing list