[llvm] [SPIRV] Legalize byte-buffer reinterpretation ptrcasts (#192523) (PR #212999)

Farzon Lotfi via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 24 20:21:53 PDT 2026


================
@@ -222,15 +222,207 @@ class SPIRVLegalizePointerCastImpl {
     return std::make_pair(GEP, CurrentTy);
   }
 
+  static IntrinsicInst *getResourceGetPointer(Value *Ptr) {
+    if (auto *II = dyn_cast<IntrinsicInst>(Ptr))
+      if (II->getIntrinsicID() == Intrinsic::spv_resource_getpointer)
+        return II;
+    return nullptr;
+  }
+
+  Value *gepByteOffset(IRBuilder<> &B, Value *BasePtr, unsigned ByteOffset) {
+    if (ByteOffset == 0)
+      return BasePtr;
+
+    IntrinsicInst *ResourcePtr = getResourceGetPointer(BasePtr);
+    assert(ResourcePtr &&
+           "byte layout pointer must come from spv.resource.getpointer");
+
+    Value *Handle = ResourcePtr->getOperand(0);
+    Value *BaseOffset = ResourcePtr->getOperand(1);
+    Value *NewOffset;
+    if (auto *CI = dyn_cast<ConstantInt>(BaseOffset))
+      NewOffset =
+          ConstantInt::get(CI->getType(), CI->getZExtValue() + ByteOffset);
+    else
+      NewOffset = B.CreateAdd(
+          BaseOffset, ConstantInt::get(BaseOffset->getType(), ByteOffset));
+    SmallVector<OperandBundleDef> OpBundles;
+    ResourcePtr->getOperandBundlesAsDefs(OpBundles);
+    CallInst *ResourcePtrAtOffset = B.CreateCall(
+        ResourcePtr->getFunctionType(), ResourcePtr->getCalledOperand(),
+        {Handle, NewOffset}, OpBundles);
+    ResourcePtrAtOffset->setAttributes(ResourcePtr->getAttributes());
+    ResourcePtrAtOffset->setCallingConv(ResourcePtr->getCallingConv());
+    Type *I8Ty = Type::getInt8Ty(B.getContext());
+    GR->buildAssignPtr(B, I8Ty, ResourcePtrAtOffset);
+    return ResourcePtrAtOffset;
+  }
+
+  Value *scalarToStoreInt(IRBuilder<> &B, Value *Scalar) {
+    Type *Ty = Scalar->getType();
+    const DataLayout &DL = B.GetInsertBlock()->getModule()->getDataLayout();
+    Type *IntTy =
+        IntegerType::get(B.getContext(), DL.getTypeStoreSizeInBits(Ty));
+    if (Ty == IntTy)
+      return Scalar;
+    if (Ty->isIntOrIntVectorTy())
+      return B.CreateIntCast(Scalar, IntTy, /*isSigned=*/false);
+    return B.CreateBitCast(Scalar, IntTy);
+  }
+
+  Value *storeIntToScalar(IRBuilder<> &B, Value *IntVal, Type *ScalarTy) {
+    if (IntVal->getType() == ScalarTy)
+      return IntVal;
+    if (ScalarTy->isIntOrIntVectorTy())
+      return B.CreateIntCast(IntVal, ScalarTy, /*isSigned=*/false);
+    return B.CreateBitCast(IntVal, ScalarTy);
+  }
+
+  void storeScalarToByteLayout(IRBuilder<> &B, Value *Src, Value *Dst,
+                               Align Alignment) {
+    LLVMContext &Ctx = B.getContext();
+    Type *I8Ty = Type::getInt8Ty(Ctx);
+    const DataLayout &DL = B.GetInsertBlock()->getModule()->getDataLayout();
+    Value *IntVal = scalarToStoreInt(B, Src);
+    unsigned NumBytes = DL.getTypeStoreSize(Src->getType());
+
+    for (unsigned I = 0; I < NumBytes; ++I) {
+      Value *Shifted =
+          I == 0 ? IntVal
+                 : B.CreateLShr(IntVal,
+                                ConstantInt::get(IntVal->getType(), 8 * I));
+      Value *Byte = B.CreateTrunc(Shifted, I8Ty);
+      buildAssignType(B, I8Ty, Byte);
+      Value *Ptr = gepByteOffset(B, Dst, I);
+      StoreInst *SI = B.CreateStore(Byte, Ptr);
+      SI->setAlignment(commonAlignment(Alignment, I));
+    }
+  }
+
+  Value *loadScalarFromByteLayout(IRBuilder<> &B, Type *AccessTy, Value *Src,
+                                  Align Alignment) {
+    LLVMContext &Ctx = B.getContext();
+    Type *I8Ty = Type::getInt8Ty(Ctx);
+    const DataLayout &DL = B.GetInsertBlock()->getModule()->getDataLayout();
+    unsigned NumBytes = DL.getTypeStoreSize(AccessTy);
+    Type *IntTy = IntegerType::get(Ctx, DL.getTypeStoreSizeInBits(AccessTy));
+    Value *IntVal = ConstantInt::get(IntTy, 0);
+
+    for (unsigned I = 0; I < NumBytes; ++I) {
+      Value *Ptr = gepByteOffset(B, Src, I);
+      LoadInst *LI = B.CreateLoad(I8Ty, Ptr);
+      LI->setAlignment(commonAlignment(Alignment, I));
+      buildAssignType(B, I8Ty, LI);
+      Value *Extended = B.CreateZExt(LI, IntTy);
+      buildAssignType(B, IntTy, Extended);
+      Value *Shifted =
+          I == 0 ? Extended
----------------
farzonl wrote:

same comment here.

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


More information about the llvm-commits mailing list