Skip to content

Commit 1ffff05

Browse files
authored
[clang][SPIR][SPIRV] Materialize non-generic null pointers via addrspacecast (#161773)
LLVM models ConstantPointerNull as all-zero, but some GPUs (e.g. AMDGPU and our downstream GPU target) use a non-zero sentinel for null in private / local address spaces. SPIR-V is a supported input for our GPU target. This PR preserves a canonical zero form in the generic AS while allowing later lowering to substitute the target’s real sentinel.
1 parent a4a9803 commit 1ffff05

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

clang/lib/CodeGen/Targets/SPIR.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo {
6161
QualType SampledType, CodeGenModule &CGM) const;
6262
void
6363
setOCLKernelStubCallingConvention(const FunctionType *&FT) const override;
64+
llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
65+
llvm::PointerType *T,
66+
QualType QT) const override;
6467
};
6568
class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo {
6669
public:
@@ -240,6 +243,29 @@ void CommonSPIRTargetCodeGenInfo::setOCLKernelStubCallingConvention(
240243
FT, FT->getExtInfo().withCallingConv(CC_SpirFunction));
241244
}
242245

246+
// LLVM currently assumes a null pointer has the bit pattern 0, but some GPU
247+
// targets use a non-zero encoding for null in certain address spaces.
248+
// Because SPIR(-V) is a generic target and the bit pattern of null in
249+
// non-generic AS is unspecified, materialize null in non-generic AS via an
250+
// addrspacecast from null in generic AS. This allows later lowering to
251+
// substitute the target's real sentinel value.
252+
llvm::Constant *
253+
CommonSPIRTargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM,
254+
llvm::PointerType *PT,
255+
QualType QT) const {
256+
LangAS AS = QT->getUnqualifiedDesugaredType()->isNullPtrType()
257+
? LangAS::Default
258+
: QT->getPointeeType().getAddressSpace();
259+
if (AS == LangAS::Default || AS == LangAS::opencl_generic)
260+
return llvm::ConstantPointerNull::get(PT);
261+
262+
auto &Ctx = CGM.getContext();
263+
auto NPT = llvm::PointerType::get(
264+
PT->getContext(), Ctx.getTargetAddressSpace(LangAS::opencl_generic));
265+
return llvm::ConstantExpr::getAddrSpaceCast(
266+
llvm::ConstantPointerNull::get(NPT), PT);
267+
}
268+
243269
LangAS
244270
SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
245271
const VarDecl *D) const {

clang/test/CodeGenOpenCL/builtins.cl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,19 @@ void testBranchingOnAddressSpaceCast(generic long* ptr) {
6262
if (to_global(ptr))
6363
(void)0;
6464
// CHECK: [[P:%[0-9]+]] = call spir_func [[GLOBAL_VOID:ptr addrspace\(1\)]] @__to_global([[GENERIC_VOID:ptr addrspace\(4\)]] {{%[0-9]+}})
65-
// CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(1) [[P]], null
65+
// CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(1) [[P]], addrspacecast (ptr addrspace(4) null to ptr addrspace(1))
6666
// CHECK-NEXT: br i1 [[BOOL]]
6767

6868
if (to_local(ptr))
6969
(void)0;
7070
// CHECK: [[P:%[0-9]+]] = call spir_func [[LOCAL_VOID:ptr addrspace\(3\)]] @__to_local([[GENERIC_VOID]] {{%[0-9]+}})
71-
// CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(3) [[P]], null
71+
// CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr addrspace(3) [[P]], addrspacecast (ptr addrspace(4) null to ptr addrspace(3))
7272
// CHECK-NEXT: br i1 [[BOOL]]
7373

7474
if (to_private(ptr))
7575
(void)0;
7676
// CHECK: [[P:%[0-9]+]] = call spir_func [[PRIVATE_VOID:ptr]] @__to_private([[GENERIC_VOID]] {{%[0-9]+}})
77-
// CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr [[P]], null
77+
// CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = icmp ne ptr [[P]], addrspacecast (ptr addrspace(4) null to ptr)
7878
// CHECK-NEXT: br i1 [[BOOL]]
7979
}
8080

clang/test/CodeGenSYCL/address-space-conversions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ void tmpl(T t) {}
3535
// CHECK-DAG: [[LOC]].ascast = addrspacecast ptr [[LOC]] to ptr addrspace(4)
3636
// CHECK-DAG: [[PRIV]].ascast = addrspacecast ptr [[PRIV]] to ptr addrspace(4)
3737
LOC = nullptr;
38-
// CHECK-DAG: store ptr addrspace(3) null, ptr addrspace(4) [[LOC]].ascast, align 8
38+
// CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr addrspace(4) null to ptr addrspace(3)), ptr addrspace(4) [[LOC]].ascast, align 8
3939
GLOB = nullptr;
40-
// CHECK-DAG: store ptr addrspace(1) null, ptr addrspace(4) [[GLOB]].ascast, align 8
40+
// CHECK-DAG: store ptr addrspace(1) addrspacecast (ptr addrspace(4) null to ptr addrspace(1)), ptr addrspace(4) [[GLOB]].ascast, align 8
4141

4242
// Explicit conversions
4343
// From named address spaces to default address space

0 commit comments

Comments
 (0)