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

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 30 10:28:46 PDT 2025


================
@@ -239,6 +247,72 @@ downcastI64toI32InsertExtractElements(Instruction &I,
   }
 }
 
+void emitMemsetExpansion(IRBuilder<> &Builder, Value *Dst, Value *Val,
+                         ConstantInt *SizeCI,
+                         DenseMap<Value *, Value *> &ReplacedValues) {
+  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) {
+    // Note for i8 replacements if we know them we should use them.
+    // Further if this is a constant ReplacedValues will return null
+    // so we will stick to TypedVal = Val
+    if (ReplacedValues[Val])
+      TypedVal = ReplacedValues[Val];
+    // This case Val is a ConstantInt so the cast folds away.
+    // However if we don't do the cast the store below ends up being
+    // an i8.
+    else
+      TypedVal = Builder.CreateIntCast(Val, ElemTy, false);
+  }
+
+  for (uint64_t I = 0; I < Size; ++I) {
+    Value *Offset = ConstantInt::get(Type::getInt32Ty(Ctx), I);
+    Value *Ptr = Builder.CreateGEP(ElemTy, Dst, Offset, "gep");
+    Builder.CreateStore(TypedVal, Ptr);
+  }
+}
+
+static void removeMemSet(Instruction &I,
+                         SmallVectorImpl<Instruction *> &ToRemove,
+                         DenseMap<Value *, Value *> &ReplacedValues) {
+  if (CallInst *CI = dyn_cast<CallInst>(&I)) {
+    Intrinsic::ID ID = CI->getIntrinsicID();
+    if (ID == Intrinsic::memset) {
+      IRBuilder<> Builder(&I);
+      Value *Dst = CI->getArgOperand(0);
+      Value *Val = CI->getArgOperand(1);
+      [[maybe_unused]] ConstantInt *Size =
+          dyn_cast<ConstantInt>(CI->getArgOperand(2));
----------------
bogner wrote:

This is used in `emitMemsetExpansion`, so we don't need the `[[maybe_unused]]`

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


More information about the llvm-commits mailing list