From: Artem Belevich Date: Mon, 27 Apr 2015 19:37:53 +0000 (+0000) Subject: [cuda] Ignore "TLS unsupported by target" errors for host variables during device... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fa62ad40872b0d85f9b9a55f0b806c910edab257;p=platform%2Fupstream%2Fllvm.git [cuda] Ignore "TLS unsupported by target" errors for host variables during device compilation. During device-side CUDA compilation clang currently complains about all TLS variables, regardless of whether they are __host__ or __device__. This patch suppresses "TLS unsupported" errors for host variables during device compilation and for device variables during host compilation. Differential Revision: http://reviews.llvm.org/D9269 llvm-svn: 235907 --- diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h index 14e119c..60c6598 100644 --- a/clang/include/clang/Sema/SemaInternal.h +++ b/clang/include/clang/Sema/SemaInternal.h @@ -48,6 +48,18 @@ inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) { Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(); } +// Helper function to check whether D's attributes match current CUDA mode. +// Decls with mismatched attributes and related diagnostics may have to be +// ignored during this CUDA compilation pass. +inline bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D) { + if (!LangOpts.CUDA || !D) + return true; + bool isDeviceSideDecl = D->hasAttr() || + D->hasAttr() || + D->hasAttr(); + return isDeviceSideDecl == LangOpts.CUDAIsDevice; +} + // Directly mark a variable odr-used. Given a choice, prefer to use // MarkVariableReferenced since it does additional checks and then // calls MarkVarDeclODRUsed. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 07dbdaf..58e7838 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5753,6 +5753,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (IsLocalExternDecl) NewVD->setLocalExternDecl(); + bool EmitTLSUnsupportedError = false; if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) { // C++11 [dcl.stc]p4: // When thread_local is applied to a variable of block scope the @@ -5767,10 +5768,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), diag::err_thread_non_global) << DeclSpec::getSpecifierName(TSCS); - else if (!Context.getTargetInfo().isTLSSupported()) - Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), - diag::err_thread_unsupported); - else + else if (!Context.getTargetInfo().isTLSSupported()) { + if (getLangOpts().CUDA) + // Postpone error emission until we've collected attributes required to + // figure out whether it's a host or device variable and whether the + // error should be ignored. + EmitTLSUnsupportedError = true; + else + Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), + diag::err_thread_unsupported); + } else NewVD->setTSCSpec(TSCS); } @@ -5819,6 +5826,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, ProcessDeclAttributes(S, NewVD, D); if (getLangOpts().CUDA) { + if (EmitTLSUnsupportedError && DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) + Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), + diag::err_thread_unsupported); // CUDA B.2.5: "__shared__ and __constant__ variables have implied static // storage [duration]." if (SC == SC_None && S->getFnParent() != nullptr && diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 179e207..9f48616 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -124,16 +124,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, // The parser verifies that there is a string literal here. assert(AsmString->isAscii()); - bool ValidateConstraints = true; - if (getLangOpts().CUDA) { - // In CUDA mode don't verify asm constraints in device functions during host - // compilation and vice versa. - bool InDeviceMode = getLangOpts().CUDAIsDevice; - FunctionDecl *FD = getCurFunctionDecl(); - bool IsDeviceFunction = - FD && (FD->hasAttr() || FD->hasAttr()); - ValidateConstraints = IsDeviceFunction == InDeviceMode; - } + bool ValidateConstraints = + DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()); for (unsigned i = 0; i != NumOutputs; i++) { StringLiteral *Literal = Constraints[i]; diff --git a/clang/test/SemaCUDA/qualifiers.cu b/clang/test/SemaCUDA/qualifiers.cu index 42a80b8..a5c8a6c 100644 --- a/clang/test/SemaCUDA/qualifiers.cu +++ b/clang/test/SemaCUDA/qualifiers.cu @@ -1,7 +1,23 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple nvptx-unknown-cuda -fsyntax-only -verify -fcuda-is-device %s #include "Inputs/cuda.h" +// Host (x86) supports TLS and device-side compilation should ignore +// host variables. No errors in either case. +int __thread host_tls_var; + +#if defined(__CUDA_ARCH__) +// NVPTX does not support TLS +__device__ int __thread device_tls_var; // expected-error {{thread-local storage is not supported for the current target}} +__shared__ int __thread shared_tls_var; // expected-error {{thread-local storage is not supported for the current target}} +#else +// Device-side vars should not produce any errors during host-side +// compilation. +__device__ int __thread device_tls_var; +__shared__ int __thread shared_tls_var; +#endif + __global__ void g1(int x) {} __global__ int g2(int x) { // expected-error {{must have void return type}} return 1;