r213916 - clang-cl: Merge adjacent single-line __asm blocks

Ehsan Akhgari ehsan.akhgari at gmail.com
Thu Jul 24 19:27:14 PDT 2014


Author: ehsan
Date: Thu Jul 24 21:27:14 2014
New Revision: 213916

URL: http://llvm.org/viewvc/llvm-project?rev=213916&view=rev
Log:
clang-cl: Merge adjacent single-line __asm blocks

Summary:
This patch extends the __asm parser to make it keep parsing input tokens
as inline assembly if a single-line __asm line is followed by another line
starting with __asm too.  It also makes sure that we correctly keep
matching braces in such situations by separating the notions of how many
braces we are matching and whether we are in single-line asm block mode.

Reviewers: rnk

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D4598

Modified:
    cfe/trunk/lib/Parse/ParseStmtAsm.cpp
    cfe/trunk/test/CodeGen/ms-inline-asm.c
    cfe/trunk/test/CodeGen/ms-inline-asm.cpp
    cfe/trunk/test/Parser/ms-inline-asm.c
    cfe/trunk/test/Sema/ms-inline-asm.c

Modified: cfe/trunk/lib/Parse/ParseStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmtAsm.cpp?rev=213916&r1=213915&r2=213916&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmtAsm.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmtAsm.cpp Thu Jul 24 21:27:14 2014
@@ -322,6 +322,7 @@ StmtResult Parser::ParseMicrosoftAsmStat
   SourceLocation EndLoc = AsmLoc;
   SmallVector<Token, 4> AsmToks;
 
+  bool SingleLineMode = true;
   unsigned BraceNesting = 0;
   unsigned short savedBraceCount = BraceCount;
   bool InAsmComment = false;
@@ -333,6 +334,7 @@ StmtResult Parser::ParseMicrosoftAsmStat
 
   if (Tok.is(tok::l_brace)) {
     // Braced inline asm: consume the opening brace.
+    SingleLineMode = false;
     BraceNesting = 1;
     EndLoc = ConsumeBrace();
     LBraceLocs.push_back(EndLoc);
@@ -364,30 +366,39 @@ StmtResult Parser::ParseMicrosoftAsmStat
     } else if (!InAsmComment && Tok.is(tok::semi)) {
       // A semicolon in an asm is the start of a comment.
       InAsmComment = true;
-      if (BraceNesting) {
+      if (!SingleLineMode) {
         // Compute which line the comment is on.
         std::pair<FileID, unsigned> ExpSemiLoc =
             SrcMgr.getDecomposedExpansionLoc(TokLoc);
         FID = ExpSemiLoc.first;
         LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
       }
-    } else if (!BraceNesting || InAsmComment) {
+    } else if (SingleLineMode || InAsmComment) {
       // If end-of-line is significant, check whether this token is on a
       // new line.
       std::pair<FileID, unsigned> ExpLoc =
           SrcMgr.getDecomposedExpansionLoc(TokLoc);
       if (ExpLoc.first != FID ||
           SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
-        // If this is a single-line __asm, we're done.
-        if (!BraceNesting)
+        // If this is a single-line __asm, we're done, except if the next
+        // line begins with an __asm too, in which case we finish a comment
+        // if needed and then keep processing the next line as a single
+        // line __asm.
+        bool isAsm = Tok.is(tok::kw_asm);
+        if (SingleLineMode && !isAsm)
           break;
         // We're no longer in a comment.
         InAsmComment = false;
+        if (isAsm) {
+          LineNo = SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second);
+          SkippedStartOfLine = Tok.isAtStartOfLine();
+        }
       } else if (!InAsmComment && Tok.is(tok::r_brace)) {
-        // Single-line asm always ends when a closing brace is seen.
-        // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
-        // does MSVC do here?
-        break;
+        // In MSVC mode, braces only participate in brace matching and
+        // separating the asm statements.  This is an intentional
+        // departure from the Apple gcc behavior.
+        if (!BraceNesting)
+          break;
       }
     }
     if (!InAsmComment && BraceNesting && Tok.is(tok::r_brace) &&
@@ -398,7 +409,7 @@ StmtResult Parser::ParseMicrosoftAsmStat
       BraceNesting--;
       // Finish if all of the opened braces in the inline asm section were
       // consumed.
-      if (BraceNesting == 0)
+      if (BraceNesting == 0 && !SingleLineMode)
         break;
       else {
         LBraceLocs.pop_back();

Modified: cfe/trunk/test/CodeGen/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm.c?rev=213916&r1=213915&r2=213916&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-inline-asm.c (original)
+++ cfe/trunk/test/CodeGen/ms-inline-asm.c Thu Jul 24 21:27:14 2014
@@ -10,9 +10,7 @@ void t1() {
 
 void t2() {
 // CHECK: @t2
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
 // CHECK: ret void
   __asm nop
   __asm nop
@@ -28,8 +26,7 @@ void t3() {
 
 void t4(void) {
 // CHECK: @t4
-// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: ret void
   __asm mov ebx, eax
   __asm mov ecx, ebx
@@ -69,9 +66,7 @@ int t8() {
   __asm int 4
   return 10;
 // CHECK: t8
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "int $$4\0A\09int $$4", "~{dirflag},~{fpsr},~{flags}"()
 // CHECK: ret i32 10
 }
 
@@ -126,8 +121,7 @@ void t13() {
   __asm movzx eax, i
   __asm movzx eax, j
 // CHECK: t13
-// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0\0A\09movzx eax, word ptr $1", "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
 }
 
 void t14() {
@@ -145,14 +139,15 @@ void t14() {
 
 int gvar = 10;
 void t15() {
+// CHECK: t15
   int lvar = 10;
   __asm mov eax, lvar        ; eax = 10
+// CHECK: mov eax, dword ptr $0
   __asm mov eax, offset lvar ; eax = address of lvar
+// CHECK: mov eax, $1
   __asm mov eax, offset gvar ; eax = address of gvar
-// CHECK: t15
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @{{.*}})
+// CHECK: mov eax, $2
+// CHECK: "*m,r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}})
 }
 
 void t16() {
@@ -163,50 +158,52 @@ void t16() {
 }
 
 void t17() {
+// CHECK: t17
   __asm _emit 0x4A
+// CHECK: .byte 0x4A
   __asm _emit 0x43
+// CHECK: .byte 0x43
   __asm _emit 0x4B
+// CHECK: .byte 0x4B
   __asm _EMIT 0x4B
-// CHECK: t17
-// CHECK:  call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK:  call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK:  call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK:  call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: .byte 0x4B
+// CHECK:  "~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t20() {
+// CHECK: t20
   char bar;
   int foo;
   char _bar[2];
   int _foo[4];
 
   __asm mov eax, LENGTH foo
+// CHECK: mov eax, $$1
   __asm mov eax, LENGTH bar
+// CHECK: mov eax, $$1
   __asm mov eax, LENGTH _foo
+// CHECK: mov eax, $$4
   __asm mov eax, LENGTH _bar
-// CHECK: t20
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$2
 
   __asm mov eax, TYPE foo
+// CHECK: mov eax, $$4
   __asm mov eax, TYPE bar
+// CHECK: mov eax, $$1
   __asm mov eax, TYPE _foo
+// CHECK: mov eax, $$4
   __asm mov eax, TYPE _bar
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$1
 
   __asm mov eax, SIZE foo
+// CHECK: mov eax, $$4
   __asm mov eax, SIZE bar
+// CHECK: mov eax, $$1
   __asm mov eax, SIZE _foo
+// CHECK: mov eax, $$16
   __asm mov eax, SIZE _bar
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$2
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t21() {
@@ -253,34 +250,35 @@ void t24() {
 }
 
 void t25() {
+// CHECK: t25
   __asm mov eax, 0ffffffffh
+// CHECK: mov eax, $$4294967295
   __asm mov eax, 0fh
+// CHECK: mov eax, $$15
   __asm mov eax, 0a2h
+// CHECK: mov eax, $$162
   __asm mov eax, 0xa2h
+// CHECK: mov eax, $$0xa2h
   __asm mov eax, 0xa2
-// CHECK: t25
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967295", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$15", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$162", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$0xa2
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t26() {
+// CHECK: t26
   __asm pushad
+// CHECK: pushad
   __asm mov eax, 0
+// CHECK: mov eax, $$0
   __asm __emit 0fh
+// CHECK: .byte 0fh
   __asm __emit 0a2h
+// CHECK: .byte 0a2h
   __asm __EMIT 0a2h
+// CHECK: .byte 0a2h
   __asm popad
-// FIXME: These all need to be merged into the same asm blob.
-// CHECK: t26
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: popad
+// CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t27() {
@@ -290,160 +288,171 @@ void t27() {
 }
 
 void t28() {
+// CHECK: t28
   __asm align 8
+// CHECK: .align 3
   __asm align 16;
+// CHECK: .align 4
   __asm align 128;
+// CHECK: .align 7
   __asm ALIGN 256;
-// CHECK: t28
-// CHECK: call void asm sideeffect inteldialect ".align 3", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".align 4", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".align 7", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".align 8", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: .align 8
+// CHECK: "~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t29() {
+// CHECK: t29
   int arr[2] = {0, 0};
   int olen = 0, osize = 0, otype = 0;
   __asm mov olen, LENGTH arr
+// CHECK: mov dword ptr $0, $$2
   __asm mov osize, SIZE arr
+// CHECK: mov dword ptr $1, $$8
   __asm mov otype, TYPE arr
-// CHECK: t29
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$2", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$8", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$4", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: mov dword ptr $2, $$4
+// CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
 }
 
 int results[2] = {13, 37};
 int *t30()
+// CHECK: t30
 {
   int *res;
   __asm lea edi, results
+// CHECK: lea edi, dword ptr $1
   __asm mov res, edi
+// CHECK: mov dword ptr $0, edi
   return res;
-// CHECK: t30
-// CHECK: call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}})
+// CHECK: "=*m,*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}, [2 x i32]* @{{.*}})
 }
 
 void t31() {
+// CHECK: t31
   __asm pushad
+// CHECK: pushad
   __asm popad
-// CHECK: t31
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: popad
+// CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t32() {
+// CHECK: t32
   int i;
   __asm mov eax, i
+// CHECK: mov eax, dword ptr $0
   __asm mov eax, dword ptr i
+// CHECK: mov eax, dword ptr $1
   __asm mov ax, word ptr i
+// CHECK: mov ax, word ptr $2
   __asm mov al, byte ptr i
-// CHECK: t32
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: mov al, byte ptr $3
+// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
 }
 
 void t33() {
+// CHECK: t33
   int i;
   __asm mov eax, [i]
+// CHECK: mov eax, dword ptr $0
   __asm mov eax, dword ptr [i]
+// CHECK: mov eax, dword ptr $1
   __asm mov ax, word ptr [i]
+// CHECK: mov ax, word ptr $2
   __asm mov al, byte ptr [i]
-// CHECK: t33
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: mov al, byte ptr $3
+// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
 }
 
 void t34() {
+// CHECK: t34
   __asm prefetchnta 64[eax]
+// CHECK: prefetchnta $$64[eax]
   __asm mov eax, dword ptr 4[eax]
-// CHECK: t34
-// CHECK: call void asm sideeffect inteldialect "prefetchnta $$64[eax]", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4[eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, dword ptr $$4[eax]
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t35() {
+// CHECK: t35
   __asm prefetchnta [eax + (200*64)]
+// CHECK: prefetchnta [eax + ($$200*$$64)]
   __asm mov eax, dword ptr [eax + (200*64)]
-// CHECK: t35
-// CHECK: call void asm sideeffect inteldialect "prefetchnta [eax + ($$200*$$64)]", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [eax + ($$200*$$64)]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, dword ptr [eax + ($$200*$$64)]
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t36() {
-  int arr[4];
-  __asm mov eax, 4[arr]
-  __asm mov eax, 4[arr + 4]
-  __asm mov eax, 8[arr + 4 + 32*2 - 4]
-  __asm mov eax, 12[4 + arr]
-  __asm mov eax, 4[4 + arr + 4]
-  __asm mov eax, 4[64 + arr + (2*32)]
-  __asm mov eax, 4[64 + arr - 2*32]
-  __asm mov eax, [arr + 4]
-  __asm mov eax, [arr + 4 + 32*2 - 4]
-  __asm mov eax, [4 + arr]
-  __asm mov eax, [4 + arr + 4]
-  __asm mov eax, [64 + arr + (2*32)]
-  __asm mov eax, [64 + arr - 2*32]
 // CHECK: t36
+  int arr[4];
+  // Work around PR20368: These should be single line blocks
+  __asm { mov eax, 4[arr] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 4[arr + 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 8[arr + 4 + 32*2 - 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 12[4 + arr] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 4[4 + arr + 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 4[64 + arr + (2*32)] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 4[64 + arr - 2*32] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, [arr + 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, [arr + 4 + 32*2 - 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, [4 + arr] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, [4 + arr + 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, [64 + arr + (2*32)] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, [64 + arr - 2*32] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
 }
 
 void t37() {
+// CHECK: t37
   __asm mov eax, 4 + 8
+// CHECK: mov eax, $$12
   __asm mov eax, 4 + 8 * 16
+// CHECK: mov eax, $$132
   __asm mov eax, -4 + 8 * 16
+// CHECK: mov eax, $$124
   __asm mov eax, (4 + 4) * 16
+// CHECK: mov eax, $$128
   __asm mov eax, 4 + 8 * -16
+// CHECK: mov eax, $$4294967172
   __asm mov eax, 4 + 16 / -8
+// CHECK: mov eax, $$2
   __asm mov eax, (16 + 16) / -8
+// CHECK: mov eax, $$4294967292
   __asm mov eax, ~15
-// CHECK: t37
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$12", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$132", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$124", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$128", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967172", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967292", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967280", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$4294967280
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t38() {
-  int arr[4];
-  __asm mov eax, 4+4[arr]
-  __asm mov eax, (4+4)[arr + 4]
-  __asm mov eax, 8*2[arr + 4 + 32*2 - 4]
-  __asm mov eax, 12+20[4 + arr]
-  __asm mov eax, 4*16+4[4 + arr + 4]
-  __asm mov eax, 4*4[64 + arr + (2*32)]
-  __asm mov eax, 4*(4-2)[64 + arr - 2*32]
-  __asm mov eax, 32*(4-2)[arr - 2*32]
 // CHECK: t38
+  int arr[4];
+  // Work around PR20368: These should be single line blocks
+  __asm { mov eax, 4+4[arr] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, (4+4)[arr + 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 8*2[arr + 4 + 32*2 - 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 12+20[4 + arr] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 4*16+4[4 + arr + 4] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 4*4[64 + arr + (2*32)] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 4*(4-2)[64 + arr - 2*32] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+  __asm { mov eax, 32*(4-2)[arr - 2*32] }
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
 }
 
@@ -459,38 +468,39 @@ typedef struct {
 } A;
 
 void t39() {
+// CHECK-LABEL: define void @t39
   __asm mov eax, [eax].A.b
+// CHECK: mov eax, [eax].4
   __asm mov eax, [eax] A.b
+// CHECK: mov eax, [eax] .4
   __asm mov eax, fs:[0] A.b
-  // CHECK-LABEL: define void @t39
-  // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-  // CHECK: call void asm sideeffect inteldialect "mov eax, [eax] .4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-  // CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0] .4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, fs:[$$0] .4
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t40(float a) {
+// CHECK-LABEL: define void @t40
   int i;
   __asm fld a
+// CHECK: fld dword ptr $1
   __asm fistp i
-  // CHECK-LABEL: define void @t40
-  // CHECK: call void asm sideeffect inteldialect "fld dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(float* {{.*}})
-  // CHECK: call void asm sideeffect inteldialect "fistp dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* {{.*}})
+// CHECK: fistp dword ptr $0
+// CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, float* %{{.*}})
 }
 
 void t41(unsigned short a) {
+// CHECK-LABEL: define void @t41(i16 zeroext %a)
   __asm mov cs, a;
+// CHECK: mov cs, word ptr $0
   __asm mov ds, a;
+// CHECK: mov ds, word ptr $1
   __asm mov es, a;
+// CHECK: mov es, word ptr $2
   __asm mov fs, a;
+// CHECK: mov fs, word ptr $3
   __asm mov gs, a;
+// CHECK: mov gs, word ptr $4
   __asm mov ss, a;
-  // CHECK-LABEL: define void @t41(i16 zeroext %a)
-  // CHECK: [[T41_A_ADDR:%.+]] = alloca i16
-  // CHECK: store i16 %a, i16* [[T41_A_ADDR]]
-  // CHECK: call void asm sideeffect inteldialect "mov cs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
-  // CHECK: call void asm sideeffect inteldialect "mov ds, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
-  // CHECK: call void asm sideeffect inteldialect "mov es, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
-  // CHECK: call void asm sideeffect inteldialect "mov fs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
-  // CHECK: call void asm sideeffect inteldialect "mov gs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
-  // CHECK: call void asm sideeffect inteldialect "mov ss, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+// CHECK: mov ss, word ptr $5
+// CHECK: "*m,*m,*m,*m,*m,*m,~{dirflag},~{fpsr},~{flags}"(i16* %a.addr, i16* %a.addr, i16* %a.addr, i16* %a.addr, i16* %a.addr, i16* %a.addr)
 }

Modified: cfe/trunk/test/CodeGen/ms-inline-asm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm.cpp?rev=213916&r1=213915&r2=213916&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-inline-asm.cpp (original)
+++ cfe/trunk/test/CodeGen/ms-inline-asm.cpp Thu Jul 24 21:27:14 2014
@@ -22,11 +22,7 @@ void t1() {
   __asm mov eax, dword ptr [Foo :: ptr]
   __asm mov eax, dword ptr [Foo :: ptr]
 // CHECK: @_Z2t1v
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0\0A\09mov eax, dword ptr $1\0A\09mov eax, dword ptr $2\0A\09mov eax, dword ptr $3\0A\09mov eax, dword ptr $4", "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE)
 }
 
 int gvar = 10;
@@ -35,38 +31,26 @@ void t2() {
   __asm mov eax, offset Foo::ptr
   __asm mov eax, offset Foo::Bar::ptr
 // CHECK: t2
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0\0A\09mov eax, $1", "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE)
 }
 
 // CHECK-LABEL: define void @_Z2t3v()
 void t3() {
   __asm mov eax, LENGTH Foo::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, LENGTH Foo::Bar::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, LENGTH Foo::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, LENGTH Foo::Bar::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 
   __asm mov eax, TYPE Foo::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, TYPE Foo::Bar::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, TYPE Foo::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, TYPE Foo::Bar::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 
   __asm mov eax, SIZE Foo::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, SIZE Foo::Bar::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, SIZE Foo::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
   __asm mov eax, SIZE Foo::Bar::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$2\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$16\0A\09mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 
 }
 
@@ -82,9 +66,8 @@ void T4::test() {
 // CHECK: [[THIS:%.*]] = load [[T4]]** [[T0]]
 // CHECK: [[X:%.*]] = getelementptr inbounds [[T4]]* [[THIS]], i32 0, i32 0
   __asm mov eax, x;
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
   __asm mov y, eax;
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE, i32* %x)
 }
 
 template <class T> struct T5 {
@@ -97,11 +80,9 @@ void test5() {
   // CHECK: [[Y:%.*]] = alloca i32
   int x, y;
   __asm push y
-  // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
   __asm call T5<int>::create<float>
-  // CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(i32 (float)* @_ZN2T5IiE6createIfEEiT_)
   __asm mov x, eax
-  // CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
+  // CHECK: call void asm sideeffect inteldialect "push dword ptr $0\0A\09call $2\0A\09mov dword ptr $1, eax", "=*m,=*m,r,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_)
 }
 
 // Just verify this doesn't emit an error.

Modified: cfe/trunk/test/Parser/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/ms-inline-asm.c?rev=213916&r1=213915&r2=213916&view=diff
==============================================================================
--- cfe/trunk/test/Parser/ms-inline-asm.c (original)
+++ cfe/trunk/test/Parser/ms-inline-asm.c Thu Jul 24 21:27:14 2014
@@ -50,4 +50,4 @@ void t11() {
 }
 int t_fail() { // expected-note {{to match this}}
   __asm 
-  __asm { // expected-error 3 {{expected}} expected-note {{to match this}}
+  __asm { // expected-error 2 {{expected}} expected-note {{to match this}}

Modified: cfe/trunk/test/Sema/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms-inline-asm.c?rev=213916&r1=213915&r2=213916&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ms-inline-asm.c (original)
+++ cfe/trunk/test/Sema/ms-inline-asm.c Thu Jul 24 21:27:14 2014
@@ -60,13 +60,13 @@ int t2(int *arr, int i) {
   }
 
   // expected-error at +1 {{cannot use base register with variable reference}}
-  __asm mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1]
+  __asm { mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1] }
   // expected-error at +1 {{cannot use index register with variable reference}}
-  __asm mov eax, arr[esi * 4]
+  __asm { mov eax, arr[esi * 4] }
   // expected-error at +1 {{cannot use more than one symbol in memory operand}}
-  __asm mov eax, arr[i]
+  __asm { mov eax, arr[i] }
   // expected-error at +1 {{cannot use more than one symbol in memory operand}}
-  __asm mov eax, global[i]
+  __asm { mov eax, global[i] }
 
   // FIXME: Why don't we diagnose this?
   // expected-Xerror at +1 {{cannot reference multiple local variables in assembly operand}}
@@ -80,22 +80,22 @@ typedef struct {
 } A;
 
 void t3() {
-  __asm mov eax, [eax] UndeclaredId // expected-error {{unknown token in expression}}
+  __asm { mov eax, [eax] UndeclaredId } // expected-error {{unknown token in expression}}
 
   // FIXME: Only emit one diagnostic here.
   // expected-error at +2 {{unexpected type name 'A': expected expression}}
   // expected-error at +1 {{unknown token in expression}}
-  __asm mov eax, [eax] A
+  __asm { mov eax, [eax] A }
 }
 
 void t4() {
   // The dot in the "intel dot operator" is optional in MSVC.  MSVC also does
   // global field lookup, but we don't.
-  __asm mov eax, [0] A.a
-  __asm mov eax, [0].A.a
-  __asm mov eax, [0].a    // expected-error {{Unable to lookup field reference!}}
-  __asm mov eax, fs:[0] A.a
-  __asm mov eax, fs:[0].A.a
-  __asm mov eax, fs:[0].a // expected-error {{Unable to lookup field reference!}}
-  __asm mov eax, fs:[0]. A.a  // expected-error {{Unexpected token type!}}
+  __asm { mov eax, [0] A.a }
+  __asm { mov eax, [0].A.a }
+  __asm { mov eax, [0].a } // expected-error {{Unable to lookup field reference!}}
+  __asm { mov eax, fs:[0] A.a }
+  __asm { mov eax, fs:[0].A.a }
+  __asm { mov eax, fs:[0].a } // expected-error {{Unable to lookup field reference!}}
+  __asm { mov eax, fs:[0]. A.a } // expected-error {{Unexpected token type!}}
 }





More information about the cfe-commits mailing list