diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 4aa63143a66cd..6974df200a6cf 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -61,6 +61,9 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo { QualType SampledType, CodeGenModule &CGM) const; void setOCLKernelStubCallingConvention(const FunctionType *&FT) const override; + llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM, + llvm::PointerType *T, + QualType QT) const override; }; class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo { public: @@ -240,6 +243,31 @@ void CommonSPIRTargetCodeGenInfo::setOCLKernelStubCallingConvention( FT, FT->getExtInfo().withCallingConv(CC_SpirFunction)); } +// LLVM currently assumes a null pointer has the bit pattern 0, but some GPU +// targets use a non-zero encoding for null in certain address spaces. +// Because SPIR(-V) is a virtual target and the bit pattern of a non-generic +// null is unspecified, materialize non-generic null via an addrspacecast from +// the generic null. +// This allows later lowering to substitute the target’s real sentinel value. +llvm::Constant * +CommonSPIRTargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM, + llvm::PointerType *PT, + QualType QT) const { + LangAS AS; + if (QT->getUnqualifiedDesugaredType()->isNullPtrType()) + AS = LangAS::Default; + else + AS = QT->getPointeeType().getAddressSpace(); + if (AS == LangAS::Default || AS == LangAS::opencl_generic) + return llvm::ConstantPointerNull::get(PT); + + auto &Ctx = CGM.getContext(); + auto NPT = llvm::PointerType::get( + PT->getContext(), Ctx.getTargetAddressSpace(LangAS::opencl_generic)); + return llvm::ConstantExpr::getAddrSpaceCast( + llvm::ConstantPointerNull::get(NPT), PT); +} + LangAS SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const { diff --git a/clang/test/CodeGenOpenCL/builtins.cl b/clang/test/CodeGenOpenCL/builtins.cl index aa666c7b671b9..708d1b84f4838 100644 --- a/clang/test/CodeGenOpenCL/builtins.cl +++ b/clang/test/CodeGenOpenCL/builtins.cl @@ -62,19 +62,19 @@ void testBranchingOnAddressSpaceCast(generic long* ptr) { if (to_global(ptr)) (void)0; // CHECK: [[P:%[0-9]+]] = call spir_func [[GLOBAL_VOID:ptr addrspace\(1\)]] @__to_global([[GENERIC_VOID:ptr addrspace\(4\)]] {{%[0-9]+}}) - // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(1) [[P]], null + // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(1) [[P]], addrspacecast (ptr addrspace(4) null to ptr addrspace(1)) // CHECK-NEXT: br i1 [[BOOL]] if (to_local(ptr)) (void)0; // CHECK: [[P:%[0-9]+]] = call spir_func [[LOCAL_VOID:ptr addrspace\(3\)]] @__to_local([[GENERIC_VOID]] {{%[0-9]+}}) - // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(3) [[P]], null + // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(3) [[P]], addrspacecast (ptr addrspace(4) null to ptr addrspace(3)) // CHECK-NEXT: br i1 [[BOOL]] if (to_private(ptr)) (void)0; // CHECK: [[P:%[0-9]+]] = call spir_func [[PRIVATE_VOID:ptr]] @__to_private([[GENERIC_VOID]] {{%[0-9]+}}) - // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr [[P]], null + // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr [[P]], addrspacecast (ptr addrspace(4) null to ptr) // CHECK-NEXT: br i1 [[BOOL]] } diff --git a/clang/test/CodeGenSYCL/address-space-conversions.cpp b/clang/test/CodeGenSYCL/address-space-conversions.cpp index fa7acb0d99433..ea52be53ea906 100644 --- a/clang/test/CodeGenSYCL/address-space-conversions.cpp +++ b/clang/test/CodeGenSYCL/address-space-conversions.cpp @@ -35,9 +35,9 @@ void tmpl(T t) {} // CHECK-DAG: [[LOC]].ascast = addrspacecast ptr [[LOC]] to ptr addrspace(4) // CHECK-DAG: [[PRIV]].ascast = addrspacecast ptr [[PRIV]] to ptr addrspace(4) LOC = nullptr; - // CHECK-DAG: store ptr addrspace(3) null, ptr addrspace(4) [[LOC]].ascast, align 8 + // CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr addrspace(4) null to ptr addrspace(3)), ptr addrspace(4) [[LOC]].ascast, align 8 GLOB = nullptr; - // CHECK-DAG: store ptr addrspace(1) null, ptr addrspace(4) [[GLOB]].ascast, align 8 + // CHECK-DAG: store ptr addrspace(1) addrspacecast (ptr addrspace(4) null to ptr addrspace(1)), ptr addrspace(4) [[GLOB]].ascast, align 8 // Explicit conversions // From named address spaces to default address space