Skip to content

Commit

Permalink
Fix SPIR-V Builtin OpGenericCastToPtr transformation to OCL (#2763)
Browse files Browse the repository at this point in the history
OpGenericCastToPtrExplict is for dynamic cast and OpGenericCastToPtr is for static cast.

OpGenericCastToPtrExplict is already transformed to to_{global|local|private} OCL builtins, but the handling for OpGenericCastToPtr is missing.

Looks we can transform OpGenericCastToPtr to addrspacecast instruction directly in SPIRV to OCL transformation.

Signed-off-by: Cui, Dele <[email protected]>
  • Loading branch information
delecui authored Oct 18, 2024
1 parent bdad3f9 commit 21e9654
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/SPIRV/SPIRVToOCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ void SPIRVToOCLBase::visitCallInst(CallInst &CI) {
visitCallBuildNDRangeBuiltIn(&CI, OC, DemangledName);
return;
}
if (OC == OpGenericCastToPtr) {
visitCallGenericCastToPtrBuiltIn(&CI, OC);
return;
}
if (OC == OpGenericCastToPtrExplicit) {
visitCallGenericCastToPtrExplicitBuiltIn(&CI, OC);
return;
Expand Down Expand Up @@ -629,6 +633,18 @@ void SPIRVToOCLBase::visitCallBuildNDRangeBuiltIn(CallInst *CI, Op OC,
.moveArg(2, 0);
}

void SPIRVToOCLBase::visitCallGenericCastToPtrBuiltIn(CallInst *CI, Op OC) {
assert(CI->getCalledFunction() && "Unexpected indirect call");
IRBuilder<> Builder(CI);
Value *PtrArg = CI->getArgOperand(0);
auto AddrSpace =
static_cast<SPIRAddressSpace>(CI->getType()->getPointerAddressSpace());
Type *NewTy = PointerType::get(PtrArg->getType(), AddrSpace);
Value *ASC = Builder.CreateAddrSpaceCast(PtrArg, NewTy);
CI->replaceAllUsesWith(ASC);
CI->eraseFromParent();
}

void SPIRVToOCLBase::visitCallGenericCastToPtrExplicitBuiltIn(CallInst *CI,
Op OC) {
assert(CI->getCalledFunction() && "Unexpected indirect call");
Expand Down
4 changes: 4 additions & 0 deletions lib/SPIRV/SPIRVToOCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ class SPIRVToOCLBase : public InstVisitor<SPIRVToOCLBase>,
/// intel_sub_group_media_block_write
void visitCallSPIRVImageMediaBlockBuiltin(CallInst *CI, Op OC);

/// Transform __spirv_OpGenericCastToPtr_To{Global|Local|Private} to llvm
/// addrspacecast instruction.
void visitCallGenericCastToPtrBuiltIn(CallInst *CI, Op OC);

/// Transform __spirv_OpGenericCastToPtrExplicit_To{Global|Local|Private} to
/// to_{global|local|private} OCL builtin.
void visitCallGenericCastToPtrExplicitBuiltIn(CallInst *CI, Op OC);
Expand Down
48 changes: 48 additions & 0 deletions test/generic-cast-to-ptr.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
; REQUIRES: pass-plugin
; UNSUPPORTED: target={{.*windows.*}}

; RUN: opt %load_spirv_lib -passes=spirv-to-ocl20 %s -S -o - | FileCheck %s --check-prefixes=CHECK-LLVM-OCL

%id = type { %arr }
%arr = type { [1 x i64] }

@__spirv_BuiltInGlobalInvocationId = external local_unnamed_addr addrspace(1) constant <3 x i64>

; Check that SPIR-V Builtin GenericCastToPtr and GenericCastToPtrExplicit can be transformed to OCL.

; CHECK-LLVM-OCL-LABEL: void @test(
; CHECK-LLVM-OCL: %[[VAR_1:.*]] = addrspacecast ptr addrspace(1) %idx to ptr addrspace(4)
; CHECK-LLVM-OCL-NEXT: %[[VAR_2:.*]] = addrspacecast ptr addrspace(3) %_arg_LocalA to ptr addrspace(4)
; CHECK-LLVM-OCL-NEXT: %[[VAR_3:.*]] = addrspacecast ptr %var to ptr addrspace(4)
; CHECK-LLVM-OCL-NEXT: addrspacecast ptr addrspace(4) %[[VAR_1]] to ptr addrspace(1)
; CHECK-LLVM-OCL-NEXT: addrspacecast ptr addrspace(4) %[[VAR_2]] to ptr addrspace(3)
; CHECK-LLVM-OCL-NEXT: addrspacecast ptr addrspace(4) %[[VAR_3]] to ptr
; CHECK-LLVM-OCL-NEXT: call spir_func ptr addrspace(1) @__to_global(ptr addrspace(4) %[[VAR_1]])
; CHECK-LLVM-OCL-NEXT: call spir_func ptr addrspace(3) @__to_local(ptr addrspace(4) %[[VAR_2]])
; CHECK-LLVM-OCL-NEXT: call spir_func ptr @__to_private(ptr addrspace(4) %[[VAR_3]])

define spir_kernel void @test(ptr addrspace(1) %_arg_GlobalA, ptr byval(%id) %_arg_GlobalId, ptr addrspace(3) %_arg_LocalA) {
entry:
%var = alloca i32
%p0 = load i64, ptr %_arg_GlobalId
%add = getelementptr inbounds i32, ptr addrspace(1) %_arg_GlobalA, i64 %p0
%p2 = load i64, ptr addrspace(1) @__spirv_BuiltInGlobalInvocationId
%idx = getelementptr inbounds i32, ptr addrspace(1) %add, i64 %p2
%var1 = addrspacecast ptr addrspace(1) %idx to ptr addrspace(4)
%var2 = addrspacecast ptr addrspace(3) %_arg_LocalA to ptr addrspace(4)
%var3 = addrspacecast ptr %var to ptr addrspace(4)
%G = call spir_func ptr addrspace(1) @_Z33__spirv_GenericCastToPtr_ToGlobalPvi(ptr addrspace(4) %var1, i32 5)
%L = call spir_func ptr addrspace(3) @_Z32__spirv_GenericCastToPtr_ToLocalPvi(ptr addrspace(4) %var2, i32 4)
%P = call spir_func ptr @_Z34__spirv_GenericCastToPtr_ToPrivatePvi(ptr addrspace(4) %var3, i32 7)
%GE = call spir_func ptr addrspace(1) @_Z41__spirv_GenericCastToPtrExplicit_ToGlobalPvi(ptr addrspace(4) %var1, i32 5)
%LE = call spir_func ptr addrspace(3) @_Z40__spirv_GenericCastToPtrExplicit_ToLocalPvi(ptr addrspace(4) %var2, i32 4)
%PE = call spir_func ptr @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePvi(ptr addrspace(4) %var3, i32 7)
ret void
}

declare spir_func ptr addrspace(1) @_Z33__spirv_GenericCastToPtr_ToGlobalPvi(ptr addrspace(4), i32)
declare spir_func ptr addrspace(3) @_Z32__spirv_GenericCastToPtr_ToLocalPvi(ptr addrspace(4), i32)
declare spir_func ptr @_Z34__spirv_GenericCastToPtr_ToPrivatePvi(ptr addrspace(4), i32)
declare spir_func ptr addrspace(1) @_Z41__spirv_GenericCastToPtrExplicit_ToGlobalPvi(ptr addrspace(4), i32)
declare spir_func ptr addrspace(3) @_Z40__spirv_GenericCastToPtrExplicit_ToLocalPvi(ptr addrspace(4), i32)
declare spir_func ptr @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePvi(ptr addrspace(4), i32)

0 comments on commit 21e9654

Please sign in to comment.