@@ -268,36 +268,41 @@ static void emitMemcpyExpansion(IRBuilder<> &Builder, Value *Dst, Value *Src,
268268    return  nullptr ;
269269  };
270270
271-   ArrayType *ArrTy  = GetArrTyFromVal (Dst);
272-   assert (ArrTy  && " Expected Dst of memcpy to be a Pointer to an Array Type" 
271+   ArrayType *DstArrTy  = GetArrTyFromVal (Dst);
272+   assert (DstArrTy  && " Expected Dst of memcpy to be a Pointer to an Array Type" 
273273  if  (auto  *DstGlobalVar = dyn_cast<GlobalVariable>(Dst))
274274    assert (!DstGlobalVar->isConstant () &&
275275           " The Dst of memcpy must not be a constant Global Variable" 
276- 
277276  [[maybe_unused]] ArrayType *SrcArrTy = GetArrTyFromVal (Src);
278277  assert (SrcArrTy && " Expected Src of memcpy to be a Pointer to an Array Type" 
279278
279+   Type *DstElemTy = DstArrTy->getElementType ();
280+   uint64_t  DstElemByteSize = DL.getTypeStoreSize (DstElemTy);
281+   assert (DstElemByteSize > 0  && " Dst element type store size must be set" 
282+   Type *SrcElemTy = SrcArrTy->getElementType ();
283+   [[maybe_unused]] uint64_t  SrcElemByteSize = DL.getTypeStoreSize (SrcElemTy);
284+   assert (SrcElemByteSize > 0  && " Src element type store size must be set" 
285+ 
280286  //  This assumption simplifies implementation and covers currently-known
281287  //  use-cases for DXIL. It may be relaxed in the future if required.
282-   assert (ArrTy == SrcArrTy &&
283-          " Array Types of Src and Dst in memcpy must match" 
284- 
285-   Type *ElemTy = ArrTy->getElementType ();
286-   uint64_t  ElemSize = DL.getTypeStoreSize (ElemTy);
287-   assert (ElemSize > 0  && " Size must be set" 
288- 
289-   [[maybe_unused]] uint64_t  Size = ArrTy->getArrayNumElements ();
290-   assert (ElemSize * Size >= ByteLength &&
291-          " Array size must be at least as large as the memcpy length" 
292- 
293-   uint64_t  NumElemsToCopy = ByteLength / ElemSize;
294-   assert (ByteLength % ElemSize == 0  &&
288+   assert (DstElemTy == SrcElemTy &&
289+          " The element types of Src and Dst arrays must match" 
290+ 
291+   [[maybe_unused]] uint64_t  DstArrNumElems = DstArrTy->getArrayNumElements ();
292+   assert (DstElemByteSize * DstArrNumElems >= ByteLength &&
293+          " Dst array size must be at least as large as the memcpy length" 
294+   [[maybe_unused]] uint64_t  SrcArrNumElems = SrcArrTy->getArrayNumElements ();
295+   assert (SrcElemByteSize * SrcArrNumElems >= ByteLength &&
296+          " Src array size must be at least as large as the memcpy length" 
297+ 
298+   uint64_t  NumElemsToCopy = ByteLength / DstElemByteSize;
299+   assert (ByteLength % DstElemByteSize == 0  &&
295300         " memcpy length must be divisible by array element type" 
296301  for  (uint64_t  I = 0 ; I < NumElemsToCopy; ++I) {
297302    Value *Offset = ConstantInt::get (Type::getInt32Ty (Ctx), I);
298-     Value *SrcPtr = Builder.CreateInBoundsGEP (ElemTy , Src, Offset, " gep" 
299-     Value *SrcVal = Builder.CreateLoad (ElemTy , SrcPtr);
300-     Value *DstPtr = Builder.CreateInBoundsGEP (ElemTy , Dst, Offset, " gep" 
303+     Value *SrcPtr = Builder.CreateInBoundsGEP (SrcElemTy , Src, Offset, " gep" 
304+     Value *SrcVal = Builder.CreateLoad (SrcElemTy , SrcPtr);
305+     Value *DstPtr = Builder.CreateInBoundsGEP (DstElemTy , Dst, Offset, " gep" 
301306    Builder.CreateStore (SrcVal, DstPtr);
302307  }
303308}
0 commit comments