summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-29 23:52:52 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-29 23:52:52 +0000
commitffba07b9270c622edacc773dcfbe1b57c7f4db07 (patch)
tree1648a29f95f78e72565fd026b70f1294f76301cf /llvm/lib/CodeGen
parentf470f08463e5ce749e19441382654140b028283e (diff)
downloadbcm5719-llvm-ffba07b9270c622edacc773dcfbe1b57c7f4db07.tar.gz
bcm5719-llvm-ffba07b9270c622edacc773dcfbe1b57c7f4db07.zip
Verify the order of tied operands in inline asm.
When there are multiple tied use-def pairs on an inline asm instruction, the tied uses must appear in the same order as the defs. It is possible to write an LLVM IR inline asm instruction that breaks this constraint, but there is no reason for a front end to emit the operands out of order. The gnu inline asm syntax specifies tied operands as a single read/write constraint "+r", so ouf of order operands are not possible. llvm-svn: 162878
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 5927838b533..4d09c444945 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -895,6 +895,7 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
// Remember to operand index of the group flags.
SmallVector<unsigned, 8> GroupIdx;
+ unsigned PrevDefGroup = 0;
// Add all of the operand registers to the instruction.
for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
@@ -943,9 +944,20 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
if (InlineAsm::getKind(Flags) == InlineAsm::Kind_RegUse) {
unsigned DefGroup = 0;
if (InlineAsm::isUseOperandTiedToDef(Flags, DefGroup)) {
+ // Check that the def groups are monotonically increasing.
+ // Otherwise, the tied uses and defs won't line up, and
+ // MI::findTiedOperandIdx() will find the wrong operand. This
+ // should be automatically enforced by the front ends when
+ // translating "+" constraints into tied def+use pairs.
+ assert(DefGroup >= PrevDefGroup &&
+ "Tied inline asm operands must be in increasing order.");
+ PrevDefGroup = DefGroup;
+
unsigned DefIdx = GroupIdx[DefGroup] + 1;
unsigned UseIdx = GroupIdx.back() + 1;
for (unsigned j = 0; j != NumVals; ++j) {
+ assert(!MI->getOperand(DefIdx + j).isTied() &&
+ "Def is already tied to another use");
MI->getOperand(DefIdx + j).setIsTied();
MI->getOperand(UseIdx + j).setIsTied();
}
OpenPOWER on IntegriCloud