Fznamznon created this revision. Herald added subscribers: cfe-commits, Anastasia, ebevhan, yaxunl. Herald added a project: clang. Fznamznon added reviewers: bader, Anastasia.
sampler_t type name is replaced with __ocl_sampler_t to avoid potential collisions with user types. 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. Patch by Alexey Bader <alexey.ba...@intel.com> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D63710 Files: clang/lib/AST/ASTContext.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaInit.cpp clang/lib/Sema/SemaType.cpp clang/test/CodeGenSYCL/ocl_sampler.cpp clang/test/SemaSYCL/ocl_sampler.cpp
Index: clang/test/SemaSYCL/ocl_sampler.cpp =================================================================== --- /dev/null +++ clang/test/SemaSYCL/ocl_sampler.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++11 -fsycl-is-device -fsyntax-only -verify %s + +#define CLK_ADDRESS_CLAMP_TO_EDGE 2 +#define CLK_NORMALIZED_COORDS_TRUE 1 +#define CLK_FILTER_NEAREST 0x10 +#define CLK_FILTER_LINEAR 0x20 + +__ocl_sampler_t global_nonconst_smp = 0; // expected-error {{global sampler requires a const or constant address space qualifier}} +const __ocl_sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; + +void foo(__ocl_sampler_t argsmp) { + __ocl_sampler_t smp1 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; + __ocl_sampler_t smp2 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_NEAREST; + &smp1; //expected-error{{invalid argument type '__ocl_sampler_t' (aka 'sampler_t') to unary expression}} + *smp2; //expected-error{{invalid argument type '__ocl_sampler_t' (aka 'sampler_t') to unary expression}} + + const __ocl_sampler_t const_smp6 = 0x100000000LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} + + __ocl_sampler_t sa[] = {argsmp, glb_smp}; // expected-error {{array of '__ocl_sampler_t' (aka 'sampler_t') type is invalid in OpenCL}} +} + +void foo_smplr_ptr(__ocl_sampler_t*); // expected-error{{pointer to type '__ocl_sampler_t' (aka 'sampler_t') is invalid in OpenCL}} Index: clang/test/CodeGenSYCL/ocl_sampler.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenSYCL/ocl_sampler.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple spir64-unknown-unknown -std=c++11 -fsycl-is-device -S -emit-llvm %s -o - | FileCheck %s + +// CHECK: %opencl.sampler_t = type opaque + +void foo(__ocl_sampler_t s) {} +// CHECK: define spir_func void @{{.*}}foo{{.*}}(%opencl.sampler_t addrspace(2)* Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -2320,7 +2320,7 @@ // OpenCL v2.0 s6.12.5 - Arrays of blocks are not supported. // OpenCL v2.0 s6.16.13.1 - Arrays of pipe type are not supported. // OpenCL v2.0 s6.9.b - Arrays of image/sampler type are not supported. - if (getLangOpts().OpenCL) { + if (getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) { const QualType ArrType = Context.getBaseElementType(T); if (ArrType->isBlockPointerType() || ArrType->isPipeType() || ArrType->isSamplerT() || ArrType->isImageType()) { @@ -4407,7 +4407,7 @@ // OpenCL v2.0 s6.9b - Pointer to image/sampler cannot be used. // OpenCL v2.0 s6.13.16.1 - Pointer to pipe cannot be used. // OpenCL v2.0 s6.12.5 - Pointers to Blocks are not allowed. - if (LangOpts.OpenCL) { + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) { if (T->isImageType() || T->isSamplerT() || T->isPipeType() || T->isBlockPointerType()) { S.Diag(D.getIdentifierLoc(), diag::err_opencl_pointer_to_type) << T; @@ -4605,7 +4605,7 @@ } } - if (LangOpts.OpenCL) { + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) { // OpenCL v2.0 s6.12.5 - A block cannot be the return value of a // function. if (T->isBlockPointerType() || T->isImageType() || T->isSamplerT() || @@ -4617,7 +4617,9 @@ // OpenCL doesn't support variadic functions and blocks // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf. // We also allow here any toolchain reserved identifiers. + // FIXME: Use deferred diagnostics engine to skip host side issues. if (FTI.isVariadic && + !LangOpts.SYCLIsDevice && !(D.getIdentifier() && ((D.getIdentifier()->getName() == "printf" && (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) || Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -5325,9 +5325,9 @@ InitializationSequence &Sequence, QualType DestType, Expr *Initializer) { - if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() || + if (!DestType->isSamplerT() || (!Initializer->isIntegerConstantExpr(S.Context) && - !Initializer->getType()->isSamplerT())) + !Initializer->getType()->isSamplerT())) return false; Sequence.AddOCLSamplerInitStep(DestType); @@ -5640,6 +5640,9 @@ bool allowObjCWritebackConversion = S.getLangOpts().ObjCAutoRefCount && Entity.isParameterKind(); + if (TryOCLSamplerInitialization(S, *this, DestType, Initializer)) + return; + // We're at the end of the line for C: it's either a write-back conversion // or it's a C assignment. There's no need to check anything else. if (!S.getLangOpts().CPlusPlus) { @@ -5649,9 +5652,6 @@ return; } - if (TryOCLSamplerInitialization(S, *this, DestType, Initializer)) - return; - if (TryOCLZeroOpaqueTypeInitialization(S, *this, DestType, Initializer)) return; Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -13082,7 +13082,7 @@ bool CanOverflow = false; bool ConvertHalfVec = false; - if (getLangOpts().OpenCL) { + if (getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) { QualType Ty = InputExpr->getType(); // The only legal unary operation for atomics is '&'. if ((Opc != UO_AddrOf && Ty->isAtomicType()) || Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -6351,6 +6351,26 @@ return nullptr; } + if (R->isSamplerT()) { + // OpenCL v1.2 s6.9.b p4: + // The sampler type cannot be used with the __local and __global address + // space qualifiers. + if (R.getAddressSpace() == LangAS::opencl_local || + R.getAddressSpace() == LangAS::opencl_global) { + Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); + } + + // OpenCL v1.2 s6.12.14.1: + // A global sampler must be declared with either the constant address + // space qualifier or with the const qualifier. + if (DC->isTranslationUnit() && + !(R.getAddressSpace() == LangAS::opencl_constant || + R.isConstQualified())) { + Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler); + D.setInvalidType(); + } + } + if (getLangOpts().OpenCL) { // OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. // OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function @@ -6396,26 +6416,6 @@ } } - if (R->isSamplerT()) { - // OpenCL v1.2 s6.9.b p4: - // The sampler type cannot be used with the __local and __global address - // space qualifiers. - if (R.getAddressSpace() == LangAS::opencl_local || - R.getAddressSpace() == LangAS::opencl_global) { - Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); - } - - // OpenCL v1.2 s6.12.14.1: - // A global sampler must be declared with either the constant address - // space qualifier or with the const qualifier. - if (DC->isTranslationUnit() && - !(R.getAddressSpace() == LangAS::opencl_constant || - R.isConstQualified())) { - Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler); - D.setInvalidType(); - } - } - // OpenCL v1.2 s6.9.r: // The event type cannot be used with the __local, __constant and __global // address space qualifiers. Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -263,6 +263,10 @@ addImplicitTypedef("size_t", Context.getSizeType()); } + if (getLangOpts().SYCLIsDevice) { + addImplicitTypedef("__ocl_sampler_t", Context.OCLSamplerTy); + } + // Initialize predefined OpenCL types and supported extensions and (optional) // core features. if (getLangOpts().OpenCL) { Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -129,7 +129,7 @@ if (LangOpts.ObjC) createObjCRuntime(); - if (LangOpts.OpenCL) + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) createOpenCLRuntime(); if (LangOpts.OpenMP) createOpenMPRuntime(); Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -1283,7 +1283,7 @@ InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); - if (LangOpts.OpenCL) { + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) { #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ InitBuiltinType(SingletonId, BuiltinType::Id); #include "clang/Basic/OpenCLImageTypes.def"
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits