diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -1090,7 +1090,6 @@ void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { MachineOperand &DefMO = getOperand(DefIdx); MachineOperand &UseMO = getOperand(UseIdx); - assert(DefMO.isDef() && "DefIdx must be a def operand"); assert(UseMO.isUse() && "UseIdx must be a use operand"); assert(!DefMO.isTied() && "Def is already tied to another use"); assert(!UseMO.isTied() && "Use is already tied to another def"); diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1324,6 +1324,10 @@ // Tied constraint already satisfied? if (SrcReg == DstReg) continue; + // Ignore tied operands where both are source operands. + if (!DstMO.isDef()) { + continue; + } assert(SrcReg && SrcMO.isUse() && "two address instruction invalid"); diff --git a/llvm/test/TableGen/ConstraintChecking4.td b/llvm/test/TableGen/ConstraintChecking4.td --- a/llvm/test/TableGen/ConstraintChecking4.td +++ b/llvm/test/TableGen/ConstraintChecking4.td @@ -2,5 +2,5 @@ include "ConstraintChecking.inc" -// CHECK: [[FILE]]:[[@LINE+1]]:1: error: Output operands '$dest1' and '$dest2' of 'Foo' cannot be tied! -def Foo : TestInstructionWithConstraints<"$dest1 = $dest2">; +// CHECK: [[FILE]]:[[@LINE+1]]:1: error: Operand '$dest1' of 'Foo' cannot have multiple operands tied to it! +def Foo : TestInstructionWithConstraints<"$dest1 = $src1, $dest1 = $src2">; diff --git a/llvm/test/TableGen/ConstraintChecking5.td b/llvm/test/TableGen/ConstraintChecking5.td --- a/llvm/test/TableGen/ConstraintChecking5.td +++ b/llvm/test/TableGen/ConstraintChecking5.td @@ -2,5 +2,5 @@ include "ConstraintChecking.inc" -// CHECK: [[FILE]]:[[@LINE+1]]:1: error: Input operands '$src1' and '$src2' of 'Foo' cannot be tied! -def Foo : TestInstructionWithConstraints<"$src1 = $src2">; +// CHECK: [[FILE]]:[[@LINE+1]]:1: error: Operand '$src1' of 'Foo' cannot have multiple constraints! +def Foo : TestInstructionWithConstraints<"$dest1 = $src1, $dest2 = $src1">; diff --git a/llvm/test/TableGen/ConstraintChecking6.td b/llvm/test/TableGen/ConstraintChecking6.td deleted file mode 100644 --- a/llvm/test/TableGen/ConstraintChecking6.td +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: not llvm-tblgen -gen-asm-writer -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s - -include "ConstraintChecking.inc" - -// CHECK: [[FILE]]:[[@LINE+1]]:1: error: Operand '$dest1' of 'Foo' cannot have multiple operands tied to it! -def Foo : TestInstructionWithConstraints<"$dest1 = $src1, $dest1 = $src2">; diff --git a/llvm/test/TableGen/ConstraintChecking7.td b/llvm/test/TableGen/ConstraintChecking7.td deleted file mode 100644 --- a/llvm/test/TableGen/ConstraintChecking7.td +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: not llvm-tblgen -gen-asm-writer -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s - -include "ConstraintChecking.inc" - -// CHECK: [[FILE]]:[[@LINE+1]]:1: error: Operand '$src1' of 'Foo' cannot have multiple constraints! -def Foo : TestInstructionWithConstraints<"$dest1 = $src1, $dest2 = $src1">; diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -291,16 +291,6 @@ std::pair SrcOp = (FirstIsDest ? RHSOp : LHSOp); StringRef SrcOpName = (FirstIsDest ? RHSOpName : LHSOpName); - // Ensure one operand is a def and the other is a use. - if (DestOp.first >= Ops.NumDefs) - PrintFatalError( - Rec->getLoc(), "Input operands '" + LHSOpName + "' and '" + RHSOpName + - "' of '" + Rec->getName() + "' cannot be tied!"); - if (SrcOp.first < Ops.NumDefs) - PrintFatalError( - Rec->getLoc(), "Output operands '" + LHSOpName + "' and '" + RHSOpName + - "' of '" + Rec->getName() + "' cannot be tied!"); - // The constraint has to go on the operand with higher index, i.e. // the source one. Check there isn't another constraint there // already.