Fix pr3954.  The register scavenger asserts for inline assembly with
register destinations that are tied to source operands.  The
TargetInstrDescr::findTiedToSrcOperand method silently fails for inline
assembly.  The existing MachineInstr::isRegReDefinedByTwoAddr was very
close to doing what is needed, so this revision makes a few changes to
that method and also renames it to isRegTiedToUseOperand (for consistency
with the very similar isRegTiedToDefOperand and because it handles both
two-address instructions and inline assembly with tied registers).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68714 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index ade8683..d3b2e9a 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -690,12 +690,14 @@
   return -1;
 }
   
-/// isRegReDefinedByTwoAddr - Given the index of a register operand,
-/// check if the register def is a re-definition due to two addr elimination.
-bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{
+/// isRegTiedToUseOperand - Given the index of a register def operand,
+/// check if the register def is tied to a source operand, due to either
+/// two-address elimination or inline assembly constraints. Returns the
+/// first tied use operand index by reference is UseOpIdx is not null.
+bool MachineInstr::isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx){
   if (getOpcode() == TargetInstrInfo::INLINEASM) {
-    assert(DefIdx >= 2);
-    const MachineOperand &MO = getOperand(DefIdx);
+    assert(DefOpIdx >= 2);
+    const MachineOperand &MO = getOperand(DefOpIdx);
     if (!MO.isReg() || !MO.isDef())
       return false;
     // Determine the actual operand no corresponding to this index.
@@ -705,7 +707,7 @@
       assert(FMO.isImm());
       // Skip over this def.
       i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
-      if (i > DefIdx)
+      if (i > DefOpIdx)
         break;
       ++DefNo;
     }
@@ -717,18 +719,24 @@
         continue;
       unsigned Idx;
       if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) && 
-          Idx == DefNo)
+          Idx == DefNo) {
+        if (UseOpIdx)
+          *UseOpIdx = (unsigned)i + 1;
         return true;
+      }
     }
   }
 
-  assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!");
+  assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!");
   const TargetInstrDesc &TID = getDesc();
   for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = getOperand(i);
     if (MO.isReg() && MO.isUse() &&
-        TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefIdx)
+        TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefOpIdx) {
+      if (UseOpIdx)
+        *UseOpIdx = (unsigned)i;
       return true;
+    }
   }
   return false;
 }