Skip to content

Commit 1639578

Browse files
committed
[AMDGPU][LowerBufferFatPointers] Handle addrspacecast null to p7
Some application code operating on generic pointers (that then gete initialized to buffer fat pointers) may perform tests against nullptr. After address space inference, this results in comparisons against `addrspacecast (ptr null to ptr addrspace(7))`, which were crashing. However, while general casts to ptr addrspace(7) from generic pointers aren't supposted, it is possible to cast null pointers to the all-zerose bufer resource and 0 offset, which this patch adds. It also adds a TODO for casting _out_ of buffer resources, which isn't implemented here but could be.
1 parent 4a0ae4f commit 1639578

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,8 @@ PtrParts SplitPtrStructs::visitIntToPtrInst(IntToPtrInst &IP) {
19801980
}
19811981

19821982
PtrParts SplitPtrStructs::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
1983+
// TODO(krzysz00): handle casts from ptr addrspace(7) to global pointers
1984+
// by computing the effective address.
19831985
if (!isSplitFatPtr(I.getType()))
19841986
return {nullptr, nullptr};
19851987
IRB.SetInsertPoint(&I);
@@ -1990,11 +1992,24 @@ PtrParts SplitPtrStructs::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
19901992
SplitUsers.insert(&I);
19911993
return {Rsrc, Off};
19921994
}
1993-
if (I.getSrcAddressSpace() != AMDGPUAS::BUFFER_RESOURCE)
1994-
report_fatal_error("Only buffer resources (addrspace 8) can be cast to "
1995-
"buffer fat pointers (addrspace 7)");
1996-
Type *OffTy = cast<StructType>(I.getType())->getElementType(1);
1995+
1996+
auto *ResTy = cast<StructType>(I.getType());
1997+
Type *RsrcTy = ResTy->getElementType(0);
1998+
Type *OffTy = ResTy->getElementType(1);
19971999
Value *ZeroOff = Constant::getNullValue(OffTy);
2000+
2001+
// Special case for null pointers, which can be created by address space
2002+
// propagation.
2003+
auto *InConst = dyn_cast<Constant>(In);
2004+
if (InConst && InConst->isNullValue()) {
2005+
Value *NullRsrc = Constant::getNullValue(RsrcTy);
2006+
SplitUsers.insert(&I);
2007+
return {NullRsrc, ZeroOff};
2008+
}
2009+
2010+
if (I.getSrcAddressSpace() != AMDGPUAS::BUFFER_RESOURCE)
2011+
report_fatal_error("Only buffer resources (addrspace 8) and null pointers "
2012+
"can be cast to buffer fat pointers (addrspace 7)");
19982013
SplitUsers.insert(&I);
19992014
return {In, ZeroOff};
20002015
}

llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,38 @@ define <2 x ptr addrspace(7)> @addrspacecast_vec(<2 x ptr addrspace(8)> %buf) {
332332
ret <2 x ptr addrspace(7)> %ret
333333
}
334334

335+
define ptr addrspace(7) @addrspacecast_null() {
336+
; CHECK-LABEL: define { ptr addrspace(8), i32 } @addrspacecast_null
337+
; CHECK-SAME: () #[[ATTR0]] {
338+
; CHECK-NEXT: ret { ptr addrspace(8), i32 } zeroinitializer
339+
;
340+
%ret = addrspacecast ptr null to ptr addrspace(7)
341+
ret ptr addrspace(7) %ret
342+
}
343+
344+
define <2 x ptr addrspace(7)> @addrspacecast_null_vec() {
345+
; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @addrspacecast_null_vec
346+
; CHECK-SAME: () #[[ATTR0]] {
347+
; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } zeroinitializer
348+
;
349+
%ret = addrspacecast <2 x ptr> zeroinitializer to <2 x ptr addrspace(7)>
350+
ret <2 x ptr addrspace(7)> %ret
351+
}
352+
353+
define i1 @test_null(ptr addrspace(7) %p) {
354+
; CHECK-LABEL: define i1 @test_null
355+
; CHECK-SAME: ({ ptr addrspace(8), i32 } [[P:%.*]]) #[[ATTR0]] {
356+
; CHECK-NEXT: [[P_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 0
357+
; CHECK-NEXT: [[P_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 1
358+
; CHECK-NEXT: [[IS_NULL_RSRC:%.*]] = icmp eq ptr addrspace(8) [[P_RSRC]], null
359+
; CHECK-NEXT: [[IS_NULL_OFF:%.*]] = icmp eq i32 [[P_OFF]], 0
360+
; CHECK-NEXT: [[IS_NULL:%.*]] = and i1 [[IS_NULL_RSRC]], [[IS_NULL_OFF]]
361+
; CHECK-NEXT: ret i1 [[IS_NULL]]
362+
;
363+
%is.null = icmp eq ptr addrspace(7) %p, addrspacecast (ptr null to ptr addrspace(7))
364+
ret i1 %is.null
365+
}
366+
335367
declare ptr addrspace(7) @llvm.amdgcn.make.buffer.rsrc.p7.p1(ptr addrspace(1), i16, i32, i32)
336368

337369
define ptr addrspace(7) @make_buffer_rsrc(ptr addrspace(1) %buf, i16 %stride, i32 %numRecords, i32 %flags) {

0 commit comments

Comments
 (0)