[llvm] [DirectX] legalize memset (PR #136244)

Farzon Lotfi via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 21 15:41:14 PDT 2025


================
@@ -151,6 +152,82 @@ downcastI64toI32InsertExtractElements(Instruction &I,
   }
 }
 
+void emitMemset(IRBuilder<> &Builder, Value *Dst, Value *Val,
+                ConstantInt *SizeCI) {
+  LLVMContext &Ctx = Builder.getContext();
+  [[maybe_unused]] DataLayout DL =
+      Builder.GetInsertBlock()->getModule()->getDataLayout();
+  [[maybe_unused]] uint64_t OrigSize = SizeCI->getZExtValue();
+
+  AllocaInst *Alloca = dyn_cast<AllocaInst>(Dst);
+
+  assert(Alloca && "Expected memset on an Alloca");
+  assert(OrigSize == Alloca->getAllocationSize(DL)->getFixedValue() &&
+         "Expected for memset size to match DataLayout size");
+
+  Type *AllocatedTy = Alloca->getAllocatedType();
+  ArrayType *ArrTy = dyn_cast<ArrayType>(AllocatedTy);
+  assert(ArrTy && "Expected Alloca for an Array Type");
+
+  Type *ElemTy = ArrTy->getElementType();
+  uint64_t Size = ArrTy->getArrayNumElements();
+
+  [[maybe_unused]] uint64_t ElemSize = DL.getTypeStoreSize(ElemTy);
+
+  assert(ElemSize > 0 && "Size must be set");
+  assert(OrigSize == ElemSize * Size && "Size in bytes must match");
+
+  Value *TypedVal = Val;
+  if (Val->getType() != ElemTy)
+    TypedVal = Builder.CreateIntCast(Val, ElemTy,
----------------
farzonl wrote:

so memset require this input value to be an i8. So after legalization i'm left with code that looks like this:
```llvm
%accum.i.flat = alloca [1 x i32], align 4
%i = alloca i8, align 4
store i8 1, ptr %i
%i8.load = load i8, ptr %i
%z = zext i8 %i8.load to i32
%gep = getelementptr i32, ptr %accum.i.flat, i32 0
store i32 %z, ptr %gep, align 4
```
I'm assuming it isn't valid DXIL to alloca/load/store an i8?
Do we need to walk the uses to replace these with   gep/final store size  version in this case i32 instead of doing the `zext`?

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


More information about the llvm-commits mailing list