[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
craig.topper marked an inline comment as done. craig.topper added inline comments. Comment at: clang/include/clang/AST/ASTContext.h:116 class ObjCTypeParamDecl; +class ParsedTargetAttr; class Preprocessor; MaskRay wrote: > This should be `struct`. I fixed it it in > 4b64e034612017fcc97b64d6031319cf18dbbb88 Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
MaskRay added inline comments. Comment at: clang/include/clang/AST/ASTContext.h:116 class ObjCTypeParamDecl; +class ParsedTargetAttr; class Preprocessor; This should be `struct`. I fixed it it in 4b64e034612017fcc97b64d6031319cf18dbbb88 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
This revision was automatically updated to reflect the committed changes. Closed by commit rGd35bcbbb5dab: [Sema][X86] Consider target attribute into the checks in validateOutputSize and… (authored by craig.topper). Changed prior to commit: https://reviews.llvm.org/D68627?vs=232666&id=235168#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/Basic/TargetInfo.h clang/lib/AST/ASTContext.cpp clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/lib/Sema/SemaStmtAsm.cpp clang/test/CodeGen/x86_32-inline-asm.c Index: clang/test/CodeGen/x86_32-inline-asm.c === --- clang/test/CodeGen/x86_32-inline-asm.c +++ clang/test/CodeGen/x86_32-inline-asm.c @@ -70,3 +70,35 @@ __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} #endif } + +int __attribute__((__target__("sse"))) _func2() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. +#ifdef __AVX__ + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. +#else + __asm__ volatile("foo1 %0" : : "x" (val256)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} +#endif + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx"))) _func3() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx512f"))) _func4() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val512)); // No error. +} Index: clang/lib/Sema/SemaStmtAsm.cpp === --- clang/lib/Sema/SemaStmtAsm.cpp +++ clang/lib/Sema/SemaStmtAsm.cpp @@ -11,6 +11,7 @@ //===--===// #include "clang/AST/ExprCXX.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/TargetInfo.h" @@ -255,6 +256,10 @@ // The parser verifies that there is a string literal here. assert(AsmString->isAscii()); + FunctionDecl *FD = dyn_cast(getCurLexicalContext()); + llvm::StringMap FeatureMap; + Context.getFunctionFeatureMap(FeatureMap, FD); + for (unsigned i = 0; i != NumOutputs; i++) { StringLiteral *Literal = Constraints[i]; assert(Literal->isAscii()); @@ -325,8 +330,8 @@ } unsigned Size = Context.getTypeSize(OutputExpr->getType()); -if (!Context.getTargetInfo().validateOutputSize(Literal->getString(), -Size)) { +if (!Context.getTargetInfo().validateOutputSize( +FeatureMap, Literal->getString(), Size)) { targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size) << Info.getConstraintStr(); return new (Context) @@ -427,8 +432,8 @@ return StmtError(); unsigned Size = Context.getTypeSize(Ty); -if (!Context.getTargetInfo().validateInputSize(Literal->getString(), - Size)) +if (!Context.getTargetInfo().validateInputSize(FeatureMap, + Literal->getString(), Size)) return StmtResult( targetDiag(InputExpr->getBeginLoc(), diag::err_asm_invalid_input_size) << Info.getConstraintStr()); Index: clang/lib/CodeGen/CodeGenModule.h === --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -1157,14 +1157,6 @@ /// It's up to you to ensure that this is safe. void AddDe
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
rnk added inline comments. Comment at: clang/include/clang/AST/ASTContext.h:2826 + /// valid feature names. + TargetAttr::ParsedTargetAttr + filterFunctionTargetAttrs(const TargetAttr *TD) const; I reverted this because it requires TargetAttr to be complete here, which I have been working for a few weeks to avoid. If you pull ParsedTargetAttr out of the TargetAttr class, then you can forward declare it, and reland. Sorry I didn't see that in review, this commit raced with rG60573ae6fe509b618dc6a2c5c55d921bccd77608, which removes the Attr.h include in ASTContext.h. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
This revision was automatically updated to reflect the committed changes. Closed by commit rGe1578fd2b79f: [Sema][X86] Consider target attribute into the checks in validateOutputSize and… (authored by craig.topper). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/Basic/TargetInfo.h clang/lib/AST/ASTContext.cpp clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/lib/Sema/SemaStmtAsm.cpp clang/test/CodeGen/x86_32-inline-asm.c Index: clang/test/CodeGen/x86_32-inline-asm.c === --- clang/test/CodeGen/x86_32-inline-asm.c +++ clang/test/CodeGen/x86_32-inline-asm.c @@ -70,3 +70,35 @@ __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} #endif } + +int __attribute__((__target__("sse"))) _func2() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. +#ifdef __AVX__ + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. +#else + __asm__ volatile("foo1 %0" : : "x" (val256)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} +#endif + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx"))) _func3() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx512f"))) _func4() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val512)); // No error. +} Index: clang/lib/Sema/SemaStmtAsm.cpp === --- clang/lib/Sema/SemaStmtAsm.cpp +++ clang/lib/Sema/SemaStmtAsm.cpp @@ -11,6 +11,7 @@ //===--===// #include "clang/AST/ExprCXX.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/TargetInfo.h" @@ -255,6 +256,10 @@ // The parser verifies that there is a string literal here. assert(AsmString->isAscii()); + FunctionDecl *FD = dyn_cast(getCurLexicalContext()); + llvm::StringMap FeatureMap; + Context.getFunctionFeatureMap(FeatureMap, FD); + for (unsigned i = 0; i != NumOutputs; i++) { StringLiteral *Literal = Constraints[i]; assert(Literal->isAscii()); @@ -325,8 +330,8 @@ } unsigned Size = Context.getTypeSize(OutputExpr->getType()); -if (!Context.getTargetInfo().validateOutputSize(Literal->getString(), -Size)) { +if (!Context.getTargetInfo().validateOutputSize( +FeatureMap, Literal->getString(), Size)) { targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size) << Info.getConstraintStr(); return new (Context) @@ -427,8 +432,8 @@ return StmtError(); unsigned Size = Context.getTypeSize(Ty); -if (!Context.getTargetInfo().validateInputSize(Literal->getString(), - Size)) +if (!Context.getTargetInfo().validateInputSize(FeatureMap, + Literal->getString(), Size)) return StmtResult( targetDiag(InputExpr->getBeginLoc(), diag::err_asm_invalid_input_size) << Info.getConstraintStr()); Index: clang/lib/CodeGen/CodeGenModule.h === --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -1150,14 +1150,6 @@ /// It's up to you to ensure that this is safe. void AddDefaultFnAttrs(llvm::Function &F); - /// Parses the target attributes passed in, an
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
rnk accepted this revision. rnk added a comment. This revision is now accepted and ready to land. lgtm Hoisting this to ASTContext and using it where needed seems like the logical thing to do. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
craig.topper updated this revision to Diff 228511. craig.topper added a comment. Refactor to share more code with the CodeGen target feature stuff. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/Basic/TargetInfo.h clang/lib/AST/ASTContext.cpp clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/lib/Sema/SemaStmtAsm.cpp clang/test/CodeGen/x86_32-inline-asm.c Index: clang/test/CodeGen/x86_32-inline-asm.c === --- clang/test/CodeGen/x86_32-inline-asm.c +++ clang/test/CodeGen/x86_32-inline-asm.c @@ -70,3 +70,35 @@ __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} #endif } + +int __attribute__((__target__("sse"))) _func2() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. +#ifdef __AVX__ + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. +#else + __asm__ volatile("foo1 %0" : : "x" (val256)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} +#endif + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx"))) _func3() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx512f"))) _func4() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val512)); // No error. +} Index: clang/lib/Sema/SemaStmtAsm.cpp === --- clang/lib/Sema/SemaStmtAsm.cpp +++ clang/lib/Sema/SemaStmtAsm.cpp @@ -11,6 +11,7 @@ //===--===// #include "clang/AST/ExprCXX.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/TargetInfo.h" @@ -255,6 +256,10 @@ // The parser verifies that there is a string literal here. assert(AsmString->isAscii()); + FunctionDecl *FD = dyn_cast(getCurLexicalContext()); + llvm::StringMap FeatureMap; + Context.getFunctionFeatureMap(FeatureMap, FD); + for (unsigned i = 0; i != NumOutputs; i++) { StringLiteral *Literal = Constraints[i]; assert(Literal->isAscii()); @@ -325,8 +330,8 @@ } unsigned Size = Context.getTypeSize(OutputExpr->getType()); -if (!Context.getTargetInfo().validateOutputSize(Literal->getString(), -Size)) { +if (!Context.getTargetInfo().validateOutputSize( +FeatureMap, Literal->getString(), Size)) { targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size) << Info.getConstraintStr(); return new (Context) @@ -427,8 +432,8 @@ return StmtError(); unsigned Size = Context.getTypeSize(Ty); -if (!Context.getTargetInfo().validateInputSize(Literal->getString(), - Size)) +if (!Context.getTargetInfo().validateInputSize(FeatureMap, + Literal->getString(), Size)) return StmtResult( targetDiag(InputExpr->getBeginLoc(), diag::err_asm_invalid_input_size) << Info.getConstraintStr()); Index: clang/lib/CodeGen/CodeGenModule.h === --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -1150,14 +1150,6 @@ /// It's up to you to ensure that this is safe. void AddDefaultFnAttrs(llvm::Function &F); - /// Parses the target attributes passed in, and returns only the ones that are - /// valid feature names. - TargetAttr::ParsedTargetAttr filterFunctio
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
erichkeane added inline comments. Comment at: clang/include/clang/Basic/TargetInfo.h:947 - virtual bool validateOutputSize(StringRef /*Constraint*/, + virtual bool validateOutputSize(const llvm::StringMap &FeatureMap, + StringRef /*Constraint*/, Other Parameter names are commented out (presumably to avoid an unused param warning?). Do we need to do that for this parameter as well? Comment at: clang/lib/Sema/SemaStmtAsm.cpp:240 +void getFunctionFeatureMap(llvm::StringMap &FeatureMap, + DiagnosticsEngine &Diags, First, this ought to be static. Second, since this is basically identical to what we do for CodeGen, I wonder if this needs to just be a member of Sema/ASTContext or something. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68627/new/ https://reviews.llvm.org/D68627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D68627: [Sema][X86] Consider target attribute into the checks in validateOutputSize and validateInputSize.
craig.topper created this revision. craig.topper added reviewers: rnk, echristo, erichkeane, RKSimon, spatel. Herald added a project: clang. The validateOutputSize and validateInputSize need to check whether AVX or AVX512 are enabled. But this can be affected by the target attribute so we need to factor that in. This patch copies some of the code from CodeGen to create an appropriate feature map that we can pass to the function. Probably need some refactoring here to share more code with Codegen. Is there a good place to do that? Also need to support the cpu_specific attribute as well. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D68627 Files: clang/include/clang/Basic/TargetInfo.h clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Sema/SemaStmtAsm.cpp clang/test/CodeGen/x86_32-inline-asm.c Index: clang/test/CodeGen/x86_32-inline-asm.c === --- clang/test/CodeGen/x86_32-inline-asm.c +++ clang/test/CodeGen/x86_32-inline-asm.c @@ -70,3 +70,35 @@ __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} #endif } + +int __attribute__((__target__("sse"))) _func2() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. +#ifdef __AVX__ + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. +#else + __asm__ volatile("foo1 %0" : : "x" (val256)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val256)); // expected-error {{invalid output size for constraint '=x'}} +#endif + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx"))) _func3() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}} + __asm__ volatile("foo1 %0" : "=x" (val512)); // expected-error {{invalid output size for constraint '=x'}} +} + +int __attribute__((__target__("avx512f"))) _func4() { + __asm__ volatile("foo1 %0" : : "x" (val128)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val128)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val256)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val256)); // No error. + __asm__ volatile("foo1 %0" : : "x" (val512)); // No error. + __asm__ volatile("foo1 %0" : "=x" (val512)); // No error. +} Index: clang/lib/Sema/SemaStmtAsm.cpp === --- clang/lib/Sema/SemaStmtAsm.cpp +++ clang/lib/Sema/SemaStmtAsm.cpp @@ -237,6 +237,44 @@ return SourceLocation(); } +void getFunctionFeatureMap(llvm::StringMap &FeatureMap, + DiagnosticsEngine &Diags, + const TargetInfo &Target, FunctionDecl *FD) { + StringRef TargetCPU = Target.getTargetOpts().CPU; + if (FD) { +if (const auto *TD = FD->getAttr()) { + TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse(); + + ParsedAttr.Features.erase( + llvm::remove_if(ParsedAttr.Features, + [&](const std::string &Feat) { +return !Target.isValidFeatureName( +StringRef{Feat}.substr(1)); + }), + ParsedAttr.Features.end()); + + ParsedAttr.Features.insert(ParsedAttr.Features.begin(), +Target.getTargetOpts().FeaturesAsWritten.begin(), +Target.getTargetOpts().FeaturesAsWritten.end()); + + if (ParsedAttr.Architecture != "" && + Target.isValidCPUName(ParsedAttr.Architecture)) +TargetCPU = ParsedAttr.Architecture; + + // Now populate the feature map, first with the TargetCPU which is either + // the default or a new one from the target attribute string. Then we'll + // use the passed in features (FeaturesAsWritten) along with the new ones + // from the attribute. + Target.initFeatureMap(FeatureMap, Diags, TargetCPU, +ParsedAttr.Features); + return; +} + } + + Target.initFeatureMap(FeatureMap, Diags, TargetCPU, +Target.getTargetOpts().Features); +} + StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, @@ -255,6 +293,10 @@