[inlineasm] Fix crash when number of matched input constraint operands overflows...
authorDaniil Fukalov <daniil.fukalov@amd.com>
Wed, 25 Oct 2017 12:51:32 +0000 (12:51 +0000)
committerDaniil Fukalov <daniil.fukalov@amd.com>
Wed, 25 Oct 2017 12:51:32 +0000 (12:51 +0000)
In a case when number of output constraint operands that has matched input operands
doesn't fit to signed char, TargetLowering::ParseConstraints() can try to access
ConstraintOperands (that is std::vector) with negative index.

Reviewers: rampitec, arsenm

Differential Review: https://reviews.llvm.org/D39125

llvm-svn: 316574

llvm/include/llvm/IR/InlineAsm.h
llvm/lib/IR/InlineAsm.cpp
llvm/test/CodeGen/AMDGPU/InlineAsmCrash.ll [new file with mode: 0644]

index 59874b0..1519a45 100644 (file)
@@ -101,7 +101,7 @@ public:
     /// input constraint is required to match it (e.g. "0").  The value is the
     /// constraint number that matches this one (for example, if this is
     /// constraint #0 and constraint #4 has the value "0", this will be 4).
-    signed char MatchingInput = -1;
+    int MatchingInput = -1;
 
     /// Code - The constraint code, either the register name (in braces) or the
     /// constraint letter/number.
@@ -128,7 +128,7 @@ public:
     /// input constraint is required to match it (e.g. "0").  The value is the
     /// constraint number that matches this one (for example, if this is
     /// constraint #0 and constraint #4 has the value "0", this will be 4).
-    signed char MatchingInput = -1;
+    int MatchingInput = -1;
 
     /// hasMatchingInput - Return true if this is an output constraint that has
     /// a matching input constraint.
index ad22efd..8667d7a 100644 (file)
@@ -163,6 +163,7 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
           return true;
         // Note that operand #n has a matching input.
         scInfo.MatchingInput = ConstraintsSoFar.size();
+        assert(scInfo.MatchingInput >= 0);
       } else {
         if (ConstraintsSoFar[N].hasMatchingInput() &&
             (size_t)ConstraintsSoFar[N].MatchingInput !=
@@ -170,6 +171,7 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
           return true;
         // Note that operand #n has a matching input.
         ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size();
+        assert(ConstraintsSoFar[N].MatchingInput >= 0);
         }
     } else if (*I == '|') {
       multipleAlternativeIndex++;
diff --git a/llvm/test/CodeGen/AMDGPU/InlineAsmCrash.ll b/llvm/test/CodeGen/AMDGPU/InlineAsmCrash.ll
new file mode 100644 (file)
index 0000000..8ad1cbb
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck %s
+
+; CHECK: ;;#ASMSTART
+; CHECK-NEXT: s_nop 0
+; CHECK-NEXT: ;;#ASMEND
+
+define void @foo(i32* %ptr) {
+  %tmp = tail call { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } asm "s_nop 0", "=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,=v,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65"(i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2)
+  %tmp2 = extractvalue { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } %tmp, 0
+  store i32 %tmp2, i32* %ptr, align 4
+  ret void
+}