r314494 - [X86][MS-InlineAsm] Extended support for variables / identifiers on memory / immediate expressions

Coby Tayree via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 29 00:02:49 PDT 2017


Author: coby
Date: Fri Sep 29 00:02:49 2017
New Revision: 314494

URL: http://llvm.org/viewvc/llvm-project?rev=314494&view=rev
Log:
[X86][MS-InlineAsm] Extended support for variables / identifiers on memory / immediate expressions

Allow the proper recognition of Enum values and global variables inside ms inline-asm memory / immediate expressions, as they require some additional overhead and treated incorrect if doesn't early recognized.
supersedes D33278, D35774

Differential Revision: https://reviews.llvm.org/D37413

Added:
    cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp   (with props)
    cfe/trunk/test/CodeGen/ms-inline-asm-variables.c   (with props)
Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseStmtAsm.cpp
    cfe/trunk/lib/Sema/SemaStmtAsm.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=314494&r1=314493&r2=314494&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Sep 29 00:02:49 2017
@@ -1474,7 +1474,6 @@ public:
 
   ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
                                   unsigned &NumLineToksConsumed,
-                                  void *Info,
                                   bool IsUnevaluated);
 
 private:

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=314494&r1=314493&r2=314494&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Sep 29 00:02:49 2017
@@ -3788,15 +3788,15 @@ public:
                              Expr *AsmString, MultiExprArg Clobbers,
                              SourceLocation RParenLoc);
 
+  void FillInlineAsmIdentifierInfo(Expr *Res,
+                                   llvm::InlineAsmIdentifierInfo &Info);
   ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS,
                                        SourceLocation TemplateKWLoc,
                                        UnqualifiedId &Id,
-                                       llvm::InlineAsmIdentifierInfo &Info,
                                        bool IsUnevaluatedContext);
   bool LookupInlineAsmField(StringRef Base, StringRef Member,
                             unsigned &Offset, SourceLocation AsmLoc);
   ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member,
-                                         llvm::InlineAsmIdentifierInfo &Info,
                                          SourceLocation AsmLoc);
   StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
                             ArrayRef<Token> AsmToks,

Modified: cfe/trunk/lib/Parse/ParseStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmtAsm.cpp?rev=314494&r1=314493&r2=314494&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmtAsm.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmtAsm.cpp Fri Sep 29 00:02:49 2017
@@ -54,9 +54,9 @@ public:
     assert(AsmToks.size() == AsmTokOffsets.size());
   }
 
-  void *LookupInlineAsmIdentifier(StringRef &LineBuf,
-                                  llvm::InlineAsmIdentifierInfo &Info,
-                                  bool IsUnevaluatedContext) override {
+  void LookupInlineAsmIdentifier(StringRef &LineBuf,
+                                 llvm::InlineAsmIdentifierInfo &Info,
+                                 bool IsUnevaluatedContext) override {
     // Collect the desired tokens.
     SmallVector<Token, 16> LineToks;
     const Token *FirstOrigToken = nullptr;
@@ -64,7 +64,7 @@ public:
 
     unsigned NumConsumedToks;
     ExprResult Result = TheParser.ParseMSAsmIdentifier(
-        LineToks, NumConsumedToks, &Info, IsUnevaluatedContext);
+        LineToks, NumConsumedToks, IsUnevaluatedContext);
 
     // If we consumed the entire line, tell MC that.
     // Also do this if we consumed nothing as a way of reporting failure.
@@ -89,9 +89,10 @@ public:
       LineBuf = LineBuf.substr(0, TotalOffset);
     }
 
-    // Initialize the "decl" with the lookup result.
-    Info.OpDecl = static_cast<void *>(Result.get());
-    return Info.OpDecl;
+    // Initialize Info with the lookup result.
+    if (!Result.isUsable())
+      return;
+    TheParser.getActions().FillInlineAsmIdentifierInfo(Result.get(), Info);
   }
 
   StringRef LookupInlineAsmLabel(StringRef Identifier, llvm::SourceMgr &LSM,
@@ -178,16 +179,9 @@ private:
 }
 
 /// Parse an identifier in an MS-style inline assembly block.
-///
-/// \param CastInfo - a void* so that we don't have to teach Parser.h
-///   about the actual type.
 ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
                                         unsigned &NumLineToksConsumed,
-                                        void *CastInfo,
                                         bool IsUnevaluatedContext) {
-  llvm::InlineAsmIdentifierInfo &Info =
-      *(llvm::InlineAsmIdentifierInfo *)CastInfo;
-
   // Push a fake token on the end so that we don't overrun the token
   // stream.  We use ';' because it expression-parsing should never
   // overrun it.
@@ -227,7 +221,7 @@ ExprResult Parser::ParseMSAsmIdentifier(
                                  /*AllowDeductionGuide=*/false,
                                  /*ObjectType=*/nullptr, TemplateKWLoc, Id);
     // Perform the lookup.
-    Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info,
+    Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id,
                                                IsUnevaluatedContext);
   }
   // While the next two tokens are 'period' 'identifier', repeatedly parse it as
@@ -241,7 +235,7 @@ ExprResult Parser::ParseMSAsmIdentifier(
     IdentifierInfo *Id = Tok.getIdentifierInfo();
     ConsumeToken(); // Consume the identifier.
     Result = Actions.LookupInlineAsmVarDeclField(Result.get(), Id->getName(),
-                                                 Info, Tok.getLocation());
+                                                 Tok.getLocation());
   }
 
   // Figure out how many tokens we are into LineToks.

Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=314494&r1=314493&r2=314494&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Fri Sep 29 00:02:49 2017
@@ -48,10 +48,10 @@ static bool CheckAsmLValue(const Expr *E
   if (E != E2 && E2->isLValue()) {
     if (!S.getLangOpts().HeinousExtensions)
       S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
-        << E->getSourceRange();
+          << E->getSourceRange();
     else
       S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
-        << E->getSourceRange();
+          << E->getSourceRange();
     // Accept, even if we emitted an error diagnostic.
     return false;
   }
@@ -607,23 +607,31 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceL
   return NS;
 }
 
-static void fillInlineAsmTypeInfo(const ASTContext &Context, QualType T,
-                                  llvm::InlineAsmIdentifierInfo &Info) {
-  // Compute the type size (and array length if applicable?).
-  Info.Type = Info.Size = Context.getTypeSizeInChars(T).getQuantity();
-  if (T->isArrayType()) {
-    const ArrayType *ATy = Context.getAsArrayType(T);
-    Info.Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity();
-    Info.Length = Info.Size / Info.Type;
-  }
+void Sema::FillInlineAsmIdentifierInfo(Expr *Res,
+                                       llvm::InlineAsmIdentifierInfo &Info) {
+  QualType T = Res->getType();
+  Expr::EvalResult Eval;
+  if (T->isFunctionType() || T->isDependentType())
+    return Info.setLabel(Res);
+  if (Res->isRValue()) {
+    if (isa<clang::EnumType>(T) && Res->EvaluateAsRValue(Eval, Context))
+      return Info.setEnum(Eval.Val.getInt().getSExtValue());
+    return Info.setLabel(Res);
+  }
+  unsigned Size = Context.getTypeSizeInChars(T).getQuantity();
+  unsigned Type = Size;
+  if (const auto *ATy = Context.getAsArrayType(T))
+    Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity();
+  bool IsGlobalLV = false;
+  if (Res->EvaluateAsLValue(Eval, Context))
+    IsGlobalLV = Eval.isGlobalLValue();
+  Info.setVar(Res, IsGlobalLV, Size, Type);
 }
 
 ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
                                            SourceLocation TemplateKWLoc,
                                            UnqualifiedId &Id,
-                                           llvm::InlineAsmIdentifierInfo &Info,
                                            bool IsUnevaluatedContext) {
-  Info.clear();
 
   if (IsUnevaluatedContext)
     PushExpressionEvaluationContext(
@@ -664,12 +672,6 @@ ExprResult Sema::LookupInlineAsmIdentifi
     return ExprError();
   }
 
-  fillInlineAsmTypeInfo(Context, T, Info);
-
-  // We can work with the expression as long as it's not an r-value.
-  if (!Result.get()->isRValue())
-    Info.IsVarDecl = true;
-
   return Result;
 }
 
@@ -743,9 +745,7 @@ bool Sema::LookupInlineAsmField(StringRe
 
 ExprResult
 Sema::LookupInlineAsmVarDeclField(Expr *E, StringRef Member,
-                                  llvm::InlineAsmIdentifierInfo &Info,
                                   SourceLocation AsmLoc) {
-  Info.clear();
 
   QualType T = E->getType();
   if (T->isDependentType()) {
@@ -780,14 +780,6 @@ Sema::LookupInlineAsmVarDeclField(Expr *
   ExprResult Result = BuildMemberReferenceExpr(
       E, E->getType(), AsmLoc, /*IsArrow=*/false, CXXScopeSpec(),
       SourceLocation(), nullptr, FieldResult, nullptr, nullptr);
-  if (Result.isInvalid())
-    return Result;
-  Info.OpDecl = Result.get();
-
-  fillInlineAsmTypeInfo(Context, Result.get()->getType(), Info);
-
-  // Fields are "variables" as far as inline assembly is concerned.
-  Info.IsVarDecl = true;
 
   return Result;
 }

Added: cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp?rev=314494&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp (added)
+++ cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp Fri Sep 29 00:02:49 2017
@@ -0,0 +1,55 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -fasm-blocks -triple i386-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+namespace x {
+  enum { A = 12 };
+  struct y_t {
+    enum { A = 17 };
+    int r;
+  } y;
+}
+
+// CHECK-LABEL: t1
+void t1() {
+  enum { A = 1 };
+  // CHECK: call void asm
+  // CHECK-SAME: mov eax, $$12
+  __asm mov eax, x::A
+  // CHECK-SAME: mov eax, $$17
+  __asm mov eax, x::y_t::A
+  // CHECK-NEXT: call void asm
+  // CHECK-SAME: mov eax, $$1
+  __asm {mov eax, A}
+}
+
+// CHECK-LABEL: t2
+void t2() {
+  enum { A = 1, B };
+  // CHECK: call void asm
+  // CHECK-SAME: mov eax, $$21
+  __asm mov eax, (A + 9) * 2 + A
+  // CHECK-SAME: mov eax, $$4
+  __asm mov eax, A << 2
+  // CHECK-SAME: mov eax, $$2
+  __asm mov eax, B & 3
+  // CHECK-SAME: mov eax, $$5
+  __asm mov eax, 3 + (B & 3)
+  // CHECK-SAME: mov eax, $$8
+  __asm mov eax, 2 << A * B
+}
+
+// CHECK-LABEL: t3
+void t3() {
+  int arr[4];
+  enum { A = 4, B };
+  // CHECK: call void asm
+  // CHECK-SAME: mov eax, [eax + $$47]
+  __asm { mov eax, [(x::A + 9) + A * B + 3 + 3 + eax] }
+  // CHECK-NEXT: call void asm
+  // CHECK-SAME: mov eax, dword ptr $0[$$4]
+  __asm { mov eax, dword ptr [arr + A] }
+  // CHECK-NEXT: call void asm
+  // CHECK-SAME: mov eax, dword ptr $0[$$8]
+  __asm { mov eax, dword ptr A[arr + A] }
+}
+

Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-enums.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/CodeGen/ms-inline-asm-variables.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm-variables.c?rev=314494&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/ms-inline-asm-variables.c (added)
+++ cfe/trunk/test/CodeGen/ms-inline-asm-variables.c Fri Sep 29 00:02:49 2017
@@ -0,0 +1,35 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -fasm-blocks -triple i386-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+int gVar;
+void t1() {
+  // CHECK: add eax, dword ptr gVar[eax]
+  __asm add eax, dword ptr gVar[eax]
+  // CHECK: add dword ptr gVar[eax], eax
+  __asm add dword ptr [eax+gVar], eax
+  // CHECK: add ebx, dword ptr gVar[ebx + $$270]
+  __asm add ebx, dword ptr gVar[271 - 82 + 81 + ebx]
+  // CHECK: add dword ptr gVar[ebx + $$828], ebx
+  __asm add dword ptr [ebx + gVar + 828], ebx
+  // CHECK: add ecx, dword ptr gVar[ecx + ecx * $$4 + $$4590]
+  __asm add ecx, dword ptr gVar[4590 + ecx + ecx*4]
+  // CHECK: add dword ptr gVar[ecx + ecx * $$8 + $$73], ecx
+  __asm add dword ptr [gVar + ecx + 45 + 23 - 53 + 60 - 2 + ecx*8], ecx
+  // CHECK: add gVar[ecx + ebx + $$7], eax
+  __asm add 1 + 1 + 2 + 3[gVar + ecx + ebx], eax
+}
+
+void t2() {
+  int lVar;
+  // CHECK: mov eax, dword ptr ${{[0-9]}}[eax]
+  __asm mov eax, dword ptr lVar[eax]
+  // CHECK: mov dword ptr ${{[0-9]}}[eax], eax
+  __asm mov dword ptr [eax+lVar], eax
+  // CHECK: mov ebx, dword ptr ${{[0-9]}}[ebx + $$270]
+  __asm mov ebx, dword ptr lVar[271 - 82 + 81 + ebx]
+  // CHECK: mov dword ptr ${{[0-9]}}[ebx + $$828], ebx
+  __asm mov dword ptr [ebx + lVar + 828], ebx
+  // CHECK: mov ${{[0-9]}}[ebx + $$47], eax
+  __asm mov 5 + 8 + 13 + 21[lVar + ebx], eax
+}
+

Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-variables.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-variables.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-variables.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the cfe-commits mailing list