Skip to content

Commit eb735ee

Browse files
committed
[SYCL] Enable OpenCL diagnostics for sampler in SYCL mode
Selectively enabled a few OpenCL diagnostics for sampler type as some diagnostics trigger on SYCL use cases. For instance, OpenCL kernel in SYCL mode initializes lambda captures with the kernel argument values. This initialization code for sampler emits errors because OpenCL disallows sampler on the right hand side of the binary operators - these are supposed to be used only by built-in functions. Another potential issue is the lambda object itself - captured sampler is a member of the lambda object and OpenCL doesn't allow composite types with samplers. SPIR-V produced from SYCL should be okay as lambda object can be removed by standard LLVM transformation passes. Signed-off-by: Alexey Bader <alexey.bader@intel.com>
1 parent 208cd7c commit eb735ee

File tree

4 files changed

+31
-29
lines changed

4 files changed

+31
-29
lines changed

clang/lib/Sema/SemaDecl.cpp

+20-20
Original file line numberDiff line numberDiff line change
@@ -6347,6 +6347,26 @@ NamedDecl *Sema::ActOnVariableDeclarator(
63476347
return nullptr;
63486348
}
63496349

6350+
if (R->isSamplerT()) {
6351+
// OpenCL v1.2 s6.9.b p4:
6352+
// The sampler type cannot be used with the __local and __global address
6353+
// space qualifiers.
6354+
if (R.getAddressSpace() == LangAS::opencl_local ||
6355+
R.getAddressSpace() == LangAS::opencl_global) {
6356+
Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
6357+
}
6358+
6359+
// OpenCL v1.2 s6.12.14.1:
6360+
// A global sampler must be declared with either the constant address
6361+
// space qualifier or with the const qualifier.
6362+
if (DC->isTranslationUnit() &&
6363+
!(R.getAddressSpace() == LangAS::opencl_constant ||
6364+
R.isConstQualified())) {
6365+
Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler);
6366+
D.setInvalidType();
6367+
}
6368+
}
6369+
63506370
if (getLangOpts().OpenCL) {
63516371
// OpenCL v2.0 s6.9.b - Image type can only be used as a function argument.
63526372
// OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function
@@ -6392,26 +6412,6 @@ NamedDecl *Sema::ActOnVariableDeclarator(
63926412
}
63936413
}
63946414

6395-
if (R->isSamplerT()) {
6396-
// OpenCL v1.2 s6.9.b p4:
6397-
// The sampler type cannot be used with the __local and __global address
6398-
// space qualifiers.
6399-
if (R.getAddressSpace() == LangAS::opencl_local ||
6400-
R.getAddressSpace() == LangAS::opencl_global) {
6401-
Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
6402-
}
6403-
6404-
// OpenCL v1.2 s6.12.14.1:
6405-
// A global sampler must be declared with either the constant address
6406-
// space qualifier or with the const qualifier.
6407-
if (DC->isTranslationUnit() &&
6408-
!(R.getAddressSpace() == LangAS::opencl_constant ||
6409-
R.isConstQualified())) {
6410-
Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler);
6411-
D.setInvalidType();
6412-
}
6413-
}
6414-
64156415
// OpenCL v1.2 s6.9.r:
64166416
// The event type cannot be used with the __local, __constant and __global
64176417
// address space qualifiers.

clang/lib/Sema/SemaExpr.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -13046,7 +13046,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
1304613046
bool CanOverflow = false;
1304713047

1304813048
bool ConvertHalfVec = false;
13049-
if (getLangOpts().OpenCL) {
13049+
if (getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) {
1305013050
QualType Ty = InputExpr->getType();
1305113051
// The only legal unary operation for atomics is '&'.
1305213052
if ((Opc != UO_AddrOf && Ty->isAtomicType()) ||

clang/lib/Sema/SemaInit.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -5319,9 +5319,9 @@ static bool TryOCLSamplerInitialization(Sema &S,
53195319
InitializationSequence &Sequence,
53205320
QualType DestType,
53215321
Expr *Initializer) {
5322-
if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() ||
5322+
if (!DestType->isSamplerT() ||
53235323
(!Initializer->isIntegerConstantExpr(S.Context) &&
5324-
!Initializer->getType()->isSamplerT()))
5324+
!Initializer->getType()->isSamplerT()))
53255325
return false;
53265326

53275327
Sequence.AddOCLSamplerInitStep(DestType);
@@ -5634,6 +5634,9 @@ void InitializationSequence::InitializeFrom(Sema &S,
56345634
bool allowObjCWritebackConversion = S.getLangOpts().ObjCAutoRefCount &&
56355635
Entity.isParameterKind();
56365636

5637+
if (TryOCLSamplerInitialization(S, *this, DestType, Initializer))
5638+
return;
5639+
56375640
// We're at the end of the line for C: it's either a write-back conversion
56385641
// or it's a C assignment. There's no need to check anything else.
56395642
if (!S.getLangOpts().CPlusPlus) {
@@ -5643,9 +5646,6 @@ void InitializationSequence::InitializeFrom(Sema &S,
56435646
return;
56445647
}
56455648

5646-
if (TryOCLSamplerInitialization(S, *this, DestType, Initializer))
5647-
return;
5648-
56495649
if (TryOCLZeroOpaqueTypeInitialization(S, *this, DestType, Initializer))
56505650
return;
56515651

clang/lib/Sema/SemaType.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -2322,7 +2322,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
23222322
// OpenCL v2.0 s6.12.5 - Arrays of blocks are not supported.
23232323
// OpenCL v2.0 s6.16.13.1 - Arrays of pipe type are not supported.
23242324
// OpenCL v2.0 s6.9.b - Arrays of image/sampler type are not supported.
2325-
if (getLangOpts().OpenCL) {
2325+
if (getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) {
23262326
const QualType ArrType = Context.getBaseElementType(T);
23272327
if (ArrType->isBlockPointerType() || ArrType->isPipeType() ||
23282328
ArrType->isSamplerT() || ArrType->isImageType()) {
@@ -4409,7 +4409,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
44094409
// OpenCL v2.0 s6.9b - Pointer to image/sampler cannot be used.
44104410
// OpenCL v2.0 s6.13.16.1 - Pointer to pipe cannot be used.
44114411
// OpenCL v2.0 s6.12.5 - Pointers to Blocks are not allowed.
4412-
if (LangOpts.OpenCL) {
4412+
if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) {
44134413
if (T->isImageType() || T->isSamplerT() || T->isPipeType() ||
44144414
T->isBlockPointerType()) {
44154415
S.Diag(D.getIdentifierLoc(), diag::err_opencl_pointer_to_type) << T;
@@ -4607,7 +4607,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
46074607
}
46084608
}
46094609

4610-
if (LangOpts.OpenCL) {
4610+
if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) {
46114611
// OpenCL v2.0 s6.12.5 - A block cannot be the return value of a
46124612
// function.
46134613
if (T->isBlockPointerType() || T->isImageType() || T->isSamplerT() ||
@@ -4619,7 +4619,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
46194619
// OpenCL doesn't support variadic functions and blocks
46204620
// (s6.9.e and s6.12.5 OpenCL v2.0) except for printf.
46214621
// We also allow here any toolchain reserved identifiers.
4622+
// FIXME: Use deferred diagnostics engine to skip host side issues.
46224623
if (FTI.isVariadic &&
4624+
!LangOpts.SYCLIsDevice &&
46234625
!(D.getIdentifier() &&
46244626
((D.getIdentifier()->getName() == "printf" &&
46254627
(LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) ||

0 commit comments

Comments
 (0)