Verify the tied operand flags.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 29 Aug 2012 00:38:03 +0000 (00:38 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 29 Aug 2012 00:38:03 +0000 (00:38 +0000)
WHen running with -verify-machineinstrs, check that tied operands come
in matching use/def pairs, and that they are consistent with MCInstrDesc
when it applies.

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

lib/CodeGen/MachineVerifier.cpp

index 3ed5c44b068b01aae104295ca9c9e13f1d2f8610..4a766b328c5d3f7906d348023b3ad240ff4c057d 100644 (file)
@@ -703,6 +703,35 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
         << MI->getNumExplicitOperands() << " given.\n";
   }
 
+  // Check the tied operands.
+  SmallVector<unsigned, 4> TiedDefs;
+  SmallVector<unsigned, 4> TiedUses;
+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+    const MachineOperand &MO = MI->getOperand(i);
+    if (!MO.isReg() || !MO.isTied())
+      continue;
+    if (MO.isDef()) {
+      TiedDefs.push_back(i);
+      continue;
+    }
+    TiedUses.push_back(i);
+    if (TiedDefs.size() < TiedUses.size()) {
+      report("No tied def for tied use", &MO, i);
+      break;
+    }
+    if (i >= MCID.getNumOperands())
+      continue;
+    int DefIdx = MCID.getOperandConstraint(i, MCOI::TIED_TO);
+    if (unsigned(DefIdx) != TiedDefs[TiedUses.size() - 1]) {
+      report("Tied def doesn't match MCInstrDesc", &MO, i);
+      *OS << "Descriptor says tied def should be operand " << DefIdx << ".\n";
+    }
+  }
+  if (TiedDefs.size() > TiedUses.size()) {
+    unsigned i = TiedDefs[TiedUses.size() - 1];
+    report("No tied use for tied def", &MI->getOperand(i), i);
+  }
+
   // Check the MachineMemOperands for basic consistency.
   for (MachineInstr::mmo_iterator I = MI->memoperands_begin(),
        E = MI->memoperands_end(); I != E; ++I) {
@@ -758,6 +787,14 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
       if (MO->isImplicit())
         report("Explicit operand marked as implicit", MO, MONum);
     }
+
+    if (MCID.getOperandConstraint(MONum, MCOI::TIED_TO) != -1) {
+      if (!MO->isReg())
+        report("Tied use must be a register", MO, MONum);
+      else if (!MO->isTied())
+        report("Operand should be tied", MO, MONum);
+    } else if (MO->isReg() && MO->isTied())
+      report("Explicit operand should not be tied", MO, MONum);
   } else {
     // ARM adds %reg0 operands to indicate predicates. We'll allow that.
     if (MO->isReg() && !MO->isImplicit() && !MI->isVariadic() && MO->getReg())