[llvm] [DirectX] Legalize memcpy (PR #139173)
Deric C. via llvm-commits
llvm-commits at lists.llvm.org
Thu May 15 12:59:53 PDT 2025
================
@@ -246,6 +246,61 @@ downcastI64toI32InsertExtractElements(Instruction &I,
}
}
+static void emitMemcpyExpansion(IRBuilder<> &Builder, Value *Dst, Value *Src,
+ ConstantInt *Length) {
+
+ uint64_t ByteLength = Length->getZExtValue();
+ if (ByteLength == 0)
+ return;
+
+ LLVMContext &Ctx = Builder.getContext();
+ const DataLayout &DL = Builder.GetInsertBlock()->getModule()->getDataLayout();
+
+ auto GetArrTyFromVal = [](Value *Val) -> ArrayType * {
+ assert(isa<AllocaInst>(Val) ||
+ isa<GlobalVariable>(Val) &&
+ "Expected Val to be an Alloca or Global Variable");
+ if (auto *Alloca = dyn_cast<AllocaInst>(Val))
+ return dyn_cast<ArrayType>(Alloca->getAllocatedType());
+ if (auto *GlobalVar = dyn_cast<GlobalVariable>(Val))
+ return dyn_cast<ArrayType>(GlobalVar->getValueType());
+ return nullptr;
+ };
+
+ ArrayType *ArrTy = GetArrTyFromVal(Dst);
+ assert(ArrTy && "Expected Dst of memcpy to be a Pointer to an Array Type");
+ if (auto *DstGlobalVar = dyn_cast<GlobalVariable>(Dst))
+ assert(!DstGlobalVar->isConstant() &&
+ "The Dst of memcpy must not be a constant Global Variable");
+
+ [[maybe_unused]] ArrayType *SrcArrTy = GetArrTyFromVal(Src);
+ assert(SrcArrTy && "Expected Src of memcpy to be a Pointer to an Array Type");
+
+ // This assumption simplifies implementation and covers currently-known
+ // use-cases for DXIL. It may be relaxed in the future if required.
+ assert(ArrTy == SrcArrTy &&
+ "Array Types of Src and Dst in memcpy must match");
+
+ Type *ElemTy = ArrTy->getElementType();
+ uint64_t ElemSize = DL.getTypeStoreSize(ElemTy);
+ assert(ElemSize > 0 && "Size must be set");
+
+ [[maybe_unused]] uint64_t Size = ArrTy->getArrayNumElements();
+ assert(ElemSize * Size >= ByteLength &&
+ "Array size must be at least as large as the memcpy length");
+
+ uint64_t NumElemsToCopy = ByteLength / ElemSize;
+ assert(ByteLength % ElemSize == 0 &&
+ "memcpy length must be divisible by array element type");
+ for (uint64_t I = 0; I < NumElemsToCopy; ++I) {
+ Value *Offset = ConstantInt::get(Type::getInt32Ty(Ctx), I);
+ Value *SrcPtr = Builder.CreateGEP(ElemTy, Src, Offset, "gep");
----------------
Icohedron wrote:
The asserts do ensure that the GEP is inbounds, so I think it should be fine to set `GEP.isInBounds()` which by definition also implies no unsigned signed wrapping (nusw)
https://github.com/llvm/llvm-project/pull/139173
More information about the llvm-commits
mailing list