Skip to content

[SPIRV] Correctly map OpGenericCastToPtrExplicit builtins #137189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1656,10 +1656,29 @@ static bool generateBarrierInst(const SPIRV::IncomingCall *Call,
}

static bool generateCastToPtrInst(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder) {
MIRBuilder.buildInstr(TargetOpcode::G_ADDRSPACE_CAST)
.addDef(Call->ReturnRegister)
.addUse(Call->Arguments[0]);
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
// Lookup the instruction opcode in the TableGen records.
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
unsigned Opcode =
SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;

if (Opcode == SPIRV::OpGenericCastToPtrExplicit) {
SPIRV::StorageClass::StorageClass ResSC =
GR->getPointerStorageClass(Call->ReturnRegister);
if (!isGenericCastablePtr(ResSC))
return false;

MIRBuilder.buildInstr(Opcode)
.addDef(Call->ReturnRegister)
.addUse(GR->getSPIRVTypeID(Call->ReturnType))
.addUse(Call->Arguments[0])
.addImm(ResSC);
} else {
MIRBuilder.buildInstr(TargetOpcode::G_ADDRSPACE_CAST)
.addDef(Call->ReturnRegister)
.addUse(Call->Arguments[0]);
}
return true;
}

Expand Down Expand Up @@ -2833,7 +2852,7 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
case SPIRV::Barrier:
return generateBarrierInst(Call.get(), MIRBuilder, GR);
case SPIRV::CastToPtr:
return generateCastToPtrInst(Call.get(), MIRBuilder);
return generateCastToPtrInst(Call.get(), MIRBuilder, GR);
case SPIRV::Dot:
case SPIRV::IntegerDot:
return generateDotOrFMulInst(DemangledCall, Call.get(), MIRBuilder, GR);
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.td
Original file line number Diff line number Diff line change
Expand Up @@ -687,15 +687,15 @@ defm : DemangledNativeBuiltin<"__spirv_Load", OpenCL_std, LoadStore, 1, 3, OpLoa
defm : DemangledNativeBuiltin<"__spirv_Store", OpenCL_std, LoadStore, 2, 4, OpStore>;

// Address Space Qualifier Functions/Pointers Conversion Instructions:
defm : DemangledNativeBuiltin<"to_global", OpenCL_std, CastToPtr, 1, 1, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"to_local", OpenCL_std, CastToPtr, 1, 1, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"to_private", OpenCL_std, CastToPtr, 1, 1, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"to_global", OpenCL_std, CastToPtr, 1, 1, OpGenericCastToPtrExplicit>;
defm : DemangledNativeBuiltin<"to_local", OpenCL_std, CastToPtr, 1, 1, OpGenericCastToPtrExplicit>;
defm : DemangledNativeBuiltin<"to_private", OpenCL_std, CastToPtr, 1, 1, OpGenericCastToPtrExplicit>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtr_ToGlobal", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtr_ToLocal", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtr_ToPrivate", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtrExplicit_ToGlobal", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtrExplicit_ToLocal", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtrExplicit_ToPrivate", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtr>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtrExplicit_ToGlobal", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtrExplicit>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtrExplicit_ToLocal", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtrExplicit>;
defm : DemangledNativeBuiltin<"__spirv_GenericCastToPtrExplicit_ToPrivate", OpenCL_std, CastToPtr, 2, 2, OpGenericCastToPtrExplicit>;

// Cooperative Matrix builtin records:
defm : DemangledNativeBuiltin<"__spirv_CooperativeMatrixLoadKHR", OpenCL_std, CoopMatr, 2, 4, OpCooperativeMatrixLoadKHR>;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const {
break;
case SPIRV::OpPtrCastToGeneric:
case SPIRV::OpGenericCastToPtr:
case SPIRV::OpGenericCastToPtrExplicit:
validateAccessChain(STI, MRI, GR, MI);
break;
case SPIRV::OpPtrAccessChain:
Expand Down
11 changes: 0 additions & 11 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1552,17 +1552,6 @@ bool SPIRVInstructionSelector::selectAtomicCmpXchg(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
}

static bool isGenericCastablePtr(SPIRV::StorageClass::StorageClass SC) {
switch (SC) {
case SPIRV::StorageClass::Workgroup:
case SPIRV::StorageClass::CrossWorkgroup:
case SPIRV::StorageClass::Function:
return true;
default:
return false;
}
}

static bool isUSMStorageClass(SPIRV::StorageClass::StorageClass SC) {
switch (SC) {
case SPIRV::StorageClass::DeviceOnlyINTEL:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,7 @@ defm InBoundsAccessChain : OpcodeOperand<66>;
defm InBoundsPtrAccessChain : OpcodeOperand<70>;
defm PtrCastToGeneric : OpcodeOperand<121>;
defm GenericCastToPtr : OpcodeOperand<122>;
defm GenericCastToPtrExplicit : OpcodeOperand<123>;
defm Bitcast : OpcodeOperand<124>;
defm ConvertPtrToU : OpcodeOperand<117>;
defm ConvertUToPtr : OpcodeOperand<120>;
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,19 @@ MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I);
// terminators and debug instructions.
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB);

// Returns true if a pointer to the storage class can be casted to/from a
// pointer to the Generic storage class.
constexpr bool isGenericCastablePtr(SPIRV::StorageClass::StorageClass SC) {
switch (SC) {
case SPIRV::StorageClass::Workgroup:
case SPIRV::StorageClass::CrossWorkgroup:
case SPIRV::StorageClass::Function:
return true;
default:
return false;
}
}

// Convert a SPIR-V storage class to the corresponding LLVM IR address space.
// TODO: maybe the following two functions should be handled in the subtarget
// to allow for different OpenCL vs Vulkan handling.
Expand Down
36 changes: 18 additions & 18 deletions llvm/test/CodeGen/SPIRV/transcoding/OpGenericCastToPtr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#GlobalIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#LocalCharPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#PrivateIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#GlobalIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#LocalCharPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#PrivateIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#GlobalIntPtr]] %{{.*}} CrossWorkgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#LocalCharPtr]] %{{.*}} Workgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#PrivateIntPtr]] %{{.*}} Function
; CHECK-SPIRV: OpFunctionEnd

define spir_kernel void @test1(ptr addrspace(1) %_arg_GlobalA, ptr byval(%id) %_arg_GlobalId, ptr addrspace(3) %_arg_LocalA) {
Expand All @@ -52,9 +52,9 @@ entry:
; CHECK-SPIRV: OpPtrCastToGeneric %[[#GenericIntPtr]]
; CHECK-SPIRV-NEXT: OpPtrCastToGeneric %[[#GenericCharPtr]]
; CHECK-SPIRV-NEXT: OpPtrCastToGeneric %[[#GenericIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#GlobalIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#LocalCharPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#PrivateIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#GlobalIntPtr]] %{{.*}} CrossWorkgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#LocalCharPtr]] %{{.*}} Workgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#PrivateIntPtr]] %{{.*}} Function
; CHECK-SPIRV: OpFunctionEnd

define spir_kernel void @test2(ptr addrspace(1) %_arg_GlobalA, ptr byval(%id) %_arg_GlobalId, ptr addrspace(3) %_arg_LocalA) {
Expand Down Expand Up @@ -93,18 +93,9 @@ declare spir_func ptr @_Z10to_privatePv(ptr addrspace(4))
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#GlobalIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#LocalCharPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#PrivateIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#GlobalIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#LocalCharPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#PrivateIntPtr]]
; CHECK-SPIRV: OpFunctionEnd

; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: OpPtrCastToGeneric %[[#GenericIntPtr]]
; CHECK-SPIRV-NEXT: OpPtrCastToGeneric %[[#GenericCharPtr]]
; CHECK-SPIRV-NEXT: OpPtrCastToGeneric %[[#GenericIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#GlobalIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#LocalCharPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtr %[[#PrivateIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#GlobalIntPtr]] %{{.*}} CrossWorkgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#LocalCharPtr]] %{{.*}} Workgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#PrivateIntPtr]] %{{.*}} Function
; CHECK-SPIRV: OpFunctionEnd

define spir_kernel void @test3(ptr addrspace(1) %_arg_GlobalA, ptr byval(%id) %_arg_GlobalId, ptr addrspace(3) %_arg_LocalA) {
Expand All @@ -126,6 +117,15 @@ entry:
ret void
}

; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: OpPtrCastToGeneric %[[#GenericIntPtr]]
; CHECK-SPIRV-NEXT: OpPtrCastToGeneric %[[#GenericCharPtr]]
; CHECK-SPIRV-NEXT: OpPtrCastToGeneric %[[#GenericIntPtr]]
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#GlobalIntPtr]] %{{.*}} CrossWorkgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#LocalCharPtr]] %{{.*}} Workgroup
; CHECK-SPIRV-NEXT: OpGenericCastToPtrExplicit %[[#PrivateIntPtr]] %{{.*}} Function
; CHECK-SPIRV: OpFunctionEnd

define spir_kernel void @test4(ptr addrspace(1) %_arg_GlobalA, ptr byval(%id) %_arg_GlobalId, ptr addrspace(3) %_arg_LocalA) {
entry:
%var = alloca i32
Expand Down
Loading