@@ -83,6 +83,106 @@ static CXXRecordDecl *getKernelObjectType(FunctionDecl *Caller) {
83
83
return (*Caller->param_begin())->getType()->getAsCXXRecordDecl();
84
84
}
85
85
86
+ // This information is from Section 4.13 of the SYCL spec
87
+ // https://www.khronos.org/registry/SYCL/specs/sycl-1.2.1.pdf
88
+ // This function returns false if the math lib function
89
+ // corresponding to the input builtin is not supported
90
+ // for SYCL
91
+ static bool IsSyclMathFunc(unsigned BuiltinID) {
92
+ switch (BuiltinID) {
93
+ case Builtin::BIlround:
94
+ case Builtin::BI__builtin_lround:
95
+ case Builtin::BIceill:
96
+ case Builtin::BI__builtin_ceill:
97
+ case Builtin::BIcopysignl:
98
+ case Builtin::BI__builtin_copysignl:
99
+ case Builtin::BIcosl:
100
+ case Builtin::BI__builtin_cosl:
101
+ case Builtin::BIexpl:
102
+ case Builtin::BI__builtin_expl:
103
+ case Builtin::BIexp2l:
104
+ case Builtin::BI__builtin_exp2l:
105
+ case Builtin::BIfabsl:
106
+ case Builtin::BI__builtin_fabsl:
107
+ case Builtin::BIfloorl:
108
+ case Builtin::BI__builtin_floorl:
109
+ case Builtin::BIfmal:
110
+ case Builtin::BI__builtin_fmal:
111
+ case Builtin::BIfmaxl:
112
+ case Builtin::BI__builtin_fmaxl:
113
+ case Builtin::BIfminl:
114
+ case Builtin::BI__builtin_fminl:
115
+ case Builtin::BIfmodl:
116
+ case Builtin::BI__builtin_fmodl:
117
+ case Builtin::BIlogl:
118
+ case Builtin::BI__builtin_logl:
119
+ case Builtin::BIlog10l:
120
+ case Builtin::BI__builtin_log10l:
121
+ case Builtin::BIlog2l:
122
+ case Builtin::BI__builtin_log2l:
123
+ case Builtin::BIpowl:
124
+ case Builtin::BI__builtin_powl:
125
+ case Builtin::BIrintl:
126
+ case Builtin::BI__builtin_rintl:
127
+ case Builtin::BIroundl:
128
+ case Builtin::BI__builtin_roundl:
129
+ case Builtin::BIsinl:
130
+ case Builtin::BI__builtin_sinl:
131
+ case Builtin::BIsqrtl:
132
+ case Builtin::BI__builtin_sqrtl:
133
+ case Builtin::BItruncl:
134
+ case Builtin::BI__builtin_truncl:
135
+ case Builtin::BIlroundl:
136
+ case Builtin::BI__builtin_lroundl:
137
+ case Builtin::BIceilf:
138
+ case Builtin::BI__builtin_ceilf:
139
+ case Builtin::BIcopysignf:
140
+ case Builtin::BI__builtin_copysignf:
141
+ case Builtin::BIcosf:
142
+ case Builtin::BI__builtin_cosf:
143
+ case Builtin::BIexpf:
144
+ case Builtin::BI__builtin_expf:
145
+ case Builtin::BIexp2f:
146
+ case Builtin::BI__builtin_exp2f:
147
+ case Builtin::BIfabsf:
148
+ case Builtin::BI__builtin_fabsf:
149
+ case Builtin::BIfloorf:
150
+ case Builtin::BI__builtin_floorf:
151
+ case Builtin::BIfmaf:
152
+ case Builtin::BI__builtin_fmaf:
153
+ case Builtin::BIfmaxf:
154
+ case Builtin::BI__builtin_fmaxf:
155
+ case Builtin::BIfminf:
156
+ case Builtin::BI__builtin_fminf:
157
+ case Builtin::BIfmodf:
158
+ case Builtin::BI__builtin_fmodf:
159
+ case Builtin::BIlogf:
160
+ case Builtin::BI__builtin_logf:
161
+ case Builtin::BIlog10f:
162
+ case Builtin::BI__builtin_log10f:
163
+ case Builtin::BIlog2f:
164
+ case Builtin::BI__builtin_log2f:
165
+ case Builtin::BIpowf:
166
+ case Builtin::BI__builtin_powf:
167
+ case Builtin::BIrintf:
168
+ case Builtin::BI__builtin_rintf:
169
+ case Builtin::BIroundf:
170
+ case Builtin::BI__builtin_roundf:
171
+ case Builtin::BIsinf:
172
+ case Builtin::BI__builtin_sinf:
173
+ case Builtin::BIsqrtf:
174
+ case Builtin::BI__builtin_sqrtf:
175
+ case Builtin::BItruncf:
176
+ case Builtin::BI__builtin_truncf:
177
+ case Builtin::BIlroundf:
178
+ case Builtin::BI__builtin_lroundf:
179
+ return false;
180
+ default:
181
+ break;
182
+ }
183
+ return true;
184
+ }
185
+
86
186
class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> {
87
187
public:
88
188
MarkDeviceFunction(Sema &S)
@@ -119,7 +219,28 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> {
119
219
SemaRef.addSyclDeviceDecl(Def);
120
220
}
121
221
}
122
- } else if (!SemaRef.getLangOpts().SYCLAllowFuncPtr &&
222
+ if (auto const *FD = dyn_cast<FunctionDecl>(Callee)) {
223
+ //FIXME: We need check all target specified attributes for error if that
224
+ //function with attribute can not be called from sycl kernel. The info
225
+ //is in ParsedAttr. We don't have to map from Attr to ParsedAttr
226
+ //currently. Erich is currently working on that in LLVM, once that is
227
+ //committed we need to change this".
228
+ if (FD->hasAttr<DLLImportAttr>()) {
229
+ SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict)
230
+ << Sema::KernelCallDllimportFunction;
231
+ SemaRef.Diag(FD->getLocation(), diag::note_callee_decl) << FD;
232
+ }
233
+ }
234
+ // Specifically check if the math library function corresponding to this
235
+ // builtin is supported for SYCL
236
+ unsigned BuiltinID = (Callee ? Callee->getBuiltinID() : 0);
237
+ if (BuiltinID && !IsSyclMathFunc(BuiltinID)) {
238
+ StringRef Name = SemaRef.Context.BuiltinInfo.getName(BuiltinID);
239
+ SemaRef.Diag(e->getExprLoc(),
240
+ diag::err_builtin_target_unsupported)
241
+ << Name << "SYCL device";
242
+ }
243
+ } else if ((!SemaRef.getLangOpts().SYCLAllowFuncPtr) &&
123
244
!e->isTypeDependent())
124
245
SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict)
125
246
<< Sema::KernelCallFunctionPointer;
@@ -197,9 +318,12 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> {
197
318
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict)
198
319
<< Sema::KernelNonConstStaticDataVariable;
199
320
else if (!IsConst && VD->hasGlobalStorage() && !VD->isStaticLocal() &&
200
- !VD->isStaticDataMember() && !isa<ParmVarDecl>(VD))
321
+ !VD->isStaticDataMember() && !isa<ParmVarDecl>(VD)) {
322
+ if (VD->getTLSKind() != VarDecl::TLS_None)
323
+ SemaRef.Diag(E->getLocation(), diag::err_thread_unsupported);
201
324
SemaRef.Diag(E->getLocation(), diag::err_sycl_restrict)
202
325
<< Sema::KernelGlobalVariable;
326
+ }
203
327
if (!VD->isLocalVarDeclOrParm() && VD->hasGlobalStorage()) {
204
328
VD->addAttr(SYCLDeviceAttr::CreateImplicit(SemaRef.Context));
205
329
SemaRef.addSyclDeviceDecl(VD);
0 commit comments