Skip to content

Commit 57e1c90

Browse files
committed
[SPIRV] Add intrinsic for OpGenericCastToPtrExplicit
The patch adds an intrinsic to encode OpGenericCastToPtrExplicit and the associated lowering logic.
1 parent be82be2 commit 57e1c90

File tree

4 files changed

+70
-0
lines changed

4 files changed

+70
-0
lines changed

llvm/include/llvm/IR/IntrinsicsSPIRV.td

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
def generic_ptr_ty : LLVMQualPointerType<4>;
14+
1315
let TargetPrefix = "spv" in {
1416
def int_spv_assign_type : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
1517
def int_spv_assign_ptr_type : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty, llvm_i32_ty], [ImmArg<ArgIndex<2>>]>;
@@ -146,4 +148,9 @@ let TargetPrefix = "spv" in {
146148

147149
// FPMaxErrorDecorationINTEL
148150
def int_spv_assign_fpmaxerror_decoration: Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
151+
152+
// Convert between the generic storage class and a concrete one.
153+
def int_spv_generic_cast_to_ptr_explicit
154+
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [generic_ptr_ty],
155+
[IntrNoMem, NoUndef<RetIndex>]>;
149156
}

llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,10 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(
680680
} else {
681681
llvm_unreachable("Unknown handle type for spv_resource_getpointer.");
682682
}
683+
} else if (II && II->getIntrinsicID() ==
684+
Intrinsic::spv_generic_cast_to_ptr_explicit) {
685+
Ty = deduceElementTypeHelper(CI->getArgOperand(0), Visited,
686+
UnknownElemTypeI8);
683687
} else if (Function *CalledF = CI->getCalledFunction()) {
684688
std::string DemangledName =
685689
getOclOrSpirvBuiltinDemangledName(CalledF->getName());

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -3120,6 +3120,21 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
31203120
.addUse(MemSemReg)
31213121
.constrainAllUses(TII, TRI, RBI);
31223122
}
3123+
case Intrinsic::spv_generic_cast_to_ptr_explicit: {
3124+
Register PtrReg = I.getOperand(I.getNumExplicitDefs() + 1).getReg();
3125+
SPIRV::StorageClass::StorageClass ResSC =
3126+
GR.getPointerStorageClass(ResType);
3127+
if (isGenericCastablePtr(ResSC))
3128+
report_fatal_error("The target storage class is not castable from the "
3129+
"Generic storage class");
3130+
return BuildMI(BB, I, I.getDebugLoc(),
3131+
TII.get(SPIRV::OpGenericCastToPtrExplicit))
3132+
.addDef(ResVReg)
3133+
.addUse(GR.getSPIRVTypeID(ResType))
3134+
.addUse(PtrReg)
3135+
.addImm(ResSC)
3136+
.constrainAllUses(TII, TRI, RBI);
3137+
}
31233138
case Intrinsic::spv_lifetime_start:
31243139
case Intrinsic::spv_lifetime_end: {
31253140
unsigned Op = IID == Intrinsic::spv_lifetime_start ? SPIRV::OpLifetimeStart
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; Make sure SPIRV operation function calls for generic_cast_to_ptr_explicit are lowered correctly.
5+
6+
; CHECK: %[[#Char:]] = OpTypeInt 8 0
7+
; CHECK: %[[#GenericPtr:]] = OpTypePointer Generic %[[#Char]]
8+
; CHECK: %[[#GlobalPtr:]] = OpTypePointer CrossWorkgroup %[[#Char]]
9+
; CHECK: %[[#LocalPtr:]] = OpTypePointer Workgroup %[[#Char]]
10+
; CHECK: %[[#PrivatePtr:]] = OpTypePointer Function %[[#Char]]
11+
12+
; CHECK: OpFunction %[[#GlobalPtr]]
13+
; CHECK-NEXT: %[[#Arg:]] = OpFunctionParameter %[[#GenericPtr]]
14+
; CHECK-NEXT: OpLabel
15+
; CHECK-NEXT: OpGenericCastToPtrExplicit %[[#GlobalPtr]] %[[#Arg]] CrossWorkgroup
16+
define ptr addrspace(1) @test_to_global(ptr addrspace(4) noundef %ptr) {
17+
entry:
18+
%cast = call spir_func noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4) noundef %ptr)
19+
ret ptr addrspace(1) %cast
20+
}
21+
22+
; CHECK: OpFunction %[[#LocalPtr]]
23+
; CHECK-NEXT: %[[#Arg:]] = OpFunctionParameter %[[#GenericPtr]]
24+
; CHECK-NEXT: OpLabel
25+
; CHECK-NEXT: OpGenericCastToPtrExplicit %[[#LocalPtr]] %[[#Arg]] Workgroup
26+
define ptr addrspace(3) @test_to_local(ptr addrspace(4) noundef %ptr) {
27+
entry:
28+
%cast = call spir_func noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4) noundef %ptr)
29+
ret ptr addrspace(3) %cast
30+
}
31+
32+
; CHECK: OpFunction %[[#PrivatePtr]]
33+
; CHECK-NEXT: %[[#Arg:]] = OpFunctionParameter %[[#GenericPtr]]
34+
; CHECK-NEXT: OpLabel
35+
; CHECK-NEXT: OpGenericCastToPtrExplicit %[[#PrivatePtr]] %[[#Arg]] Function
36+
define ptr @test_to_private(ptr addrspace(4) noundef %ptr) {
37+
entry:
38+
%cast = call spir_func noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4) noundef %ptr)
39+
ret ptr %cast
40+
}
41+
42+
declare noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4))
43+
declare noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4))
44+
declare noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4))

0 commit comments

Comments
 (0)