[llvm] [SPIR-V] Add lowering of ptrtoaddr (PR #184577)

Dmitry Sidorov via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 4 02:03:49 PST 2026


================
@@ -1725,6 +1727,56 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
   return NewI;
 }
 
+Instruction *SPIRVEmitIntrinsics::visitPtrToAddrInst(PtrToAddrInst &I) {
+  // If ptrtoaddr instruction wasn't handled previously during
+  // sub(ptrtoaddr, ptrtoaddr) -> OpPtrDiff pattern lowering, then
+  // replace it with PtrToInt.
+  auto *PtrToInt =
+      CastInst::Create(Instruction::PtrToInt, I.getOperand(0), I.getType());
+  PtrToInt->insertBefore(I.getIterator());
+  replaceAllUsesWith(&I, PtrToInt);
+  I.eraseFromParent();
+  return PtrToInt;
+}
+
+// Recognize sub(ptrtoaddr(A), ptrtoaddr(B)) patterns and replace with
+// spv_ptrdiff intrinsic.
+void SPIRVEmitIntrinsics::preprocessPtrToAddrDiff(Function &F, IRBuilder<> &B) {
+  // OpPtrDiff was added in SPIR-V 1.4, check for it.
+  const SPIRVSubtarget *ST = TM->getSubtargetImpl(F);
+  if (!ST->isAtLeastSPIRVVer(VersionTuple(1, 4)))
+    return;
+
+  SmallVector<BinaryOperator *> SubsToReplace;
+  for (auto &I : instructions(F)) {
+    auto *Sub = dyn_cast<BinaryOperator>(&I);
+    if (!Sub || Sub->getOpcode() != Instruction::Sub)
+      continue;
+    if (isa<PtrToAddrInst>(Sub->getOperand(0)) &&
+        isa<PtrToAddrInst>(Sub->getOperand(1)))
+      SubsToReplace.push_back(Sub);
+  }
+
+  for (auto *Sub : SubsToReplace) {
+    auto *PtrToAddrA = cast<PtrToAddrInst>(Sub->getOperand(0));
+    auto *PtrToAddrB = cast<PtrToAddrInst>(Sub->getOperand(1));
+    Value *Ptr1 = PtrToAddrA->getOperand(0);
+    Value *Ptr2 = PtrToAddrB->getOperand(0);
----------------
MrSidims wrote:

Actually, this transformation is legal only if address spaces for 2 pointers are the same. Thanks @maarquitos14 for spotting.

https://github.com/llvm/llvm-project/pull/184577


More information about the llvm-commits mailing list