yaxunl updated this revision to Diff 62966. yaxunl added a comment. Removed the old representation of sampler type by i32.
http://reviews.llvm.org/D21567 Files: include/clang/AST/ASTContext.h include/clang/AST/BuiltinTypes.def include/clang/AST/OperationKinds.def include/clang/AST/Type.h include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Overload.h include/clang/Serialization/ASTBitCodes.h lib/AST/ASTContext.cpp lib/AST/Expr.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/MicrosoftMangle.cpp lib/AST/NSAPI.cpp lib/AST/Type.cpp lib/AST/TypeLoc.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprComplex.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CGOpenCLRuntime.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/ItaniumCXXABI.cpp lib/Edit/RewriteObjCFoundationAPI.cpp lib/Index/USRGeneration.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp lib/Serialization/ASTCommon.cpp lib/Serialization/ASTReader.cpp lib/StaticAnalyzer/Core/ExprEngineC.cpp test/CodeGenOpenCL/opencl_types.cl test/CodeGenOpenCL/sampler.cl test/SemaOpenCL/sampler_t.cl tools/libclang/CIndex.cpp
Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -1466,6 +1466,7 @@ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: Index: test/SemaOpenCL/sampler_t.cl =================================================================== --- test/SemaOpenCL/sampler_t.cl +++ test/SemaOpenCL/sampler_t.cl @@ -13,6 +13,7 @@ const sampler_t const_smp = 7; foo(glb_smp); foo(const_smp); + foo(argsmp); foo(5); // expected-error {{sampler_t variable required - got 'int'}} sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}} } Index: test/CodeGenOpenCL/sampler.cl =================================================================== --- /dev/null +++ test/CodeGenOpenCL/sampler.cl @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple spir-unknown-unknown -o - -O0 | FileCheck %s + +#define CLK_ADDRESS_CLAMP_TO_EDGE 2 +#define CLK_NORMALIZED_COORDS_TRUE 1 +#define CLK_FILTER_NEAREST 0x10 +#define CLK_FILTER_LINEAR 0x20 + +constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; + +// CHECK: %__sampler_initializer = type { i32, i32, i32 } +// CHECK: %__sampler = type opaque +// CHECK: [[glb_smp_init:@[-a-zA-Z$._][-a-zA-Z$._0-9]*]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 1 } +// CHECK: @glb_smp = global %__sampler_initializer addrspace(2)* [[glb_smp_init]] +// CHECK: [[smp_init:@[-a-zA-Z$._][-a-zA-Z$._0-9]*]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 0 } + +void fnc4smp(sampler_t s) {} +// CHECK: define spir_func void @fnc4smp(%__sampler addrspace(2)* % + +kernel void foo() { + sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_NEAREST; + // CHECK-LABEL: define spir_kernel void @foo() + // CHECK: [[smp_ptr:%[A-Za-z0-9_\.]+]] = alloca %__sampler_initializer addrspace(2)* + // CHECK: store %__sampler_initializer addrspace(2)* [[smp_init]], %__sampler_initializer addrspace(2)** [[smp_ptr]] + + fnc4smp(smp); + // CHECK: [[SINIT:%[0-9]+]] = load %__sampler_initializer addrspace(2)*, %__sampler_initializer addrspace(2)** [[smp_ptr]] + // CHECK: [[SAMP:%[0-9]+]] = call %__sampler addrspace(2)* @__translate_sampler_initializer(%__sampler_initializer addrspace(2)* [[SINIT]]) + // CHECK: call spir_func void @fnc4smp(%__sampler addrspace(2)* [[SAMP]]) + + fnc4smp(glb_smp); + // CHECK: [[SINIT:%[0-9]+]] = load %__sampler_initializer addrspace(2)*, %__sampler_initializer addrspace(2)** @glb_smp + // CHECK: [[SAMP:%[0-9]+]] = call %__sampler addrspace(2)* @__translate_sampler_initializer(%__sampler_initializer addrspace(2)* [[SINIT]]) + // CHECK: call spir_func void @fnc4smp(%__sampler addrspace(2)* [[SAMP]]) +} Index: test/CodeGenOpenCL/opencl_types.cl =================================================================== --- test/CodeGenOpenCL/opencl_types.cl +++ test/CodeGenOpenCL/opencl_types.cl @@ -1,39 +1,46 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - -O0 | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -o - -O0 | FileCheck %s -constant sampler_t glb_smp = 7; -// CHECK: constant i32 7 +#define CLK_ADDRESS_CLAMP_TO_EDGE 2 +#define CLK_NORMALIZED_COORDS_TRUE 1 +#define CLK_FILTER_NEAREST 0x10 +#define CLK_FILTER_LINEAR 0x20 + +constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE|CLK_NORMALIZED_COORDS_TRUE|CLK_FILTER_NEAREST; +// CHECK: [[SAMP1:.+]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 0 } +// CHECK: glb_smp = global %__sampler_initializer addrspace(2)* [[SAMP1]] +// CHECK: [[SAMP2:.+]] = internal addrspace(2) constant %__sampler_initializer { i32 1, i32 1, i32 1 } void fnc1(image1d_t img) {} -// CHECK: @fnc1(%opencl.image1d_ro_t* +// CHECK: @fnc1(%opencl.image1d_ro_t addrspace(1)* void fnc1arr(image1d_array_t img) {} -// CHECK: @fnc1arr(%opencl.image1d_array_ro_t* +// CHECK: @fnc1arr(%opencl.image1d_array_ro_t addrspace(1)* void fnc1buff(image1d_buffer_t img) {} -// CHECK: @fnc1buff(%opencl.image1d_buffer_ro_t* +// CHECK: @fnc1buff(%opencl.image1d_buffer_ro_t addrspace(1)* void fnc2(image2d_t img) {} -// CHECK: @fnc2(%opencl.image2d_ro_t* +// CHECK: @fnc2(%opencl.image2d_ro_t addrspace(1)* void fnc2arr(image2d_array_t img) {} -// CHECK: @fnc2arr(%opencl.image2d_array_ro_t* +// CHECK: @fnc2arr(%opencl.image2d_array_ro_t addrspace(1)* void fnc3(image3d_t img) {} -// CHECK: @fnc3(%opencl.image3d_ro_t* +// CHECK: @fnc3(%opencl.image3d_ro_t addrspace(1)* void fnc4smp(sampler_t s) {} -// CHECK-LABEL: define {{.*}}void @fnc4smp(i32 +// CHECK-LABEL: define {{.*}}void @fnc4smp(%__sampler addrspace(2)* kernel void foo(image1d_t img) { - sampler_t smp = 5; - // CHECK: alloca i32 + sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE|CLK_NORMALIZED_COORDS_TRUE|CLK_FILTER_LINEAR; + // CHECK: alloca %__sampler_initializer addrspace(2)* event_t evt; // CHECK: alloca %opencl.event_t* - // CHECK: store i32 5, + // CHECK: store %__sampler_initializer addrspace(2)* [[SAMP2]], fnc4smp(smp); - // CHECK: call {{.*}}void @fnc4smp(i32 + // CHECK: call {{.*}}void @fnc4smp(%__sampler addrspace(2)* fnc4smp(glb_smp); - // CHECK: call {{.*}}void @fnc4smp(i32 + // CHECK: call {{.*}}void @fnc4smp(%__sampler addrspace(2)* } void __attribute__((overloadable)) bad1(image1d_t b, image2d_t c, image2d_t d) {} Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -341,6 +341,8 @@ case CK_AnyPointerToBlockPointerCast: case CK_ObjCObjectLValueCast: case CK_ZeroToOCLEvent: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: case CK_LValueBitCast: { // Delegate to SValBuilder to process. SVal V = state->getSVal(Ex, LCtx); Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -6087,6 +6087,9 @@ case PREDEF_TYPE_SAMPLER_ID: T = Context.OCLSamplerTy; break; + case PREDEF_TYPE_SAMPLER_INIT_ID: + T = Context.OCLSamplerInitTy; + break; case PREDEF_TYPE_EVENT_ID: T = Context.OCLEventTy; break; Index: lib/Serialization/ASTCommon.cpp =================================================================== --- lib/Serialization/ASTCommon.cpp +++ lib/Serialization/ASTCommon.cpp @@ -138,6 +138,9 @@ case BuiltinType::OCLSampler: ID = PREDEF_TYPE_SAMPLER_ID; break; + case BuiltinType::OCLSamplerInit: + ID = PREDEF_TYPE_SAMPLER_ID; + break; case BuiltinType::OCLEvent: ID = PREDEF_TYPE_EVENT_ID; break; Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -1738,7 +1738,11 @@ From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; - } else { + } else if (ToType->isSamplerT() && From->getType()->isSamplerInitT()) { + SCS.Second = ICK_Sampler_Conversion; + FromType = ToType; + } + else { // No second conversion required. SCS.Second = ICK_Identity; } @@ -5105,6 +5109,7 @@ case ICK_TransparentUnionConversion: case ICK_Writeback_Conversion: case ICK_Zero_Event_Conversion: + case ICK_Sampler_Conversion: case ICK_C_Only_Conversion: return false; Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -4886,7 +4886,8 @@ QualType DestType, Expr *Initializer) { if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() || - !Initializer->isIntegerConstantExpr(S.getASTContext())) + (!Initializer->isIntegerConstantExpr(S.Context) && + !Initializer->getType()->isSamplerInitT())) return false; Sequence.AddOCLSamplerInitStep(DestType); @@ -6904,19 +6905,27 @@ } case SK_OCLSamplerInit: { - assert(Step->Type->isSamplerT() && - "Sampler initialization on non-sampler type."); - - QualType SourceType = CurInit.get()->getType(); - + Expr *Init = CurInit.get(); + QualType SourceType = Init->getType(); if (Entity.isParameterKind()) { - if (!SourceType->isSamplerT()) + if (SourceType->isSamplerInitT()) { + Init->setValueKind(VK_RValue); + CurInit = S.ImpCastExprToType(Init, Step->Type, + CK_OCLSamplerInitializerToSampler); + } else if (!SourceType->isSamplerT()) S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; - } else if (Entity.getKind() != InitializedEntity::EK_Variable) { - llvm_unreachable("Invalid EntityKind!"); + } else { + if (!Init->isConstantInitializer(S.Context, false)) + S.Diag(Kind.getLocation(), + diag::err_sampler_initializer_not_constant); + if (!SourceType->isIntegerType() || + 32 != S.Context.getIntWidth(SourceType)) + S.Diag(Kind.getLocation(), diag::err_sampler_initializer_not_integer) + << SourceType; + CurInit = S.ImpCastExprToType(Init, S.Context.OCLSamplerInitTy, + CK_IntToOCLSamplerInitializer); } - break; } case SK_OCLZeroEvent: { Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -3698,6 +3698,11 @@ From->getValueKind()).get(); break; + case ICK_Sampler_Conversion: + From = ImpCastExprToType(From, ToType, + CK_OCLSamplerInitializerToSampler).get(); + break; + case ICK_Lvalue_To_Rvalue: case ICK_Array_To_Pointer: case ICK_Function_To_Pointer: Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -7582,6 +7582,16 @@ } } + if (LHSType->isSamplerT() && RHSType->isIntegerType()) { + Kind = CK_IntToOCLSamplerInitializer; + return Compatible; + } + + if (LHSType->isSpecificBuiltinType(BuiltinType::OCLSamplerInit) && + RHSType->isSamplerT()) { + Kind = CK_OCLSamplerInitializerToSampler; + return Compatible; + } return Incompatible; } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -10305,6 +10305,9 @@ var->setInvalidDecl(); return; } + + if (var->getType()->isSamplerT()) + var->setType(Context.OCLSamplerInitTy); } // In Objective-C, don't allow jumps past the implicit initialization of a Index: lib/Index/USRGeneration.cpp =================================================================== --- lib/Index/USRGeneration.cpp +++ lib/Index/USRGeneration.cpp @@ -635,6 +635,7 @@ case BuiltinType::OCLNDRange: case BuiltinType::OCLReserveID: case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: IgnoreResults = true; return; case BuiltinType::ObjCId: Index: lib/Edit/RewriteObjCFoundationAPI.cpp =================================================================== --- lib/Edit/RewriteObjCFoundationAPI.cpp +++ lib/Edit/RewriteObjCFoundationAPI.cpp @@ -1076,6 +1076,8 @@ case CK_CopyAndAutoreleaseBlockObject: case CK_BuiltinFnToFnPtr: case CK_ZeroToOCLEvent: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: return false; case CK_BooleanToSignedIntegral: Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -2560,6 +2560,7 @@ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: Index: lib/CodeGen/CodeGenTypes.cpp =================================================================== --- lib/CodeGen/CodeGenTypes.cpp +++ lib/CodeGen/CodeGenTypes.cpp @@ -469,6 +469,7 @@ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -1145,6 +1145,12 @@ llvm::SanitizerStatReport &getSanStats(); + llvm::Constant* + createIntToSamplerConversion(const Expr *E, + CodeGenFunction *CGF, + llvm::GlobalVariable *InsertBefore = nullptr, + StringRef Name = ""); + private: llvm::Constant * GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D, Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -4288,3 +4288,58 @@ return *SanStats; } +llvm::Constant* +CodeGenModule::createIntToSamplerConversion(const Expr *E, + CodeGenFunction *CGF, + llvm::GlobalVariable *InsertBefore, + StringRef Name) { + llvm::Constant *C = EmitConstantExpr(E, E->getType(), CGF); + assert(C && "Sampler must be initialized by constant"); + assert(isa<llvm::ConstantInt>(C) && "Sampler must be initialized by integer"); + + llvm::StructType* + ConstSamplerTy = TheModule.getTypeByName("__sampler_initializer"); + if (!ConstSamplerTy ) { + llvm::Type* Elements[] = {Int32Ty, Int32Ty, Int32Ty}; + ConstSamplerTy = llvm::StructType::create(VMContext, Elements, + "__sampler_initializer"); + } + const llvm::ConstantInt *CI = static_cast<llvm::ConstantInt*>(C); + const uint64_t SamplerValue = CI->getValue().getZExtValue(); + // 32-bit value of sampler's initializer is interpreted as + // bit-field with the following structure: + // |unspecified|Filter|Addressing Mode| Normalized Coords| + // |31 6|5 4|3 1| 0| + // This structure corresponds to values of sampler properties from opencl.h + // Mapping these bits to values defined by SPIR-V specification. + unsigned NormalizedCoords = 0x01 & SamplerValue; + unsigned AddressingMode = (0x0E & SamplerValue) >> 1; + unsigned FilterMode = (0x30 & SamplerValue) >> 4; + // In SPIR sampler's filter bits are defined as the following + // #define CLK_FILTER_NEAREST 0x10 + // #define CLK_FILTER_LINEAR 0x20 + // corresponding to 1 and 2 in bits 4-5. + // SPIR-V defines sampler filter mode enum as: nearest=0, linear=1, + // Therefore, to convert FilterMode from SPIR to SPIR-V, + // FilterMode value must be decremented + if (FilterMode == 1 || FilterMode == 2) + --FilterMode; + else + getDiags().Report(Context.getFullLoc(E->getLocStart()), + diag::warn_sampler_initializer_invalid_bits) << "Filter Mode"; + if (AddressingMode > 4) + getDiags().Report(Context.getFullLoc(E->getLocStart()), + diag::warn_sampler_initializer_invalid_bits) << "Addressing Mode"; + + llvm::Constant *Initializer = llvm::ConstantStruct::get(ConstSamplerTy, + llvm::ConstantInt::get(Int32Ty, AddressingMode), + llvm::ConstantInt::get(Int32Ty, NormalizedCoords), + llvm::ConstantInt::get(Int32Ty, FilterMode), + nullptr); + auto AS = Context.getTargetAddressSpace(LangAS::opencl_constant); + return new llvm::GlobalVariable(TheModule, ConstSamplerTy, true, + llvm::GlobalVariable::InternalLinkage, + Initializer, Name + ".sampler.init", + InsertBefore, + llvm::GlobalVariable::NotThreadLocal, AS); +} Index: lib/CodeGen/CGOpenCLRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenCLRuntime.cpp +++ lib/CodeGen/CGOpenCLRuntime.cpp @@ -47,7 +47,18 @@ ImgAddrSpc); #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: - return llvm::IntegerType::get(Ctx, 32); + return llvm::PointerType::get(llvm::StructType::create( + Ctx, "__sampler"), + CGM.getContext().getTargetAddressSpace( + LangAS::opencl_constant)); + case BuiltinType::OCLSamplerInit: { + auto Int32Ty = llvm::IntegerType::get(Ctx, 32); + llvm::Type* Elements[] = {Int32Ty, Int32Ty, Int32Ty}; + return llvm::PointerType::get(llvm::StructType::create( + Ctx, Elements, "__sampler_initializer"), + CGM.getContext().getTargetAddressSpace( + LangAS::opencl_constant)); + } case BuiltinType::OCLEvent: return llvm::PointerType::get(llvm::StructType::create( Ctx, "opencl.event_t"), 0); Index: lib/CodeGen/CGExprScalar.cpp =================================================================== --- lib/CodeGen/CGExprScalar.cpp +++ lib/CodeGen/CGExprScalar.cpp @@ -1573,8 +1573,25 @@ return llvm::Constant::getNullValue(ConvertType(DestTy)); } + case CK_IntToOCLSamplerInitializer: + return CGF.CGM.createIntToSamplerConversion(E, &CGF); + + case CK_OCLSamplerInitializerToSampler: { + auto SampInit = Visit(E); + auto SamplerTy = CGF.CGM.getModule().getTypeByName("__sampler"); + if(!SamplerTy) + SamplerTy = llvm::StructType::create(VMContext, "__sampler"); + + auto AS = CGF.getContext().getTargetAddressSpace(LangAS::opencl_constant); + auto FTy = llvm::FunctionType::get(llvm::PointerType::get(SamplerTy, AS), + {SampInit->getType()}, false); + return CGF.Builder.CreateCall( + CGF.CGM.CreateRuntimeFunction(FTy, "__translate_sampler_initializer"), + {SampInit}); } + } // end of switch + llvm_unreachable("unknown scalar cast"); } Index: lib/CodeGen/CGExprConstant.cpp =================================================================== --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -690,6 +690,12 @@ case CK_ConstructorConversion: return C; + case CK_IntToOCLSamplerInitializer: + return CGM.createIntToSamplerConversion(subExpr, CGF); + + case CK_OCLSamplerInitializerToSampler: + llvm_unreachable("saw dependent cast!"); + case CK_Dependent: llvm_unreachable("saw dependent cast!"); case CK_BuiltinFnToFnPtr: Index: lib/CodeGen/CGExprComplex.cpp =================================================================== --- lib/CodeGen/CGExprComplex.cpp +++ lib/CodeGen/CGExprComplex.cpp @@ -484,6 +484,8 @@ case CK_BuiltinFnToFnPtr: case CK_ZeroToOCLEvent: case CK_AddressSpaceConversion: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: llvm_unreachable("invalid cast kind for complex value"); case CK_FloatingRealToComplex: Index: lib/CodeGen/CGExprAgg.cpp =================================================================== --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -750,6 +750,8 @@ case CK_BuiltinFnToFnPtr: case CK_ZeroToOCLEvent: case CK_AddressSpaceConversion: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: llvm_unreachable("cast kind invalid for aggregate types"); } } Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3584,6 +3584,8 @@ case CK_ARCExtendBlockObject: case CK_CopyAndAutoreleaseBlockObject: case CK_AddressSpaceConversion: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: return EmitUnsupportedLValue(E, "unexpected cast lvalue"); case CK_Dependent: Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -67,6 +67,8 @@ #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ llvm::DIType *SingletonId = nullptr; #include "clang/Basic/OpenCLImageTypes.def" + llvm::DIType *OCLSamplerDITy = nullptr; + llvm::DIType *OCLSamplerInitDITy = nullptr; llvm::DIType *OCLEventDITy = nullptr; llvm::DIType *OCLClkEventDITy = nullptr; llvm::DIType *OCLQueueDITy = nullptr; Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -476,9 +476,11 @@ SingletonId); #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: - return DBuilder.createBasicType( - "opencl_sampler_t", CGM.getContext().getTypeSize(BT), - CGM.getContext().getTypeAlign(BT), llvm::dwarf::DW_ATE_unsigned); + return getOrCreateStructPtrType("opencl_sampler_t", + OCLSamplerInitDITy); + case BuiltinType::OCLSamplerInit: + return getOrCreateStructPtrType("opencl_sampler_initializer_t", + OCLSamplerInitDITy); case BuiltinType::OCLEvent: return getOrCreateStructPtrType("opencl_event_t", OCLEventDITy); case BuiltinType::OCLClkEvent: Index: lib/AST/TypeLoc.cpp =================================================================== --- lib/AST/TypeLoc.cpp +++ lib/AST/TypeLoc.cpp @@ -338,6 +338,7 @@ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -2595,6 +2595,8 @@ #include "clang/Basic/OpenCLImageTypes.def" case OCLSampler: return "sampler_t"; + case OCLSamplerInit: + return "samper_initializer_t"; case OCLEvent: return "event_t"; case OCLClkEvent: @@ -3570,6 +3572,7 @@ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: Index: lib/AST/NSAPI.cpp =================================================================== --- lib/AST/NSAPI.cpp +++ lib/AST/NSAPI.cpp @@ -450,6 +450,7 @@ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -1732,6 +1732,10 @@ Out << "PA"; mangleArtificalTagType(TTK_Struct, "ocl_sampler"); break; + case BuiltinType::OCLSamplerInit: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_sampler_init"); + break; case BuiltinType::OCLEvent: Out << "PA"; mangleArtificalTagType(TTK_Struct, "ocl_event"); Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -2127,6 +2127,9 @@ case BuiltinType::OCLSampler: Out << "11ocl_sampler"; break; + case BuiltinType::OCLSamplerInit: + Out << "16ocl_sampler_init"; + break; case BuiltinType::OCLEvent: Out << "9ocl_event"; break; Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -6416,6 +6416,7 @@ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: @@ -8035,6 +8036,8 @@ case CK_ZeroToOCLEvent: case CK_NonAtomicToAtomic: case CK_AddressSpaceConversion: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: llvm_unreachable("invalid cast kind for integral value"); case CK_BitCast: @@ -8526,6 +8529,8 @@ case CK_ZeroToOCLEvent: case CK_NonAtomicToAtomic: case CK_AddressSpaceConversion: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: llvm_unreachable("invalid cast kind for complex value"); case CK_LValueToRValue: Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -1570,6 +1570,8 @@ case CK_ARCReclaimReturnedObject: case CK_ARCExtendBlockObject: case CK_ZeroToOCLEvent: + case CK_IntToOCLSamplerInitializer: + case CK_OCLSamplerInitializerToSampler: assert(!getType()->isBooleanType() && "unheralded conversion to bool"); goto CheckNoBasePath; @@ -2748,7 +2750,9 @@ CE->getCastKind() == CK_ToUnion || CE->getCastKind() == CK_ConstructorConversion || CE->getCastKind() == CK_NonAtomicToAtomic || - CE->getCastKind() == CK_AtomicToNonAtomic) + CE->getCastKind() == CK_AtomicToNonAtomic || + CE->getCastKind() == CK_IntToOCLSamplerInitializer || + CE->getCastKind() == CK_OCLSamplerInitializerToSampler) return CE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit); break; Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -1091,6 +1091,7 @@ #include "clang/Basic/OpenCLImageTypes.def" InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); + InitBuiltinType(OCLSamplerInitTy, BuiltinType::OCLSamplerInit); InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent); InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue); @@ -1661,11 +1662,18 @@ Width = Target->getPointerWidth(0); Align = Target->getPointerAlign(0); break; - case BuiltinType::OCLSampler: - // Samplers are modeled as integers. - Width = Target->getIntWidth(); - Align = Target->getIntAlign(); + case BuiltinType::OCLSampler: { + auto AS = getTargetAddressSpace(LangAS::opencl_constant); + Width = Target->getPointerWidth(AS); + Align = Target->getPointerAlign(AS); break; + } + case BuiltinType::OCLSamplerInit: { + auto AS = getTargetAddressSpace(LangAS::opencl_constant); + Width = Target->getPointerWidth(AS); + Align = Target->getPointerAlign(AS); + break; + } case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: @@ -5512,6 +5520,7 @@ case BuiltinType::OCLNDRange: case BuiltinType::OCLReserveID: case BuiltinType::OCLSampler: + case BuiltinType::OCLSamplerInit: case BuiltinType::Dependent: #define BUILTIN_TYPE(KIND, ID) #define PLACEHOLDER_TYPE(KIND, ID) \ Index: include/clang/Serialization/ASTBitCodes.h =================================================================== --- include/clang/Serialization/ASTBitCodes.h +++ include/clang/Serialization/ASTBitCodes.h @@ -796,6 +796,8 @@ PREDEF_TYPE_OMP_ARRAY_SECTION = 43, /// \brief The '__float128' type PREDEF_TYPE_FLOAT128_ID = 44, + /// \brief Internal OpenCL sampler initializer type + PREDEF_TYPE_SAMPLER_INIT_ID = 45, /// \brief OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, Index: include/clang/Sema/Overload.h =================================================================== --- include/clang/Sema/Overload.h +++ include/clang/Sema/Overload.h @@ -84,6 +84,7 @@ ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10) ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++ + ICK_Sampler_Conversion, ///< Sampler initializer to sampler for OpenCL ICK_Num_Conversion_Kinds, ///< The number of conversion kinds }; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -7862,6 +7862,12 @@ "the event_t type can only be used with __private address space qualifier">; def err_expected_kernel_void_return_type : Error< "kernel must have void return type">; +def err_sampler_initializer_not_integer : Error< + "sampler_t initialization requires 32-bit integer, not %0">; +def warn_sampler_initializer_invalid_bits : Warning< + "Sampler initializer has invalid %0 bits">, InGroup<SpirCompat>; +def err_sampler_initializer_not_constant : Error< + "sampler_t initialization requires compile time constant">; def err_sampler_argument_required : Error< "sampler_t variable required - got %0">; def err_wrong_sampler_addressspace: Error< Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -871,3 +871,7 @@ def OptionIgnored : DiagGroup<"option-ignored">; def UnknownArgument : DiagGroup<"unknown-argument">; + +// A warning group for warnings about code that clang accepts when +// compiling OpenCL C/C++ but which is not compatible with the SPIR spec. +def SpirCompat : DiagGroup<"spir-compat">; \ No newline at end of file Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1738,6 +1738,7 @@ bool isImageType() const; // Any OpenCL image type bool isSamplerT() const; // OpenCL sampler_t + bool isSamplerInitT() const; // Internal sampler_init_t bool isEventT() const; // OpenCL event_t bool isClkEventT() const; // OpenCL clk_event_t bool isQueueT() const; // OpenCL queue_t @@ -5597,6 +5598,10 @@ return isSpecificBuiltinType(BuiltinType::OCLSampler); } +inline bool Type::isSamplerInitT() const { + return isSpecificBuiltinType(BuiltinType::OCLSamplerInit); +} + inline bool Type::isEventT() const { return isSpecificBuiltinType(BuiltinType::OCLEvent); } @@ -5630,7 +5635,8 @@ inline bool Type::isOpenCLSpecificType() const { return isSamplerT() || isEventT() || isImageType() || isClkEventT() || - isQueueT() || isNDRangeT() || isReserveIDT() || isPipeType(); + isQueueT() || isNDRangeT() || isReserveIDT() || isPipeType() || + isSamplerInitT(); } inline bool Type::isTemplateTypeParmType() const { Index: include/clang/AST/OperationKinds.def =================================================================== --- include/clang/AST/OperationKinds.def +++ include/clang/AST/OperationKinds.def @@ -324,6 +324,11 @@ // Convert a pointer to a different address space. CAST_OPERATION(AddressSpaceConversion) +// Convert an integer initializer to an OpenCL sampler initializer. +CAST_OPERATION(IntToOCLSamplerInitializer) + +// Convert an OpenCL sampler initializer to OpenCL sampler. +CAST_OPERATION(OCLSamplerInitializerToSampler) //===- Binary Operations -------------------------------------------------===// // Operators listed in order of precedence. Index: include/clang/AST/BuiltinTypes.def =================================================================== --- include/clang/AST/BuiltinTypes.def +++ include/clang/AST/BuiltinTypes.def @@ -160,6 +160,9 @@ // OpenCL sampler_t. BUILTIN_TYPE(OCLSampler, OCLSamplerTy) +// Internal OpenCL sampler initializer type. +BUILTIN_TYPE(OCLSamplerInit, OCLSamplerInitTy) + // OpenCL event_t. BUILTIN_TYPE(OCLEvent, OCLEventTy) Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -906,7 +906,7 @@ #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ CanQualType SingletonId; #include "clang/Basic/OpenCLImageTypes.def" - CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; + CanQualType OCLSamplerTy, OCLSamplerInitTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy; CanQualType OMPArraySectionTy;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits