mirror of
https://github.com/intel/llvm.git
synced 2026-01-23 16:06:39 +08:00
[SPIRV] Add intrinsic for OpGenericCastToPtrExplicit (#137626)
The patch adds an intrinsic to encode OpGenericCastToPtrExplicit and the associated lowering logic.
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def generic_ptr_ty : LLVMQualPointerType<4>;
|
||||
|
||||
let TargetPrefix = "spv" in {
|
||||
def int_spv_assign_type : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
|
||||
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 {
|
||||
|
||||
// FPMaxErrorDecorationINTEL
|
||||
def int_spv_assign_fpmaxerror_decoration: Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
|
||||
|
||||
// Convert between the generic storage class and a concrete one.
|
||||
def int_spv_generic_cast_to_ptr_explicit
|
||||
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [generic_ptr_ty],
|
||||
[IntrNoMem, NoUndef<RetIndex>]>;
|
||||
}
|
||||
|
||||
@@ -680,6 +680,10 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(
|
||||
} else {
|
||||
llvm_unreachable("Unknown handle type for spv_resource_getpointer.");
|
||||
}
|
||||
} else if (II && II->getIntrinsicID() ==
|
||||
Intrinsic::spv_generic_cast_to_ptr_explicit) {
|
||||
Ty = deduceElementTypeHelper(CI->getArgOperand(0), Visited,
|
||||
UnknownElemTypeI8);
|
||||
} else if (Function *CalledF = CI->getCalledFunction()) {
|
||||
std::string DemangledName =
|
||||
getOclOrSpirvBuiltinDemangledName(CalledF->getName());
|
||||
|
||||
@@ -3109,6 +3109,21 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
|
||||
.addUse(MemSemReg)
|
||||
.constrainAllUses(TII, TRI, RBI);
|
||||
}
|
||||
case Intrinsic::spv_generic_cast_to_ptr_explicit: {
|
||||
Register PtrReg = I.getOperand(I.getNumExplicitDefs() + 1).getReg();
|
||||
SPIRV::StorageClass::StorageClass ResSC =
|
||||
GR.getPointerStorageClass(ResType);
|
||||
if (!isGenericCastablePtr(ResSC))
|
||||
report_fatal_error("The target storage class is not castable from the "
|
||||
"Generic storage class");
|
||||
return BuildMI(BB, I, I.getDebugLoc(),
|
||||
TII.get(SPIRV::OpGenericCastToPtrExplicit))
|
||||
.addDef(ResVReg)
|
||||
.addUse(GR.getSPIRVTypeID(ResType))
|
||||
.addUse(PtrReg)
|
||||
.addImm(ResSC)
|
||||
.constrainAllUses(TII, TRI, RBI);
|
||||
}
|
||||
case Intrinsic::spv_lifetime_start:
|
||||
case Intrinsic::spv_lifetime_end: {
|
||||
unsigned Op = IID == Intrinsic::spv_lifetime_start ? SPIRV::OpLifetimeStart
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
|
||||
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
|
||||
|
||||
; Make sure SPIRV operation function calls for generic_cast_to_ptr_explicit are lowered correctly.
|
||||
|
||||
; CHECK: %[[#Char:]] = OpTypeInt 8 0
|
||||
; CHECK: %[[#GenericPtr:]] = OpTypePointer Generic %[[#Char]]
|
||||
; CHECK: %[[#GlobalPtr:]] = OpTypePointer CrossWorkgroup %[[#Char]]
|
||||
; CHECK: %[[#LocalPtr:]] = OpTypePointer Workgroup %[[#Char]]
|
||||
; CHECK: %[[#PrivatePtr:]] = OpTypePointer Function %[[#Char]]
|
||||
|
||||
; CHECK: OpFunction %[[#GlobalPtr]]
|
||||
; CHECK-NEXT: %[[#Arg:]] = OpFunctionParameter %[[#GenericPtr]]
|
||||
; CHECK-NEXT: OpLabel
|
||||
; CHECK-NEXT: OpGenericCastToPtrExplicit %[[#GlobalPtr]] %[[#Arg]] CrossWorkgroup
|
||||
define ptr addrspace(1) @test_to_global(ptr addrspace(4) noundef %ptr) {
|
||||
entry:
|
||||
%cast = call spir_func noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4) noundef %ptr)
|
||||
ret ptr addrspace(1) %cast
|
||||
}
|
||||
|
||||
; CHECK: OpFunction %[[#LocalPtr]]
|
||||
; CHECK-NEXT: %[[#Arg:]] = OpFunctionParameter %[[#GenericPtr]]
|
||||
; CHECK-NEXT: OpLabel
|
||||
; CHECK-NEXT: OpGenericCastToPtrExplicit %[[#LocalPtr]] %[[#Arg]] Workgroup
|
||||
define ptr addrspace(3) @test_to_local(ptr addrspace(4) noundef %ptr) {
|
||||
entry:
|
||||
%cast = call spir_func noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4) noundef %ptr)
|
||||
ret ptr addrspace(3) %cast
|
||||
}
|
||||
|
||||
; CHECK: OpFunction %[[#PrivatePtr]]
|
||||
; CHECK-NEXT: %[[#Arg:]] = OpFunctionParameter %[[#GenericPtr]]
|
||||
; CHECK-NEXT: OpLabel
|
||||
; CHECK-NEXT: OpGenericCastToPtrExplicit %[[#PrivatePtr]] %[[#Arg]] Function
|
||||
define ptr @test_to_private(ptr addrspace(4) noundef %ptr) {
|
||||
entry:
|
||||
%cast = call spir_func noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4) noundef %ptr)
|
||||
ret ptr %cast
|
||||
}
|
||||
|
||||
declare noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4))
|
||||
declare noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4))
|
||||
declare noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4))
|
||||
Reference in New Issue
Block a user