Don't enforce ordered inline asm operands.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 31 Aug 2012 15:34:59 +0000 (15:34 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 31 Aug 2012 15:34:59 +0000 (15:34 +0000)
I was too optimistic, inline asm can have tied operands that don't
follow the def order.

Fixes PR13742.

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

lib/CodeGen/SelectionDAG/InstrEmitter.cpp
test/CodeGen/X86/inline-asm-tied.ll

index 4d09c444945c775e598255da4011b4359890680e..5399a51557b2ccf15f4bba09cb9de40e4bce528d 100644 (file)
@@ -895,7 +895,6 @@ 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;) {
@@ -944,15 +943,6 @@ 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) {
index 91576fb09ec29f4a91d32d0eba318d9a895dcf00..597236e36281ef89071f160dc276b1b4e2257555 100644 (file)
@@ -19,3 +19,12 @@ entry:
        %1 = load i64* %retval          ; <i64> [#uses=1]
        ret i64 %1
 }
+
+; The tied operands are not necessarily in the same order as the defs.
+; PR13742
+define i64 @swapped(i64 %x, i64 %y) nounwind {
+entry:
+       %x0 = call { i64, i64 } asm "foo", "=r,=r,1,0,~{dirflag},~{fpsr},~{flags}"(i64 %x, i64 %y) nounwind
+        %x1 = extractvalue { i64, i64 } %x0, 0
+        ret i64 %x1
+}