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