Skip to content

Commit fa62ad4

Browse files
committedApr 27, 2015
[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
1 parent 0eafe5d commit fa62ad4

File tree

4 files changed

+45
-15
lines changed

4 files changed

+45
-15
lines changed
 

Diff for: ‎clang/include/clang/Sema/SemaInternal.h

+12
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {
4848
Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
4949
}
5050

51+
// Helper function to check whether D's attributes match current CUDA mode.
52+
// Decls with mismatched attributes and related diagnostics may have to be
53+
// ignored during this CUDA compilation pass.
54+
inline bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D) {
55+
if (!LangOpts.CUDA || !D)
56+
return true;
57+
bool isDeviceSideDecl = D->hasAttr<CUDADeviceAttr>() ||
58+
D->hasAttr<CUDASharedAttr>() ||
59+
D->hasAttr<CUDAGlobalAttr>();
60+
return isDeviceSideDecl == LangOpts.CUDAIsDevice;
61+
}
62+
5163
// Directly mark a variable odr-used. Given a choice, prefer to use
5264
// MarkVariableReferenced since it does additional checks and then
5365
// calls MarkVarDeclODRUsed.

Diff for: ‎clang/lib/Sema/SemaDecl.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -5753,6 +5753,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
57535753
if (IsLocalExternDecl)
57545754
NewVD->setLocalExternDecl();
57555755

5756+
bool EmitTLSUnsupportedError = false;
57565757
if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) {
57575758
// C++11 [dcl.stc]p4:
57585759
// When thread_local is applied to a variable of block scope the
@@ -5767,10 +5768,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
57675768
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
57685769
diag::err_thread_non_global)
57695770
<< DeclSpec::getSpecifierName(TSCS);
5770-
else if (!Context.getTargetInfo().isTLSSupported())
5771-
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
5772-
diag::err_thread_unsupported);
5773-
else
5771+
else if (!Context.getTargetInfo().isTLSSupported()) {
5772+
if (getLangOpts().CUDA)
5773+
// Postpone error emission until we've collected attributes required to
5774+
// figure out whether it's a host or device variable and whether the
5775+
// error should be ignored.
5776+
EmitTLSUnsupportedError = true;
5777+
else
5778+
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
5779+
diag::err_thread_unsupported);
5780+
} else
57745781
NewVD->setTSCSpec(TSCS);
57755782
}
57765783

@@ -5819,6 +5826,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
58195826
ProcessDeclAttributes(S, NewVD, D);
58205827

58215828
if (getLangOpts().CUDA) {
5829+
if (EmitTLSUnsupportedError && DeclAttrsMatchCUDAMode(getLangOpts(), NewVD))
5830+
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
5831+
diag::err_thread_unsupported);
58225832
// CUDA B.2.5: "__shared__ and __constant__ variables have implied static
58235833
// storage [duration]."
58245834
if (SC == SC_None && S->getFnParent() != nullptr &&

Diff for: ‎clang/lib/Sema/SemaStmtAsm.cpp

+2-10
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
124124
// The parser verifies that there is a string literal here.
125125
assert(AsmString->isAscii());
126126

127-
bool ValidateConstraints = true;
128-
if (getLangOpts().CUDA) {
129-
// In CUDA mode don't verify asm constraints in device functions during host
130-
// compilation and vice versa.
131-
bool InDeviceMode = getLangOpts().CUDAIsDevice;
132-
FunctionDecl *FD = getCurFunctionDecl();
133-
bool IsDeviceFunction =
134-
FD && (FD->hasAttr<CUDADeviceAttr>() || FD->hasAttr<CUDAGlobalAttr>());
135-
ValidateConstraints = IsDeviceFunction == InDeviceMode;
136-
}
127+
bool ValidateConstraints =
128+
DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl());
137129

138130
for (unsigned i = 0; i != NumOutputs; i++) {
139131
StringLiteral *Literal = Constraints[i];

Diff for: ‎clang/test/SemaCUDA/qualifiers.cu

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -triple nvptx-unknown-cuda -fsyntax-only -verify -fcuda-is-device %s
23

34
#include "Inputs/cuda.h"
45

6+
// Host (x86) supports TLS and device-side compilation should ignore
7+
// host variables. No errors in either case.
8+
int __thread host_tls_var;
9+
10+
#if defined(__CUDA_ARCH__)
11+
// NVPTX does not support TLS
12+
__device__ int __thread device_tls_var; // expected-error {{thread-local storage is not supported for the current target}}
13+
__shared__ int __thread shared_tls_var; // expected-error {{thread-local storage is not supported for the current target}}
14+
#else
15+
// Device-side vars should not produce any errors during host-side
16+
// compilation.
17+
__device__ int __thread device_tls_var;
18+
__shared__ int __thread shared_tls_var;
19+
#endif
20+
521
__global__ void g1(int x) {}
622
__global__ int g2(int x) { // expected-error {{must have void return type}}
723
return 1;

0 commit comments

Comments
 (0)
Please sign in to comment.