[MachineVerifier] Analyze MachineMemOperands for mem-to-mem moves.
authorJonas Paulsson <paulsson@linux.vnet.ibm.com>
Thu, 29 Oct 2015 08:28:35 +0000 (08:28 +0000)
committerJonas Paulsson <paulsson@linux.vnet.ibm.com>
Thu, 29 Oct 2015 08:28:35 +0000 (08:28 +0000)
Since the verifier will give false reports if it incorrectly thinks MI is
loading or storing using an FI, it is necessary to scan memoperands and
find out how the FI is used in the instruction. This should be relatively
rare.

Needed to make CodeGen/SystemZ/spill-01.ll pass, which now runs with this flag.

Reviewed by Quentin Colombet.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251620 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MachineVerifier.cpp
test/CodeGen/SystemZ/spill-01.ll

index b9ca0c51d76feb5d813bf4444e562ec2731be0e1..25035fdd59d4b4ebca96442326e9bc8fe728a8df 100644 (file)
@@ -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<FixedStackPseudoSourceValue>(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';
       }
index a59c06f192b62ac87c508c0d1df93f71f5c9cbac..9be4420fd8394526024fe7f105bf9a33c8968c1a 100644 (file)
@@ -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()