diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp index 2344ec529e16dc..c12e5f08f93979 100644 --- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp @@ -203,6 +203,30 @@ static void validateGroupWaitEventsPtr(const SPIRVSubtarget &STI, doInsertBitcast(STI, MRI, GR, I, OpReg, OpIdx, NewPtrType); } +static void validateLifetimeStart(const SPIRVSubtarget &STI, + MachineRegisterInfo *MRI, + SPIRVGlobalRegistry &GR, MachineInstr &I) { + Register PtrReg = I.getOperand(0).getReg(); + MachineFunction *MF = I.getParent()->getParent(); + Register PtrTypeReg = getTypeReg(MRI, PtrReg); + SPIRVType *PtrType = GR.getSPIRVTypeForVReg(PtrTypeReg, MF); + SPIRVType *PonteeElemType = PtrType ? GR.getPointeeType(PtrType) : nullptr; + if (!PonteeElemType || PonteeElemType->getOpcode() == SPIRV::OpTypeVoid || + (PonteeElemType->getOpcode() == SPIRV::OpTypeInt && + PonteeElemType->getOperand(1).getImm() == 8)) + return; + // To keep the code valid a bitcast must be inserted + SPIRV::StorageClass::StorageClass SC = + static_cast( + PtrType->getOperand(1).getImm()); + MachineIRBuilder MIB(I); + LLVMContext &Context = MF->getMMI().getModule()->getContext(); + SPIRVType *ElemType = + GR.getOrCreateSPIRVType(IntegerType::getInt8Ty(Context), MIB); + SPIRVType *NewPtrType = GR.getOrCreateSPIRVPointerType(ElemType, MIB, SC); + doInsertBitcast(STI, MRI, GR, I, PtrReg, 0, NewPtrType); +} + static void validateGroupAsyncCopyPtr(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, MachineInstr &I, @@ -413,6 +437,11 @@ void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const { SPIRV::OpTypeBool)) MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalNotEqual)); break; + case SPIRV::OpLifetimeStart: + case SPIRV::OpLifetimeStop: + if (MI.getOperand(1).getImm() > 0) + validateLifetimeStart(STI, MRI, GR, MI); + break; case SPIRV::OpGroupAsyncCopy: validateGroupAsyncCopyPtr(STI, MRI, GR, MI, 3); validateGroupAsyncCopyPtr(STI, MRI, GR, MI, 4); diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 04def5ef01e7b3..86ad7b8eb03b6c 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -2067,9 +2067,7 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, : SPIRV::OpLifetimeStop; int64_t Size = I.getOperand(I.getNumExplicitDefs() + 1).getImm(); Register PtrReg = I.getOperand(I.getNumExplicitDefs() + 2).getReg(); - unsigned PonteeOpType = GR.getPointeeTypeOp(PtrReg); - bool IsNonvoidPtr = PonteeOpType != 0 && PonteeOpType != SPIRV::OpTypeVoid; - if (Size == -1 || IsNonvoidPtr) + if (Size == -1) Size = 0; BuildMI(BB, I, I.getDebugLoc(), TII.get(Op)).addUse(PtrReg).addImm(Size); } break; diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll index 710a1581f760ca..780521c5ebe26d 100644 --- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll +++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll @@ -1,12 +1,20 @@ +; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} +; CHECK-DAG: %[[#Char:]] = OpTypeInt 8 0 +; CHECK-DAG: %[[#PtrChar:]] = OpTypePointer Function %[[#Char]] ; CHECK: OpFunction -; CHECK: %[[FooArg:.*]] = OpVariable -; CHECK: OpLifetimeStart %[[FooArg]], 0 +; CHECK: %[[#FooArg:]] = OpVariable +; CHECK: %[[#Casted1:]] = OpBitcast %[[#PtrChar]] %[[#FooArg]] +; CHECK: OpLifetimeStart %[[#Casted1]], 72 ; CHECK: OpCopyMemorySized ; CHECK: OpBitcast ; CHECK: OpInBoundsPtrAccessChain -; CHECK: OpLifetimeStop %[[FooArg]], 0 +; CHECK: %[[#Casted2:]] = OpBitcast %[[#PtrChar]] %[[#FooArg]] +; CHECK: OpLifetimeStop %[[#Casted2]], 72 %tprange = type { %tparray } %tparray = type { [2 x i64] }