[llvm] [SPIR-V] Do not reassign kernel arg SPIRVType based on later calls/uses (PR #75514)
Michal Paszkowski via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 4 10:50:21 PST 2024
================
@@ -265,6 +281,85 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
return NewI;
}
+void SPIRVEmitIntrinsics::insertPtrCastInstr(Instruction *I) {
+ Value *Pointer;
+ Type *ExpectedElementType;
+ unsigned OperandToReplace;
+ if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
+ Pointer = SI->getPointerOperand();
+ ExpectedElementType = SI->getValueOperand()->getType();
+ OperandToReplace = 1;
+ } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+ Pointer = LI->getPointerOperand();
+ ExpectedElementType = LI->getType();
+ OperandToReplace = 0;
+ } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
+ Pointer = GEPI->getPointerOperand();
+ ExpectedElementType = GEPI->getSourceElementType();
+ OperandToReplace = 0;
+ } else {
+ return;
+ }
+
+ // If Pointer is the result of nop BitCastInst (ptr -> ptr), use the source
+ // pointer instead. The BitCastInst should be later removed when visited.
+ if (BitCastInst *BC = dyn_cast<BitCastInst>(Pointer))
+ Pointer = BC->getOperand(0);
+
+ // Do not emit spv_ptrcast if Pointer is a GlobalValue of expected type.
+ GlobalValue *GV = dyn_cast<GlobalValue>(Pointer);
+ if (GV && GV->getValueType() == ExpectedElementType)
+ return;
+
+ setInsertPointSkippingPhis(*IRB, I);
+ Constant *ExpectedElementTypeConst =
+ Constant::getNullValue(ExpectedElementType);
+ ConstantAsMetadata *CM =
+ ValueAsMetadata::getConstant(ExpectedElementTypeConst);
+ MDTuple *TyMD = MDNode::get(F->getContext(), CM);
+ MetadataAsValue *VMD = MetadataAsValue::get(F->getContext(), TyMD);
+ unsigned AddressSpace = Pointer->getType()->getPointerAddressSpace();
+ bool FirstPtrCastOrAssignPtrType = true;
+
+ // Do not emit new spv_ptrcast if equivalent one already exists or when
+ // spv_assign_ptr_type already targets this pointer with the same element
+ // type.
+ for (auto User : Pointer->users()) {
+ if (auto *II = dyn_cast<IntrinsicInst>(User)) {
+ if ((II->getIntrinsicID() != Intrinsic::spv_assign_ptr_type &&
+ II->getIntrinsicID() != Intrinsic::spv_ptrcast) ||
+ II->getOperand(0) != Pointer)
+ continue;
+
+ FirstPtrCastOrAssignPtrType = false;
+ if (II->getOperand(1) == VMD &&
+ dyn_cast<ConstantInt>(II->getOperand(2))->getSExtValue() ==
+ AddressSpace)
+ return;
+ }
----------------
michalpaszkowski wrote:
Thanks! Rewrote it in a similar way in [the original pull request](https://github.com/llvm/llvm-project/pull/69621). Will rebase this one in a moment.
https://github.com/llvm/llvm-project/pull/75514
More information about the llvm-commits
mailing list