diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index b9ca0c51d76f..25035fdd59d4 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -992,15 +992,34 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { case MachineOperand::MO_FrameIndex: if (LiveStks && LiveStks->hasInterval(MO->getIndex()) && LiveInts && !LiveInts->isNotInMIMap(MI)) { - LiveInterval &LI = LiveStks->getInterval(MO->getIndex()); + int FI = MO->getIndex(); + LiveInterval &LI = LiveStks->getInterval(FI); SlotIndex Idx = LiveInts->getInstructionIndex(MI); - // For a memory-to-memory move, we don't know if MI is using - // this frame index for loading or storing, so check for - // liveness at reg-slot only in the simple load case. bool stores = MI->mayStore(); - bool simpleLoad = (MI->mayLoad() && !stores); - if (simpleLoad && !LI.liveAt(Idx.getRegSlot(true))) { + bool loads = MI->mayLoad(); + // For a memory-to-memory move, we need to check if the frame + // index is used for storing or loading, by inspecting the + // memory operands. + if (stores && loads) { + for (auto *MMO : MI->memoperands()) { + const PseudoSourceValue *PSV = MMO->getPseudoValue(); + if (PSV == nullptr) continue; + const FixedStackPseudoSourceValue *Value = + dyn_cast(PSV); + if (Value == nullptr) continue; + if (Value->getFrameIndex() != FI) continue; + + if (MMO->isStore()) + loads = false; + else + stores = false; + break; + } + if (loads == stores) + report("Missing fixed stack memoperand.", MI); + } + if (loads && !LI.liveAt(Idx.getRegSlot(true))) { report("Instruction loads from dead spill slot", MO, MONum); errs() << "Live stack: " << LI << '\n'; } diff --git a/llvm/test/CodeGen/SystemZ/spill-01.ll b/llvm/test/CodeGen/SystemZ/spill-01.ll index a59c06f192b6..9be4420fd839 100644 --- a/llvm/test/CodeGen/SystemZ/spill-01.ll +++ b/llvm/test/CodeGen/SystemZ/spill-01.ll @@ -1,7 +1,7 @@ ; Test spilling using MVC. The tests here assume z10 register pressure, ; without the high words being available. ; -; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -verify-machineinstrs | FileCheck %s declare void @foo()