summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Belevich <tra@google.com>2015-09-22 17:23:22 +0000
committerArtem Belevich <tra@google.com>2015-09-22 17:23:22 +0000
commit675c6b4346cdde41712c89a9c80cb4d1ffb7267e (patch)
treecb09d08fdedf679b21887b3ec10d8a3e931aa0d2
parent20db8d08e59176291d746d4f65cedf639d308594 (diff)
[CUDA] Allow parsing of host and device code simultaneously.
* adds -aux-triple option to specify target triple * propagates aux target info to AST context and Preprocessor * pulls in target specific preprocessor macros. * pulls in target-specific builtins from aux target. * sets appropriate host or device attribute on builtins. Differential Revision: http://reviews.llvm.org/D12917 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248299 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ASTContext.h11
-rw-r--r--include/clang/Basic/Builtins.h21
-rw-r--r--include/clang/Driver/CC1Options.td2
-rw-r--r--include/clang/Frontend/CompilerInstance.h12
-rw-r--r--include/clang/Frontend/FrontendOptions.h5
-rw-r--r--include/clang/Lex/Preprocessor.h7
-rw-r--r--lib/AST/ASTContext.cpp14
-rw-r--r--lib/Basic/Builtins.cpp19
-rw-r--r--lib/CodeGen/CGBuiltin.cpp36
-rw-r--r--lib/Frontend/CompilerInstance.cpp16
-rw-r--r--lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--lib/Frontend/InitPreprocessor.cpp4
-rw-r--r--lib/Lex/Preprocessor.cpp32
-rw-r--r--lib/Sema/SemaDecl.cpp10
-rw-r--r--test/SemaCUDA/builtins.cu33
15 files changed, 154 insertions, 71 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index b5d03e5e37..8b31876ddd 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -437,6 +437,7 @@ private:
friend class CXXRecordDecl;
const TargetInfo *Target;
+ const TargetInfo *AuxTarget;
clang::PrintingPolicy PrintingPolicy;
public:
@@ -523,7 +524,8 @@ public:
}
const TargetInfo &getTargetInfo() const { return *Target; }
-
+ const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
+
/// getIntTypeForBitwidth -
/// sets integer QualTy according to specified details:
/// bitwidth, signed/unsigned.
@@ -2415,9 +2417,10 @@ public:
/// This routine may only be invoked once for a given ASTContext object.
/// It is normally invoked after ASTContext construction.
///
- /// \param Target The target
- void InitBuiltinTypes(const TargetInfo &Target);
-
+ /// \param Target The target
+ void InitBuiltinTypes(const TargetInfo &Target,
+ const TargetInfo *AuxTarget = nullptr);
+
private:
void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 87e2ac7079..27dc615400 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -56,15 +56,23 @@ struct Info {
/// \brief Holds information about both target-independent and
/// target-specific builtins, allowing easy queries by clients.
+///
+/// Builtins from an optional auxiliary target are stored in
+/// AuxTSRecords. Their IDs are shifted up by NumTSRecords and need to
+/// be translated back with getAuxBuiltinID() before use.
class Context {
const Info *TSRecords;
+ const Info *AuxTSRecords;
unsigned NumTSRecords;
+ unsigned NumAuxTSRecords;
+
public:
Context();
/// \brief Perform target-specific initialization
- void initializeTarget(const TargetInfo &Target);
-
+ /// \param AuxTarget Target info to incorporate builtins from. May be nullptr.
+ void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget);
+
/// \brief Mark the identifiers for all the builtins with their
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.
@@ -176,6 +184,15 @@ public:
return getRecord(ID).Features;
}
+ /// \brief Return true if builtin ID belongs to AuxTarget.
+ bool isAuxBuiltinID(unsigned ID) const {
+ return ID >= (Builtin::FirstTSBuiltin + NumTSRecords);
+ }
+
+ /// Return real buitin ID (i.e. ID it would have furing compilation
+ /// for AuxTarget).
+ unsigned getAuxBuiltinID(unsigned ID) const { return ID - NumTSRecords; }
+
private:
const Info &getRecord(unsigned ID) const;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 8fec47fa7d..418768b332 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -325,6 +325,8 @@ def cc1as : Flag<["-"], "cc1as">;
def ast_merge : Separate<["-"], "ast-merge">,
MetaVarName<"<ast file>">,
HelpText<"Merge the given AST file into the translation unit being compiled.">;
+def aux_triple : Separate<["-"], "aux-triple">,
+ HelpText<"Auxiliary target triple.">;
def code_completion_at : Separate<["-"], "code-completion-at">,
MetaVarName<"<file>:<line>:<column>">,
HelpText<"Dump code-completion information at a location">;
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 9fa250e71a..5c29f753db 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -78,6 +78,9 @@ class CompilerInstance : public ModuleLoader {
/// The target being compiled for.
IntrusiveRefCntPtr<TargetInfo> Target;
+ /// Auxiliary Target info.
+ IntrusiveRefCntPtr<TargetInfo> AuxTarget;
+
/// The virtual file system.
IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem;
@@ -352,6 +355,15 @@ public:
void setTarget(TargetInfo *Value);
/// }
+ /// @name AuxTarget Info
+ /// {
+
+ TargetInfo *getAuxTarget() const { return AuxTarget.get(); }
+
+ /// Replace the current AuxTarget.
+ void setAuxTarget(TargetInfo *Value);
+
+ /// }
/// @name Virtual File System
/// {
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index cc555860bb..969f0c0a25 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -256,7 +256,10 @@ public:
/// \brief File name of the file that will provide record layouts
/// (in the format produced by -fdump-record-layouts).
std::string OverrideRecordLayoutsFile;
-
+
+ /// \brief Auxiliary triple for CUDA compilation.
+ std::string AuxTriple;
+
public:
FrontendOptions() :
DisableFree(false), RelocatablePCH(false), ShowHelp(false),
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index b2f58ead0e..de252cb5d5 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -98,6 +98,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
const TargetInfo *Target;
+ const TargetInfo *AuxTarget;
FileManager &FileMgr;
SourceManager &SourceMgr;
std::unique_ptr<ScratchBuffer> ScratchBuf;
@@ -656,7 +657,10 @@ public:
///
/// \param Target is owned by the caller and must remain valid for the
/// lifetime of the preprocessor.
- void Initialize(const TargetInfo &Target);
+ /// \param AuxTarget is owned by the caller and must remain valid for
+ /// the lifetime of the preprocessor.
+ void Initialize(const TargetInfo &Target,
+ const TargetInfo *AuxTarget = nullptr);
/// \brief Initialize the preprocessor to parse a model file
///
@@ -678,6 +682,7 @@ public:
const LangOptions &getLangOpts() const { return LangOpts; }
const TargetInfo &getTargetInfo() const { return *Target; }
+ const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
FileManager &getFileManager() const { return FileMgr; }
SourceManager &getSourceManager() const { return SourceMgr; }
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 3e0d6d1144..b98e3d4ed9 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -743,10 +743,10 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
FirstLocalImport(), LastLocalImport(), ExternCContext(nullptr),
SourceMgr(SM), LangOpts(LOpts),
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
- AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
- Idents(idents), Selectors(sels), BuiltinInfo(builtins),
- DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr),
- Comments(SM), CommentsLoaded(false),
+ AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),
+ PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
+ BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr),
+ Listener(nullptr), Comments(SM), CommentsLoaded(false),
CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), LastSDM(nullptr, 0) {
TUDecl = TranslationUnitDecl::Create(*this);
}
@@ -956,13 +956,15 @@ void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
Types.push_back(Ty);
}
-void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
+void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
+ const TargetInfo *AuxTarget) {
assert((!this->Target || this->Target == &Target) &&
"Incorrect target reinitialization");
assert(VoidTy.isNull() && "Context reinitialized?");
this->Target = &Target;
-
+ this->AuxTarget = AuxTarget;
+
ABI.reset(createCXXABI(Target));
AddrSpaceMap = getAddressSpaceMap(Target, LangOpts);
AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts);
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
index 13e09b276a..cb8a0b37bb 100644
--- a/lib/Basic/Builtins.cpp
+++ b/lib/Basic/Builtins.cpp
@@ -32,19 +32,27 @@ static const Builtin::Info BuiltinInfo[] = {
const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
if (ID < Builtin::FirstTSBuiltin)
return BuiltinInfo[ID];
- assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!");
+ assert(ID - Builtin::FirstTSBuiltin < (NumTSRecords + NumAuxTSRecords) &&
+ "Invalid builtin ID!");
+ if (isAuxBuiltinID(ID))
+ return AuxTSRecords[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin];
return TSRecords[ID - Builtin::FirstTSBuiltin];
}
Builtin::Context::Context() {
// Get the target specific builtins from the target.
TSRecords = nullptr;
+ AuxTSRecords = nullptr;
NumTSRecords = 0;
+ NumAuxTSRecords = 0;
}
-void Builtin::Context::initializeTarget(const TargetInfo &Target) {
+void Builtin::Context::InitializeTarget(const TargetInfo &Target,
+ const TargetInfo *AuxTarget) {
assert(NumTSRecords == 0 && "Already initialized target?");
Target.getTargetBuiltins(TSRecords, NumTSRecords);
+ if (AuxTarget)
+ AuxTarget->getTargetBuiltins(AuxTSRecords, NumAuxTSRecords);
}
bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo,
@@ -76,7 +84,12 @@ void Builtin::Context::initializeBuiltins(IdentifierTable &Table,
// Step #2: Register target-specific builtins.
for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
if (builtinIsSupported(TSRecords[i], LangOpts))
- Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
+ Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin);
+
+ // Step #3: Register target-specific builtins for AuxTarget.
+ for (unsigned i = 0, e = NumAuxTSRecords; i != e; ++i)
+ Table.get(AuxTSRecords[i].Name)
+ .setBuiltinID(i + Builtin::FirstTSBuiltin + NumTSRecords);
}
void Builtin::Context::forgetBuiltin(unsigned ID, IdentifierTable &Table) {
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 91614a5a64..047cf4fde7 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -1868,40 +1868,54 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return GetUndefRValue(E->getType());
}
-Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
- const CallExpr *E) {
- switch (getTarget().getTriple().getArch()) {
+static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
+ unsigned BuiltinID, const CallExpr *E,
+ llvm::Triple::ArchType Arch) {
+ switch (Arch) {
case llvm::Triple::arm:
case llvm::Triple::armeb:
case llvm::Triple::thumb:
case llvm::Triple::thumbeb:
- return EmitARMBuiltinExpr(BuiltinID, E);
+ return CGF->EmitARMBuiltinExpr(BuiltinID, E);
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- return EmitAArch64BuiltinExpr(BuiltinID, E);
+ return CGF->EmitAArch64BuiltinExpr(BuiltinID, E);
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- return EmitX86BuiltinExpr(BuiltinID, E);
+ return CGF->EmitX86BuiltinExpr(BuiltinID, E);
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
- return EmitPPCBuiltinExpr(BuiltinID, E);
+ return CGF->EmitPPCBuiltinExpr(BuiltinID, E);
case llvm::Triple::r600:
case llvm::Triple::amdgcn:
- return EmitAMDGPUBuiltinExpr(BuiltinID, E);
+ return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
case llvm::Triple::systemz:
- return EmitSystemZBuiltinExpr(BuiltinID, E);
+ return CGF->EmitSystemZBuiltinExpr(BuiltinID, E);
case llvm::Triple::nvptx:
case llvm::Triple::nvptx64:
- return EmitNVPTXBuiltinExpr(BuiltinID, E);
+ return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E);
case llvm::Triple::wasm32:
case llvm::Triple::wasm64:
- return EmitWebAssemblyBuiltinExpr(BuiltinID, E);
+ return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E);
default:
return nullptr;
}
}
+Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
+ const CallExpr *E) {
+ if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
+ assert(getContext().getAuxTargetInfo() && "Missing aux target info");
+ return EmitTargetArchBuiltinExpr(
+ this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E,
+ getContext().getAuxTargetInfo()->getTriple().getArch());
+ }
+
+ return EmitTargetArchBuiltinExpr(this, BuiltinID, E,
+ getTarget().getTriple().getArch());
+}
+
static llvm::VectorType *GetNeonType(CodeGenFunction *CGF,
NeonTypeFlags TypeFlags,
bool V1Ty=false) {
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 3326b81e60..d6e5732607 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -78,9 +78,8 @@ void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
Diagnostics = Value;
}
-void CompilerInstance::setTarget(TargetInfo *Value) {
- Target = Value;
-}
+void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
+void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
void CompilerInstance::setFileManager(FileManager *Value) {
FileMgr = Value;
@@ -312,7 +311,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(),
getSourceManager(), *HeaderInfo, *this, PTHMgr,
/*OwnsHeaderSearch=*/true, TUKind);
- PP->Initialize(getTarget());
+ PP->Initialize(getTarget(), getAuxTarget());
// Note that this is different then passing PTHMgr to Preprocessor's ctor.
// That argument is used as the IdentifierInfoLookup argument to
@@ -396,7 +395,7 @@ void CompilerInstance::createASTContext() {
auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
PP.getIdentifierTable(), PP.getSelectorTable(),
PP.getBuiltinInfo());
- Context->InitBuiltinTypes(getTarget());
+ Context->InitBuiltinTypes(getTarget(), getAuxTarget());
setASTContext(Context);
}
@@ -800,6 +799,13 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
if (!hasTarget())
return false;
+ // Create TargetInfo for the other side of CUDA compilation.
+ if (getLangOpts().CUDA && !getFrontendOpts().AuxTriple.empty()) {
+ std::shared_ptr<TargetOptions> TO(new TargetOptions);
+ TO->Triple = getFrontendOpts().AuxTriple;
+ setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO));
+ }
+
// Inform the target of the language options.
//
// FIXME: We shouldn't need to do this, the target should be immutable once
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index d7995627ac..a907133903 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -975,6 +975,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.OverrideRecordLayoutsFile
= Args.getLastArgValue(OPT_foverride_record_layout_EQ);
+ Opts.AuxTriple =
+ llvm::Triple::normalize(Args.getLastArgValue(OPT_aux_triple));
+
if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
OPT_arcmt_modify,
OPT_arcmt_migrate)) {
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 0791494f79..0b445e8b65 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -918,6 +918,10 @@ void clang::InitializePreprocessor(
// Install things like __POWERPC__, __GNUC__, etc into the macro table.
if (InitOpts.UsePredefines) {
+ if (LangOpts.CUDA && PP.getAuxTargetInfo())
+ InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
+ Builder);
+
InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts, Builder);
// Install definitions to make Objective-C++ ARC work well with various
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 29a00d3ca3..82fcde545b 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -62,20 +62,19 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
IdentifierInfoLookup *IILookup, bool OwnsHeaders,
TranslationUnitKind TUKind)
: PPOpts(PPOpts), Diags(&diags), LangOpts(opts), Target(nullptr),
- FileMgr(Headers.getFileMgr()), SourceMgr(SM),
- ScratchBuf(new ScratchBuffer(SourceMgr)),HeaderInfo(Headers),
+ AuxTarget(nullptr), FileMgr(Headers.getFileMgr()), SourceMgr(SM),
+ ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers),
TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
Identifiers(opts, IILookup),
PragmaHandlers(new PragmaNamespace(StringRef())),
- IncrementalProcessing(false), TUKind(TUKind),
- CodeComplete(nullptr), CodeCompletionFile(nullptr),
- CodeCompletionOffset(0), LastTokenWasAt(false),
- ModuleImportExpectsIdentifier(false), CodeCompletionReached(0),
- MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
- CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),
- Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState),
- MacroArgCache(nullptr), Record(nullptr),
- MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
+ IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr),
+ CodeCompletionFile(nullptr), CodeCompletionOffset(0),
+ LastTokenWasAt(false), ModuleImportExpectsIdentifier(false),
+ CodeCompletionReached(0), MainFileDir(nullptr),
+ SkipMainFilePreamble(0, true), CurPPLexer(nullptr), CurDirLookup(nullptr),
+ CurLexerKind(CLK_Lexer), CurSubmodule(nullptr), Callbacks(nullptr),
+ CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr),
+ Record(nullptr), MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
OwnsHeaderSearch = OwnsHeaders;
CounterValue = 0; // __COUNTER__ starts at 0.
@@ -170,13 +169,18 @@ Preprocessor::~Preprocessor() {
delete &HeaderInfo;
}
-void Preprocessor::Initialize(const TargetInfo &Target) {
+void Preprocessor::Initialize(const TargetInfo &Target,
+ const TargetInfo *AuxTarget) {
assert((!this->Target || this->Target == &Target) &&
"Invalid override of target information");
this->Target = &Target;
-
+
+ assert((!this->AuxTarget || this->AuxTarget == AuxTarget) &&
+ "Invalid override of aux target information.");
+ this->AuxTarget = AuxTarget;
+
// Initialize information about built-ins.
- BuiltinInfo.initializeTarget(Target);
+ BuiltinInfo.InitializeTarget(Target, AuxTarget);
HeaderInfo.setTarget(Target);
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 22d2d3469f..9195a060db 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11293,11 +11293,11 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
if (getLangOpts().CUDA && getLangOpts().CUDATargetOverloads &&
Context.BuiltinInfo.isTSBuiltin(BuiltinID) &&
!FD->hasAttr<CUDADeviceAttr>() && !FD->hasAttr<CUDAHostAttr>()) {
- // Target-specific builtins are assumed to be intended for use
- // in this particular CUDA compilation mode and should have
- // appropriate attribute set so we can enforce CUDA function
- // call restrictions.
- if (getLangOpts().CUDAIsDevice)
+ // Assign appropriate attribute depending on CUDA compilation
+ // mode and the target builtin belongs to. E.g. during host
+ // compilation, aux builtins are __device__, the rest are __host__.
+ if (getLangOpts().CUDAIsDevice !=
+ Context.BuiltinInfo.isAuxBuiltinID(BuiltinID))
FD->addAttr(CUDADeviceAttr::CreateImplicit(Context, FD->getLocation()));
else
FD->addAttr(CUDAHostAttr::CreateImplicit(Context, FD->getLocation()));
diff --git a/test/SemaCUDA/builtins.cu b/test/SemaCUDA/builtins.cu
index 2c619b5633..32b575862c 100644
--- a/test/SemaCUDA/builtins.cu
+++ b/test/SemaCUDA/builtins.cu
@@ -1,36 +1,31 @@
-// Tests that target-specific builtins have appropriate host/device
-// attributes and that CUDA call restrictions are enforced. Also
-// verify that non-target builtins can be used from both host and
-// device functions.
+// Tests that host and target builtins can be used in the same TU,
+// have appropriate host/device attributes and that CUDA call
+// restrictions are enforced. Also verify that non-target builtins can
+// be used from both host and device functions.
//
// REQUIRES: x86-registered-target
// REQUIRES: nvptx-registered-target
// RUN: %clang_cc1 -triple x86_64-unknown-unknown \
+// RUN: -aux-triple nvptx64-unknown-cuda \
// RUN: -fcuda-target-overloads -fsyntax-only -verify %s
// RUN: %clang_cc1 -triple nvptx64-unknown-cuda -fcuda-is-device \
+// RUN: -aux-triple x86_64-unknown-unknown \
// RUN: -fcuda-target-overloads -fsyntax-only -verify %s
+#if !(defined(__amd64__) && defined(__PTX__))
+#error "Expected to see preprocessor macros from both sides of compilation."
+#endif
-#ifdef __CUDA_ARCH__
-// Device-side builtins are not allowed to be called from host functions.
void hf() {
- int x = __builtin_ptx_read_tid_x(); // expected-note {{'__builtin_ptx_read_tid_x' declared here}}
+ int x = __builtin_ia32_rdtsc();
+ int y = __builtin_ptx_read_tid_x(); // expected-note {{'__builtin_ptx_read_tid_x' declared here}}
// expected-error@-1 {{reference to __device__ function '__builtin_ptx_read_tid_x' in __host__ function}}
x = __builtin_abs(1);
}
+
__attribute__((device)) void df() {
int x = __builtin_ptx_read_tid_x();
+ int y = __builtin_ia32_rdtsc(); // expected-error {{reference to __host__ function '__builtin_ia32_rdtsc' in __device__ function}}
+ // expected-note@20 {{'__builtin_ia32_rdtsc' declared here}}
x = __builtin_abs(1);
}
-#else
-// Host-side builtins are not allowed to be called from device functions.
-__attribute__((device)) void df() {
- int x = __builtin_ia32_rdtsc(); // expected-note {{'__builtin_ia32_rdtsc' declared here}}
- // expected-error@-1 {{reference to __host__ function '__builtin_ia32_rdtsc' in __device__ function}}
- x = __builtin_abs(1);
-}
-void hf() {
- int x = __builtin_ia32_rdtsc();
- x = __builtin_abs(1);
-}
-#endif