LLVM 24.0.0git
LowerMemIntrinsics.cpp
Go to the documentation of this file.
1//===- LowerMemIntrinsics.cpp ----------------------------------*- C++ -*--===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "llvm/IR/IRBuilder.h"
14#include "llvm/IR/MDBuilder.h"
17#include "llvm/Support/Debug.h"
21#include <cmath>
22#include <limits>
23#include <optional>
24
25#define DEBUG_TYPE "lower-mem-intrinsics"
26
27using namespace llvm;
28
29/// \returns \p Len urem \p OpSize, checking for optimization opportunities.
30/// \p OpSizeVal must be the integer value of the \c ConstantInt \p OpSize.
32 Value *OpSize, unsigned OpSizeVal) {
33 // For powers of 2, we can and by (OpSizeVal - 1) instead of using urem.
34 if (isPowerOf2_32(OpSizeVal))
35 return B.CreateAnd(Len, OpSizeVal - 1);
36 return B.CreateURem(Len, OpSize);
37}
38
39/// \returns (\p Len udiv \p OpSize) mul \p OpSize, checking for optimization
40/// opportunities.
41/// If \p RTLoopRemainder is provided, it must be the result of
42/// \c getRuntimeLoopRemainder() with the same arguments.
44 unsigned OpSizeVal,
45 Value *RTLoopRemainder = nullptr) {
46 if (!RTLoopRemainder)
47 RTLoopRemainder = getRuntimeLoopRemainder(B, Len, OpSize, OpSizeVal);
48 return B.CreateSub(Len, RTLoopRemainder);
49}
50
51namespace {
52/// Container for the return values of insertLoopExpansion.
53struct LoopExpansionInfo {
54 /// The instruction at the end of the main loop body.
55 Instruction *MainLoopIP = nullptr;
56
57 /// The unit index in the main loop body.
58 Value *MainLoopIndex = nullptr;
59
60 /// The instruction at the end of the residual loop body. Can be nullptr if no
61 /// residual is required.
62 Instruction *ResidualLoopIP = nullptr;
63
64 /// The unit index in the residual loop body. Can be nullptr if no residual is
65 /// required.
66 Value *ResidualLoopIndex = nullptr;
67};
68
69std::optional<uint64_t> getAverageMemOpLoopTripCount(const MemIntrinsic &I) {
70 if (std::optional<uint64_t> EC = I.getFunction()->getEntryCount();
71 !EC || *EC == 0)
72 return std::nullopt;
73 if (const auto Len = I.getLengthInBytes())
74 return Len->getZExtValue();
75 uint64_t Total = 0;
77 getValueProfDataFromInst(I, InstrProfValueKind::IPVK_MemOPSize,
78 std::numeric_limits<uint32_t>::max(), Total);
79 if (!Total)
80 return std::nullopt;
81 uint64_t TripCount = 0;
82 for (const auto &P : ProfData)
83 TripCount += P.Count * P.Value;
84 return std::round(1.0 * TripCount / Total);
85}
86
87} // namespace
88
89/// Insert the control flow and loop counters for a memcpy/memset loop
90/// expansion.
91///
92/// This function inserts IR corresponding to the following C code before
93/// \p InsertBefore:
94/// \code
95/// LoopUnits = (Len / MainLoopStep) * MainLoopStep;
96/// ResidualUnits = Len - LoopUnits;
97/// MainLoopIndex = 0;
98/// if (LoopUnits > 0) {
99/// do {
100/// // MainLoopIP
101/// MainLoopIndex += MainLoopStep;
102/// } while (MainLoopIndex < LoopUnits);
103/// }
104/// for (size_t i = 0; i < ResidualUnits; i += ResidualLoopStep) {
105/// ResidualLoopIndex = LoopUnits + i;
106/// // ResidualLoopIP
107/// }
108/// \endcode
109///
110/// \p MainLoopStep and \p ResidualLoopStep determine by how many "units" the
111/// loop index is increased in each iteration of the main and residual loops,
112/// respectively. In most cases, the "unit" will be bytes, but larger units are
113/// useful for lowering memset.pattern.
114///
115/// The computation of \c LoopUnits and \c ResidualUnits is performed at compile
116/// time if \p Len is a \c ConstantInt.
117/// The second (residual) loop is omitted if \p ResidualLoopStep is 0 or equal
118/// to \p MainLoopStep.
119/// The generated \c MainLoopIP, \c MainLoopIndex, \c ResidualLoopIP, and
120/// \c ResidualLoopIndex are returned in a \c LoopExpansionInfo object.
121///
122/// If provided, \p ExpectedUnits is used as the expected number of units
123/// handled by the loop expansion when computing branch weights.
124static LoopExpansionInfo
126 unsigned MainLoopStep, unsigned ResidualLoopStep,
127 StringRef BBNamePrefix,
128 std::optional<uint64_t> ExpectedUnits) {
129 assert((ResidualLoopStep == 0 || MainLoopStep % ResidualLoopStep == 0) &&
130 "ResidualLoopStep must divide MainLoopStep if specified");
131 assert(ResidualLoopStep <= MainLoopStep &&
132 "ResidualLoopStep cannot be larger than MainLoopStep");
133 assert(MainLoopStep > 0 && "MainLoopStep must be non-zero");
134 LoopExpansionInfo LEI;
135
136 // If the length is known to be zero, there is nothing to do.
137 if (auto *CLen = dyn_cast<ConstantInt>(Len))
138 if (CLen->isZero())
139 return LEI;
140
141 BasicBlock *PreLoopBB = InsertBefore->getParent();
142 BasicBlock *PostLoopBB = PreLoopBB->splitBasicBlock(
143 InsertBefore, BBNamePrefix + "-post-expansion");
144 Function *ParentFunc = PreLoopBB->getParent();
145 LLVMContext &Ctx = PreLoopBB->getContext();
146 const DebugLoc &DbgLoc = InsertBefore->getStableDebugLoc();
147 IRBuilder<> PreLoopBuilder(PreLoopBB->getTerminator());
148 PreLoopBuilder.SetCurrentDebugLocation(DbgLoc);
149
150 // Calculate the main loop trip count and remaining units to cover after the
151 // loop.
152 Type *LenType = Len->getType();
153 IntegerType *ILenType = cast<IntegerType>(LenType);
154 ConstantInt *CIMainLoopStep = ConstantInt::get(ILenType, MainLoopStep);
155 ConstantInt *Zero = ConstantInt::get(ILenType, 0U);
156
157 // We can avoid conditional branches and/or entire loops if we know any of the
158 // following:
159 // - that the main loop must be executed at least once
160 // - that the main loop will not be executed at all
161 // - that the residual loop must be executed at least once
162 // - that the residual loop will not be executed at all
163 bool MustTakeMainLoop = false;
164 bool MayTakeMainLoop = true;
165 bool MustTakeResidualLoop = false;
166 bool MayTakeResidualLoop = true;
167
168 Value *LoopUnits = Len;
169 Value *ResidualUnits = nullptr;
170 if (MainLoopStep != 1) {
171 if (auto *CLen = dyn_cast<ConstantInt>(Len)) {
172 uint64_t TotalUnits = CLen->getZExtValue();
173 uint64_t LoopEndCount = alignDown(TotalUnits, MainLoopStep);
174 uint64_t ResidualCount = TotalUnits - LoopEndCount;
175 LoopUnits = ConstantInt::get(LenType, LoopEndCount);
176 ResidualUnits = ConstantInt::get(LenType, ResidualCount);
177 MustTakeMainLoop = LoopEndCount > 0;
178 MayTakeMainLoop = MustTakeMainLoop;
179 MustTakeResidualLoop = ResidualCount > 0;
180 MayTakeResidualLoop = MustTakeResidualLoop;
181 // TODO: This could also use known bits to check if a non-constant loop
182 // count is guaranteed to be a multiple of MainLoopStep, in which case we
183 // could omit the residual loop. It's unclear if that is worthwhile.
184 } else {
185 ResidualUnits = getRuntimeLoopRemainder(PreLoopBuilder, Len,
186 CIMainLoopStep, MainLoopStep);
187 LoopUnits = getRuntimeLoopUnits(PreLoopBuilder, Len, CIMainLoopStep,
188 MainLoopStep, ResidualUnits);
189 }
190 } else if (auto *CLen = dyn_cast<ConstantInt>(Len)) {
191 MustTakeMainLoop = CLen->getZExtValue() > 0;
192 MayTakeMainLoop = MustTakeMainLoop;
193 }
194
195 // The case where both loops are omitted (i.e., the length is known zero) is
196 // already handled at the beginning of this function.
197 assert((MayTakeMainLoop || MayTakeResidualLoop) &&
198 "At least one of the loops must be generated");
199
200 BasicBlock *MainLoopBB = nullptr;
201 CondBrInst *MainLoopBr = nullptr;
202
203 // Construct the main loop unless we statically known that it is not taken.
204 if (MayTakeMainLoop) {
205 MainLoopBB = BasicBlock::Create(Ctx, BBNamePrefix + "-expansion-main-body",
206 ParentFunc, PostLoopBB);
207 IRBuilder<> LoopBuilder(MainLoopBB);
208 LoopBuilder.SetCurrentDebugLocation(DbgLoc);
209
210 PHINode *LoopIndex = LoopBuilder.CreatePHI(LenType, 2, "loop-index");
211 LEI.MainLoopIndex = LoopIndex;
212 LoopIndex->addIncoming(ConstantInt::get(LenType, 0U), PreLoopBB);
213
214 Value *NewIndex = LoopBuilder.CreateAdd(
215 LoopIndex, ConstantInt::get(LenType, MainLoopStep));
216 LoopIndex->addIncoming(NewIndex, MainLoopBB);
217
218 // One argument of the addition is a loop-variant PHI, so it must be an
219 // Instruction (i.e., it cannot be a Constant).
220 LEI.MainLoopIP = cast<Instruction>(NewIndex);
221
222 // Stay in the MainLoop until we have handled all the LoopUnits. The False
223 // target is adjusted below if a residual is generated.
224 MainLoopBr = LoopBuilder.CreateCondBr(
225 LoopBuilder.CreateICmpULT(NewIndex, LoopUnits), MainLoopBB, PostLoopBB);
226
227 if (ExpectedUnits.has_value()) {
228 uint64_t BackedgeTakenCount = ExpectedUnits.value() / MainLoopStep;
229 if (BackedgeTakenCount > 0)
230 BackedgeTakenCount -= 1; // The last iteration goes to the False target.
231 MDBuilder MDB(ParentFunc->getContext());
232 setFittedBranchWeights(*MainLoopBr, {BackedgeTakenCount, 1},
233 /*IsExpected=*/false);
234 } else {
236 }
237 }
238
239 // Construct the residual loop if it is requested from the caller unless we
240 // statically know that it won't be taken.
241 bool ResidualLoopRequested =
242 ResidualLoopStep > 0 && ResidualLoopStep < MainLoopStep;
243 BasicBlock *ResidualLoopBB = nullptr;
244 BasicBlock *ResidualCondBB = nullptr;
245 if (ResidualLoopRequested && MayTakeResidualLoop) {
246 ResidualLoopBB =
247 BasicBlock::Create(Ctx, BBNamePrefix + "-expansion-residual-body",
248 PreLoopBB->getParent(), PostLoopBB);
249
250 // The residual loop body is either reached from the ResidualCondBB (which
251 // checks if the residual loop needs to be executed), from the main loop
252 // body if we know statically that the residual must be executed, or from
253 // the pre-loop BB (conditionally or unconditionally) if the main loop is
254 // omitted.
255 BasicBlock *PredOfResLoopBody = PreLoopBB;
256 if (MainLoopBB) {
257 // If it's statically known that the residual must be executed, we don't
258 // need to create a preheader BB.
259 if (MustTakeResidualLoop) {
260 MainLoopBr->setSuccessor(1, ResidualLoopBB);
261 PredOfResLoopBody = MainLoopBB;
262 } else {
263 // Construct a preheader BB to check if the residual loop is executed.
264 ResidualCondBB =
265 BasicBlock::Create(Ctx, BBNamePrefix + "-expansion-residual-cond",
266 PreLoopBB->getParent(), ResidualLoopBB);
267
268 // Determine if we need to branch to the residual loop or bypass it.
269 IRBuilder<> RCBuilder(ResidualCondBB);
270 RCBuilder.SetCurrentDebugLocation(DbgLoc);
271 auto *BR =
272 RCBuilder.CreateCondBr(RCBuilder.CreateICmpNE(ResidualUnits, Zero),
273 ResidualLoopBB, PostLoopBB);
274 if (ExpectedUnits.has_value()) {
275 MDBuilder MDB(ParentFunc->getContext());
276 BR->setMetadata(LLVMContext::MD_prof,
278 } else {
280 }
281
282 MainLoopBr->setSuccessor(1, ResidualCondBB);
283 PredOfResLoopBody = ResidualCondBB;
284 }
285 }
286
287 IRBuilder<> ResBuilder(ResidualLoopBB);
288 ResBuilder.SetCurrentDebugLocation(DbgLoc);
289 PHINode *ResidualIndex =
290 ResBuilder.CreatePHI(LenType, 2, "residual-loop-index");
291 ResidualIndex->addIncoming(Zero, PredOfResLoopBody);
292
293 // Add the offset at the end of the main loop to the loop counter of the
294 // residual loop to get the proper index. If the main loop was omitted, we
295 // can also omit the addition.
296 if (MainLoopBB)
297 LEI.ResidualLoopIndex = ResBuilder.CreateAdd(LoopUnits, ResidualIndex);
298 else
299 LEI.ResidualLoopIndex = ResidualIndex;
300
301 Value *ResNewIndex = ResBuilder.CreateAdd(
302 ResidualIndex, ConstantInt::get(LenType, ResidualLoopStep));
303 ResidualIndex->addIncoming(ResNewIndex, ResidualLoopBB);
304
305 // One argument of the addition is a loop-variant PHI, so it must be an
306 // Instruction (i.e., it cannot be a Constant).
307 LEI.ResidualLoopIP = cast<Instruction>(ResNewIndex);
308
309 // Stay in the residual loop until all ResidualUnits are handled.
310 CondBrInst *BR = ResBuilder.CreateCondBr(
311 ResBuilder.CreateICmpULT(ResNewIndex, ResidualUnits), ResidualLoopBB,
312 PostLoopBB);
313
314 if (ExpectedUnits.has_value()) {
315 uint64_t BackedgeTakenCount =
316 (ExpectedUnits.value() % MainLoopStep) / ResidualLoopStep;
317 if (BackedgeTakenCount > 0)
318 BackedgeTakenCount -= 1; // The last iteration goes to the False target.
319 MDBuilder MDB(ParentFunc->getContext());
320 setFittedBranchWeights(*BR, {BackedgeTakenCount, 1},
321 /*IsExpected=*/false);
322 } else {
324 }
325 }
326
327 // Create the branch in the pre-loop block.
328 if (MustTakeMainLoop) {
329 // Go unconditionally to the main loop if it's statically known that it must
330 // be executed.
331 assert(MainLoopBB);
332 PreLoopBuilder.CreateBr(MainLoopBB);
333 } else if (!MainLoopBB && ResidualLoopBB) {
334 if (MustTakeResidualLoop) {
335 // If the main loop is omitted and the residual loop is statically known
336 // to be executed, go there unconditionally.
337 PreLoopBuilder.CreateBr(ResidualLoopBB);
338 } else {
339 // If the main loop is omitted and we don't know if the residual loop is
340 // executed, go there if necessary. The PreLoopBB takes the role of the
341 // preheader for the residual loop in this case.
342 auto *BR = PreLoopBuilder.CreateCondBr(
343 PreLoopBuilder.CreateICmpNE(ResidualUnits, Zero), ResidualLoopBB,
344 PostLoopBB);
345 if (ExpectedUnits.has_value()) {
346 MDBuilder MDB(ParentFunc->getContext());
347 BR->setMetadata(LLVMContext::MD_prof, MDB.createLikelyBranchWeights());
348 } else {
350 }
351 }
352 } else {
353 // Otherwise, go conditionally to the main loop or its successor.
354 // If there is no residual loop, the successor is the post-loop BB.
355 BasicBlock *FalseBB = PostLoopBB;
356 if (ResidualCondBB) {
357 // If we constructed a pre-header for the residual loop, that is the
358 // successor.
359 FalseBB = ResidualCondBB;
360 } else if (ResidualLoopBB) {
361 // If there is a residual loop but the preheader is omitted (because the
362 // residual loop is statically known to be executed), the successor
363 // is the residual loop body.
364 assert(MustTakeResidualLoop);
365 FalseBB = ResidualLoopBB;
366 }
367
368 auto *BR = PreLoopBuilder.CreateCondBr(
369 PreLoopBuilder.CreateICmpNE(LoopUnits, Zero), MainLoopBB, FalseBB);
370
371 if (ExpectedUnits.has_value()) {
372 MDBuilder MDB(ParentFunc->getContext());
373 BR->setMetadata(LLVMContext::MD_prof, MDB.createLikelyBranchWeights());
374 } else {
376 }
377 }
378 // Delete the unconditional branch inserted by splitBasicBlock.
379 PreLoopBB->getTerminator()->eraseFromParent();
380
381 return LEI;
382}
383
385 Value *DstAddr, ConstantInt *CopyLen,
386 Align SrcAlign, Align DstAlign,
387 bool SrcIsVolatile, bool DstIsVolatile,
388 bool CanOverlap,
390 std::optional<uint32_t> AtomicElementSize,
391 std::optional<uint64_t> AverageTripCount) {
392 // No need to expand zero length copies.
393 if (CopyLen->isZero())
394 return;
395
396 BasicBlock *PreLoopBB = InsertBefore->getParent();
397 Function *ParentFunc = PreLoopBB->getParent();
398 LLVMContext &Ctx = PreLoopBB->getContext();
399 const DataLayout &DL = ParentFunc->getDataLayout();
400 MDBuilder MDB(Ctx);
401 MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain("MemCopyDomain");
402 StringRef Name = "MemCopyAliasScope";
403 MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name);
404
405 unsigned SrcAS = cast<PointerType>(SrcAddr->getType())->getAddressSpace();
406 unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
407
408 Type *TypeOfCopyLen = CopyLen->getType();
409 Type *LoopOpType = TTI.getMemcpyLoopLoweringType(
410 Ctx, CopyLen, SrcAS, DstAS, SrcAlign, DstAlign, AtomicElementSize);
411 assert((!AtomicElementSize || !LoopOpType->isVectorTy()) &&
412 "Atomic memcpy lowering is not supported for vector operand type");
413
414 Type *Int8Type = Type::getInt8Ty(Ctx);
415 TypeSize LoopOpSize = DL.getTypeStoreSize(LoopOpType);
416 assert(LoopOpSize.isFixed() && "LoopOpType cannot be a scalable vector type");
417 assert((!AtomicElementSize || LoopOpSize % *AtomicElementSize == 0) &&
418 "Atomic memcpy lowering is not supported for selected operand size");
419
420 uint64_t LoopEndCount =
421 alignDown(CopyLen->getZExtValue(), LoopOpSize.getFixedValue());
422
423 // Skip the loop expansion entirely if the loop would never be taken.
424 if (LoopEndCount != 0) {
425 LoopExpansionInfo LEI =
426 insertLoopExpansion(InsertBefore, CopyLen, LoopOpSize, 0,
427 "static-memcpy", AverageTripCount);
428 assert(LEI.MainLoopIP && LEI.MainLoopIndex &&
429 "Main loop should be generated for non-zero loop count");
430
431 // Fill MainLoopBB
432 IRBuilder<> MainLoopBuilder(LEI.MainLoopIP);
433 Align PartDstAlign(commonAlignment(DstAlign, LoopOpSize));
434 Align PartSrcAlign(commonAlignment(SrcAlign, LoopOpSize));
435
436 // If we used LoopOpType as GEP element type, we would iterate over the
437 // buffers in TypeStoreSize strides while copying TypeAllocSize bytes, i.e.,
438 // we would miss bytes if TypeStoreSize != TypeAllocSize. Therefore, use
439 // byte offsets computed from the TypeStoreSize.
440 Value *SrcGEP =
441 MainLoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr, LEI.MainLoopIndex);
442 LoadInst *Load = MainLoopBuilder.CreateAlignedLoad(
443 LoopOpType, SrcGEP, PartSrcAlign, SrcIsVolatile);
444 if (!CanOverlap) {
445 // Set alias scope for loads.
446 Load->setMetadata(LLVMContext::MD_alias_scope,
447 MDNode::get(Ctx, NewScope));
448 }
449 Value *DstGEP =
450 MainLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, LEI.MainLoopIndex);
451 StoreInst *Store = MainLoopBuilder.CreateAlignedStore(
452 Load, DstGEP, PartDstAlign, DstIsVolatile);
453 if (!CanOverlap) {
454 // Indicate that stores don't overlap loads.
455 Store->setMetadata(LLVMContext::MD_noalias, MDNode::get(Ctx, NewScope));
456 }
457 if (AtomicElementSize) {
460 }
461 assert(!LEI.ResidualLoopIP && !LEI.ResidualLoopIndex &&
462 "No residual loop was requested");
463 }
464
465 // Copy the remaining bytes with straight-line code.
466 uint64_t BytesCopied = LoopEndCount;
467 uint64_t RemainingBytes = CopyLen->getZExtValue() - BytesCopied;
468 if (RemainingBytes == 0)
469 return;
470
471 IRBuilder<> RBuilder(InsertBefore);
472 SmallVector<Type *, 5> RemainingOps;
473 TTI.getMemcpyLoopResidualLoweringType(RemainingOps, Ctx, RemainingBytes,
474 SrcAS, DstAS, SrcAlign, DstAlign,
475 AtomicElementSize);
476
477 for (auto *OpTy : RemainingOps) {
478 Align PartSrcAlign(commonAlignment(SrcAlign, BytesCopied));
479 Align PartDstAlign(commonAlignment(DstAlign, BytesCopied));
480
481 TypeSize OperandSize = DL.getTypeStoreSize(OpTy);
482 assert((!AtomicElementSize || OperandSize % *AtomicElementSize == 0) &&
483 "Atomic memcpy lowering is not supported for selected operand size");
484
485 Value *SrcGEP = RBuilder.CreateInBoundsGEP(
486 Int8Type, SrcAddr, ConstantInt::get(TypeOfCopyLen, BytesCopied));
487 LoadInst *Load =
488 RBuilder.CreateAlignedLoad(OpTy, SrcGEP, PartSrcAlign, SrcIsVolatile);
489 if (!CanOverlap) {
490 // Set alias scope for loads.
491 Load->setMetadata(LLVMContext::MD_alias_scope,
492 MDNode::get(Ctx, NewScope));
493 }
494 Value *DstGEP = RBuilder.CreateInBoundsGEP(
495 Int8Type, DstAddr, ConstantInt::get(TypeOfCopyLen, BytesCopied));
497 RBuilder.CreateAlignedStore(Load, DstGEP, PartDstAlign, DstIsVolatile);
498 if (!CanOverlap) {
499 // Indicate that stores don't overlap loads.
500 Store->setMetadata(LLVMContext::MD_noalias, MDNode::get(Ctx, NewScope));
501 }
502 if (AtomicElementSize) {
505 }
506 BytesCopied += OperandSize;
507 }
508 assert(BytesCopied == CopyLen->getZExtValue() &&
509 "Bytes copied should match size in the call!");
510}
511
513 Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr, Value *CopyLen,
514 Align SrcAlign, Align DstAlign, bool SrcIsVolatile, bool DstIsVolatile,
515 bool CanOverlap, const TargetTransformInfo &TTI,
516 std::optional<uint32_t> AtomicElementSize,
517 std::optional<uint64_t> AverageTripCount) {
518 BasicBlock *PreLoopBB = InsertBefore->getParent();
519 Function *ParentFunc = PreLoopBB->getParent();
520 const DataLayout &DL = ParentFunc->getDataLayout();
521 LLVMContext &Ctx = PreLoopBB->getContext();
522 MDBuilder MDB(Ctx);
523 MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain("MemCopyDomain");
524 StringRef Name = "MemCopyAliasScope";
525 MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name);
526
527 unsigned SrcAS = cast<PointerType>(SrcAddr->getType())->getAddressSpace();
528 unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
529
530 Type *LoopOpType = TTI.getMemcpyLoopLoweringType(
531 Ctx, CopyLen, SrcAS, DstAS, SrcAlign, DstAlign, AtomicElementSize);
532 assert((!AtomicElementSize || !LoopOpType->isVectorTy()) &&
533 "Atomic memcpy lowering is not supported for vector operand type");
534 TypeSize LoopOpSize = DL.getTypeStoreSize(LoopOpType);
535 assert((!AtomicElementSize || LoopOpSize % *AtomicElementSize == 0) &&
536 "Atomic memcpy lowering is not supported for selected operand size");
537
538 Type *Int8Type = Type::getInt8Ty(Ctx);
539
540 Type *ResidualLoopOpType = AtomicElementSize
541 ? Type::getIntNTy(Ctx, *AtomicElementSize * 8)
542 : Int8Type;
543 TypeSize ResidualLoopOpSize = DL.getTypeStoreSize(ResidualLoopOpType);
544 assert(ResidualLoopOpSize == (AtomicElementSize ? *AtomicElementSize : 1) &&
545 "Store size is expected to match type size");
546
547 LoopExpansionInfo LEI =
548 insertLoopExpansion(InsertBefore, CopyLen, LoopOpSize, ResidualLoopOpSize,
549 "dynamic-memcpy", AverageTripCount);
550 assert(LEI.MainLoopIP && LEI.MainLoopIndex &&
551 "Main loop should be generated for unknown size copy");
552
553 // Fill MainLoopBB
554 IRBuilder<> MainLoopBuilder(LEI.MainLoopIP);
555 Align PartSrcAlign(commonAlignment(SrcAlign, LoopOpSize));
556 Align PartDstAlign(commonAlignment(DstAlign, LoopOpSize));
557
558 // If we used LoopOpType as GEP element type, we would iterate over the
559 // buffers in TypeStoreSize strides while copying TypeAllocSize bytes, i.e.,
560 // we would miss bytes if TypeStoreSize != TypeAllocSize. Therefore, use byte
561 // offsets computed from the TypeStoreSize.
562 Value *SrcGEP =
563 MainLoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr, LEI.MainLoopIndex);
564 LoadInst *Load = MainLoopBuilder.CreateAlignedLoad(
565 LoopOpType, SrcGEP, PartSrcAlign, SrcIsVolatile);
566 if (!CanOverlap) {
567 // Set alias scope for loads.
568 Load->setMetadata(LLVMContext::MD_alias_scope, MDNode::get(Ctx, NewScope));
569 }
570 Value *DstGEP =
571 MainLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, LEI.MainLoopIndex);
572 StoreInst *Store = MainLoopBuilder.CreateAlignedStore(
573 Load, DstGEP, PartDstAlign, DstIsVolatile);
574 if (!CanOverlap) {
575 // Indicate that stores don't overlap loads.
576 Store->setMetadata(LLVMContext::MD_noalias, MDNode::get(Ctx, NewScope));
577 }
578 if (AtomicElementSize) {
581 }
582
583 // Fill ResidualLoopBB.
584 if (!LEI.ResidualLoopIP)
585 return;
586
587 Align ResSrcAlign(commonAlignment(PartSrcAlign, ResidualLoopOpSize));
588 Align ResDstAlign(commonAlignment(PartDstAlign, ResidualLoopOpSize));
589
590 IRBuilder<> ResLoopBuilder(LEI.ResidualLoopIP);
591 Value *ResSrcGEP = ResLoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr,
592 LEI.ResidualLoopIndex);
593 LoadInst *ResLoad = ResLoopBuilder.CreateAlignedLoad(
594 ResidualLoopOpType, ResSrcGEP, ResSrcAlign, SrcIsVolatile);
595 if (!CanOverlap) {
596 // Set alias scope for loads.
597 ResLoad->setMetadata(LLVMContext::MD_alias_scope,
598 MDNode::get(Ctx, NewScope));
599 }
600 Value *ResDstGEP = ResLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr,
601 LEI.ResidualLoopIndex);
602 StoreInst *ResStore = ResLoopBuilder.CreateAlignedStore(
603 ResLoad, ResDstGEP, ResDstAlign, DstIsVolatile);
604 if (!CanOverlap) {
605 // Indicate that stores don't overlap loads.
606 ResStore->setMetadata(LLVMContext::MD_noalias, MDNode::get(Ctx, NewScope));
607 }
608 if (AtomicElementSize) {
611 }
612}
613
614// If \p Addr1 and \p Addr2 are pointers to different address spaces, create an
615// addresspacecast to obtain a pair of pointers in the same addressspace. The
616// caller needs to ensure that addrspacecasting is possible.
617// No-op if the pointers are in the same address space.
618static std::pair<Value *, Value *>
620 const TargetTransformInfo &TTI) {
621 Value *ResAddr1 = Addr1;
622 Value *ResAddr2 = Addr2;
623
624 unsigned AS1 = cast<PointerType>(Addr1->getType())->getAddressSpace();
625 unsigned AS2 = cast<PointerType>(Addr2->getType())->getAddressSpace();
626 if (AS1 != AS2) {
627 if (TTI.isValidAddrSpaceCast(AS2, AS1))
628 ResAddr2 = B.CreateAddrSpaceCast(Addr2, Addr1->getType());
629 else if (TTI.isValidAddrSpaceCast(AS1, AS2))
630 ResAddr1 = B.CreateAddrSpaceCast(Addr1, Addr2->getType());
631 else
632 llvm_unreachable("Can only lower memmove between address spaces if they "
633 "support addrspacecast");
634 }
635 return {ResAddr1, ResAddr2};
636}
637
638// Lower memmove to IR. memmove is required to correctly copy overlapping memory
639// regions; therefore, it has to check the relative positions of the source and
640// destination pointers and choose the copy direction accordingly.
641//
642// The code below is an IR rendition of this C function:
643//
644// void* memmove(void* dst, const void* src, size_t n) {
645// unsigned char* d = dst;
646// const unsigned char* s = src;
647// if (s < d) {
648// // copy backwards
649// while (n--) {
650// d[n] = s[n];
651// }
652// } else {
653// // copy forward
654// for (size_t i = 0; i < n; ++i) {
655// d[i] = s[i];
656// }
657// }
658// return dst;
659// }
660//
661// If the TargetTransformInfo specifies a wider MemcpyLoopLoweringType, it is
662// used for the memory accesses in the loops. Then, additional loops with
663// byte-wise accesses are added for the remaining bytes.
665 Value *SrcAddr, Value *DstAddr,
666 Value *CopyLen, Align SrcAlign,
667 Align DstAlign, bool SrcIsVolatile,
668 bool DstIsVolatile,
669 const TargetTransformInfo &TTI) {
670 Type *TypeOfCopyLen = CopyLen->getType();
671 BasicBlock *OrigBB = InsertBefore->getParent();
672 Function *F = OrigBB->getParent();
673 const DataLayout &DL = F->getDataLayout();
674 LLVMContext &Ctx = OrigBB->getContext();
675 unsigned SrcAS = cast<PointerType>(SrcAddr->getType())->getAddressSpace();
676 unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
677
678 Type *LoopOpType = TTI.getMemcpyLoopLoweringType(Ctx, CopyLen, SrcAS, DstAS,
679 SrcAlign, DstAlign);
680 TypeSize LoopOpSize = DL.getTypeStoreSize(LoopOpType);
681 Type *Int8Type = Type::getInt8Ty(Ctx);
682 bool LoopOpIsInt8 = LoopOpType == Int8Type;
683
684 // If the memory accesses are wider than one byte, residual loops with
685 // i8-accesses are required to move remaining bytes.
686 bool RequiresResidual = !LoopOpIsInt8;
687
688 Type *ResidualLoopOpType = Int8Type;
689 TypeSize ResidualLoopOpSize = DL.getTypeStoreSize(ResidualLoopOpType);
690
691 // Calculate the loop trip count and remaining bytes to copy after the loop.
692 IntegerType *ILengthType = cast<IntegerType>(TypeOfCopyLen);
693 ConstantInt *CILoopOpSize = ConstantInt::get(ILengthType, LoopOpSize);
694 ConstantInt *CIResidualLoopOpSize =
695 ConstantInt::get(ILengthType, ResidualLoopOpSize);
696 ConstantInt *Zero = ConstantInt::get(ILengthType, 0);
697
698 const DebugLoc &DbgLoc = InsertBefore->getStableDebugLoc();
699 IRBuilder<> PLBuilder(InsertBefore);
700 PLBuilder.SetCurrentDebugLocation(DbgLoc);
701
702 Value *RuntimeLoopBytes = CopyLen;
703 Value *RuntimeLoopRemainder = nullptr;
704 Value *SkipResidualCondition = nullptr;
705 if (RequiresResidual) {
706 RuntimeLoopRemainder =
707 getRuntimeLoopRemainder(PLBuilder, CopyLen, CILoopOpSize, LoopOpSize);
708 RuntimeLoopBytes = getRuntimeLoopUnits(PLBuilder, CopyLen, CILoopOpSize,
709 LoopOpSize, RuntimeLoopRemainder);
710 SkipResidualCondition =
711 PLBuilder.CreateICmpEQ(RuntimeLoopRemainder, Zero, "skip_residual");
712 }
713 Value *SkipMainCondition =
714 PLBuilder.CreateICmpEQ(RuntimeLoopBytes, Zero, "skip_main");
715
716 // Create the a comparison of src and dst, based on which we jump to either
717 // the forward-copy part of the function (if src >= dst) or the backwards-copy
718 // part (if src < dst).
719 // SplitBlockAndInsertIfThenElse conveniently creates the basic if-then-else
720 // structure. Its block terminators (unconditional branches) are replaced by
721 // the appropriate conditional branches when the loop is built.
722 // If the pointers are in different address spaces, they need to be converted
723 // to a compatible one. Cases where memory ranges in the different address
724 // spaces cannot overlap are lowered as memcpy and not handled here.
725 auto [CmpSrcAddr, CmpDstAddr] =
726 tryInsertCastToCommonAddrSpace(PLBuilder, SrcAddr, DstAddr, TTI);
727 Value *PtrCompare =
728 PLBuilder.CreateICmpULT(CmpSrcAddr, CmpDstAddr, "compare_src_dst");
729 Instruction *ThenTerm, *ElseTerm;
730 SplitBlockAndInsertIfThenElse(PtrCompare, InsertBefore->getIterator(),
731 &ThenTerm, &ElseTerm);
732
733 // If the LoopOpSize is greater than 1, each part of the function consists of
734 // four blocks:
735 // memmove_copy_backwards:
736 // skip the residual loop when 0 iterations are required
737 // memmove_bwd_residual_loop:
738 // copy the last few bytes individually so that the remaining length is
739 // a multiple of the LoopOpSize
740 // memmove_bwd_middle: skip the main loop when 0 iterations are required
741 // memmove_bwd_main_loop: the actual backwards loop BB with wide accesses
742 // memmove_copy_forward: skip the main loop when 0 iterations are required
743 // memmove_fwd_main_loop: the actual forward loop BB with wide accesses
744 // memmove_fwd_middle: skip the residual loop when 0 iterations are required
745 // memmove_fwd_residual_loop: copy the last few bytes individually
746 //
747 // The main and residual loop are switched between copying forward and
748 // backward so that the residual loop always operates on the end of the moved
749 // range. This is based on the assumption that buffers whose start is aligned
750 // with the LoopOpSize are more common than buffers whose end is.
751 //
752 // If the LoopOpSize is 1, each part of the function consists of two blocks:
753 // memmove_copy_backwards: skip the loop when 0 iterations are required
754 // memmove_bwd_main_loop: the actual backwards loop BB
755 // memmove_copy_forward: skip the loop when 0 iterations are required
756 // memmove_fwd_main_loop: the actual forward loop BB
757 BasicBlock *CopyBackwardsBB = ThenTerm->getParent();
758 CopyBackwardsBB->setName("memmove_copy_backwards");
759 BasicBlock *CopyForwardBB = ElseTerm->getParent();
760 CopyForwardBB->setName("memmove_copy_forward");
761 BasicBlock *ExitBB = InsertBefore->getParent();
762 ExitBB->setName("memmove_done");
763
764 Align PartSrcAlign(commonAlignment(SrcAlign, LoopOpSize));
765 Align PartDstAlign(commonAlignment(DstAlign, LoopOpSize));
766
767 // Accesses in the residual loops do not share the same alignment as those in
768 // the main loops.
769 Align ResidualSrcAlign(commonAlignment(PartSrcAlign, ResidualLoopOpSize));
770 Align ResidualDstAlign(commonAlignment(PartDstAlign, ResidualLoopOpSize));
771
772 // Copying backwards.
773 {
774 BasicBlock *MainLoopBB = BasicBlock::Create(
775 F->getContext(), "memmove_bwd_main_loop", F, CopyForwardBB);
776
777 // The predecessor of the memmove_bwd_main_loop. Updated in the
778 // following if a residual loop is emitted first.
779 BasicBlock *PredBB = CopyBackwardsBB;
780
781 if (RequiresResidual) {
782 // backwards residual loop
783 BasicBlock *ResidualLoopBB = BasicBlock::Create(
784 F->getContext(), "memmove_bwd_residual_loop", F, MainLoopBB);
785 IRBuilder<> ResidualLoopBuilder(ResidualLoopBB);
786 ResidualLoopBuilder.SetCurrentDebugLocation(DbgLoc);
787 PHINode *ResidualLoopPhi = ResidualLoopBuilder.CreatePHI(ILengthType, 0);
788 Value *ResidualIndex = ResidualLoopBuilder.CreateSub(
789 ResidualLoopPhi, CIResidualLoopOpSize, "bwd_residual_index");
790 // If we used LoopOpType as GEP element type, we would iterate over the
791 // buffers in TypeStoreSize strides while copying TypeAllocSize bytes,
792 // i.e., we would miss bytes if TypeStoreSize != TypeAllocSize. Therefore,
793 // use byte offsets computed from the TypeStoreSize.
794 Value *LoadGEP = ResidualLoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr,
795 ResidualIndex);
796 Value *Element = ResidualLoopBuilder.CreateAlignedLoad(
797 ResidualLoopOpType, LoadGEP, ResidualSrcAlign, SrcIsVolatile,
798 "element");
799 Value *StoreGEP = ResidualLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr,
800 ResidualIndex);
801 ResidualLoopBuilder.CreateAlignedStore(Element, StoreGEP,
802 ResidualDstAlign, DstIsVolatile);
803
804 // After the residual loop, go to an intermediate block.
805 BasicBlock *IntermediateBB = BasicBlock::Create(
806 F->getContext(), "memmove_bwd_middle", F, MainLoopBB);
807 // Later code expects a terminator in the PredBB.
808 IRBuilder<> IntermediateBuilder(IntermediateBB);
809 IntermediateBuilder.SetCurrentDebugLocation(DbgLoc);
810 IntermediateBuilder.CreateUnreachable();
811 ResidualLoopBuilder.CreateCondBr(
812 ResidualLoopBuilder.CreateICmpEQ(ResidualIndex, RuntimeLoopBytes),
813 IntermediateBB, ResidualLoopBB);
814
815 ResidualLoopPhi->addIncoming(ResidualIndex, ResidualLoopBB);
816 ResidualLoopPhi->addIncoming(CopyLen, CopyBackwardsBB);
817
818 // How to get to the residual:
819 CondBrInst *BrInst =
820 CondBrInst::Create(SkipResidualCondition, IntermediateBB,
821 ResidualLoopBB, ThenTerm->getIterator());
822 BrInst->setDebugLoc(DbgLoc);
823 ThenTerm->eraseFromParent();
824
825 PredBB = IntermediateBB;
826 }
827
828 // main loop
829 IRBuilder<> MainLoopBuilder(MainLoopBB);
830 MainLoopBuilder.SetCurrentDebugLocation(DbgLoc);
831 PHINode *MainLoopPhi = MainLoopBuilder.CreatePHI(ILengthType, 0);
832 Value *MainIndex =
833 MainLoopBuilder.CreateSub(MainLoopPhi, CILoopOpSize, "bwd_main_index");
834 Value *LoadGEP =
835 MainLoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr, MainIndex);
836 Value *Element = MainLoopBuilder.CreateAlignedLoad(
837 LoopOpType, LoadGEP, PartSrcAlign, SrcIsVolatile, "element");
838 Value *StoreGEP =
839 MainLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, MainIndex);
840 MainLoopBuilder.CreateAlignedStore(Element, StoreGEP, PartDstAlign,
841 DstIsVolatile);
842 MainLoopBuilder.CreateCondBr(MainLoopBuilder.CreateICmpEQ(MainIndex, Zero),
843 ExitBB, MainLoopBB);
844 MainLoopPhi->addIncoming(MainIndex, MainLoopBB);
845 MainLoopPhi->addIncoming(RuntimeLoopBytes, PredBB);
846
847 // How to get to the main loop:
848 Instruction *PredBBTerm = PredBB->getTerminator();
850 SkipMainCondition, ExitBB, MainLoopBB, PredBBTerm->getIterator());
851 BrInst->setDebugLoc(DbgLoc);
852 PredBBTerm->eraseFromParent();
853 }
854
855 // Copying forward.
856 // main loop
857 {
858 BasicBlock *MainLoopBB =
859 BasicBlock::Create(F->getContext(), "memmove_fwd_main_loop", F, ExitBB);
860 IRBuilder<> MainLoopBuilder(MainLoopBB);
861 MainLoopBuilder.SetCurrentDebugLocation(DbgLoc);
862 PHINode *MainLoopPhi =
863 MainLoopBuilder.CreatePHI(ILengthType, 0, "fwd_main_index");
864 Value *LoadGEP =
865 MainLoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr, MainLoopPhi);
866 Value *Element = MainLoopBuilder.CreateAlignedLoad(
867 LoopOpType, LoadGEP, PartSrcAlign, SrcIsVolatile, "element");
868 Value *StoreGEP =
869 MainLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, MainLoopPhi);
870 MainLoopBuilder.CreateAlignedStore(Element, StoreGEP, PartDstAlign,
871 DstIsVolatile);
872 Value *MainIndex = MainLoopBuilder.CreateAdd(MainLoopPhi, CILoopOpSize);
873 MainLoopPhi->addIncoming(MainIndex, MainLoopBB);
874 MainLoopPhi->addIncoming(Zero, CopyForwardBB);
875
876 Instruction *CopyFwdBBTerm = CopyForwardBB->getTerminator();
877 BasicBlock *SuccessorBB = ExitBB;
878 if (RequiresResidual)
879 SuccessorBB =
880 BasicBlock::Create(F->getContext(), "memmove_fwd_middle", F, ExitBB);
881
882 // leaving or staying in the main loop
883 MainLoopBuilder.CreateCondBr(
884 MainLoopBuilder.CreateICmpEQ(MainIndex, RuntimeLoopBytes), SuccessorBB,
885 MainLoopBB);
886
887 // getting in or skipping the main loop
888 CondBrInst *BrInst =
889 CondBrInst::Create(SkipMainCondition, SuccessorBB, MainLoopBB,
890 CopyFwdBBTerm->getIterator());
891 BrInst->setDebugLoc(DbgLoc);
892 CopyFwdBBTerm->eraseFromParent();
893
894 if (RequiresResidual) {
895 BasicBlock *IntermediateBB = SuccessorBB;
896 IRBuilder<> IntermediateBuilder(IntermediateBB);
897 IntermediateBuilder.SetCurrentDebugLocation(DbgLoc);
898 BasicBlock *ResidualLoopBB = BasicBlock::Create(
899 F->getContext(), "memmove_fwd_residual_loop", F, ExitBB);
900 IntermediateBuilder.CreateCondBr(SkipResidualCondition, ExitBB,
901 ResidualLoopBB);
902
903 // Residual loop
904 IRBuilder<> ResidualLoopBuilder(ResidualLoopBB);
905 ResidualLoopBuilder.SetCurrentDebugLocation(DbgLoc);
906 PHINode *ResidualLoopPhi =
907 ResidualLoopBuilder.CreatePHI(ILengthType, 0, "fwd_residual_index");
908 Value *LoadGEP = ResidualLoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr,
909 ResidualLoopPhi);
910 Value *Element = ResidualLoopBuilder.CreateAlignedLoad(
911 ResidualLoopOpType, LoadGEP, ResidualSrcAlign, SrcIsVolatile,
912 "element");
913 Value *StoreGEP = ResidualLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr,
914 ResidualLoopPhi);
915 ResidualLoopBuilder.CreateAlignedStore(Element, StoreGEP,
916 ResidualDstAlign, DstIsVolatile);
917 Value *ResidualIndex =
918 ResidualLoopBuilder.CreateAdd(ResidualLoopPhi, CIResidualLoopOpSize);
919 ResidualLoopBuilder.CreateCondBr(
920 ResidualLoopBuilder.CreateICmpEQ(ResidualIndex, CopyLen), ExitBB,
921 ResidualLoopBB);
922 ResidualLoopPhi->addIncoming(ResidualIndex, ResidualLoopBB);
923 ResidualLoopPhi->addIncoming(RuntimeLoopBytes, IntermediateBB);
924 }
925 }
926}
927
928// Similar to createMemMoveLoopUnknownSize, only the trip counts are computed at
929// compile time, obsolete loops and branches are omitted, and the residual code
930// is straight-line code instead of a loop.
931static void createMemMoveLoopKnownSize(Instruction *InsertBefore,
932 Value *SrcAddr, Value *DstAddr,
933 ConstantInt *CopyLen, Align SrcAlign,
934 Align DstAlign, bool SrcIsVolatile,
935 bool DstIsVolatile,
936 const TargetTransformInfo &TTI) {
937 // No need to expand zero length moves.
938 if (CopyLen->isZero())
939 return;
940
941 Type *TypeOfCopyLen = CopyLen->getType();
942 BasicBlock *OrigBB = InsertBefore->getParent();
943 Function *F = OrigBB->getParent();
944 const DataLayout &DL = F->getDataLayout();
945 LLVMContext &Ctx = OrigBB->getContext();
946 unsigned SrcAS = cast<PointerType>(SrcAddr->getType())->getAddressSpace();
947 unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
948
949 Type *LoopOpType = TTI.getMemcpyLoopLoweringType(Ctx, CopyLen, SrcAS, DstAS,
950 SrcAlign, DstAlign);
951 TypeSize LoopOpSize = DL.getTypeStoreSize(LoopOpType);
952 assert(LoopOpSize.isFixed() && "LoopOpType cannot be a scalable vector type");
953 Type *Int8Type = Type::getInt8Ty(Ctx);
954
955 // Calculate the loop trip count and remaining bytes to copy after the loop.
956 uint64_t BytesCopiedInLoop =
957 alignDown(CopyLen->getZExtValue(), LoopOpSize.getFixedValue());
958 uint64_t RemainingBytes = CopyLen->getZExtValue() - BytesCopiedInLoop;
959
960 IntegerType *ILengthType = cast<IntegerType>(TypeOfCopyLen);
961 ConstantInt *Zero = ConstantInt::get(ILengthType, 0);
962 ConstantInt *LoopBound = ConstantInt::get(ILengthType, BytesCopiedInLoop);
963 ConstantInt *CILoopOpSize = ConstantInt::get(ILengthType, LoopOpSize);
964
965 const DebugLoc &DbgLoc = InsertBefore->getStableDebugLoc();
966 IRBuilder<> PLBuilder(InsertBefore);
967 PLBuilder.SetCurrentDebugLocation(DbgLoc);
968
969 auto [CmpSrcAddr, CmpDstAddr] =
970 tryInsertCastToCommonAddrSpace(PLBuilder, SrcAddr, DstAddr, TTI);
971 Value *PtrCompare =
972 PLBuilder.CreateICmpULT(CmpSrcAddr, CmpDstAddr, "compare_src_dst");
973 Instruction *ThenTerm, *ElseTerm;
974 SplitBlockAndInsertIfThenElse(PtrCompare, InsertBefore->getIterator(),
975 &ThenTerm, &ElseTerm);
976
977 BasicBlock *CopyBackwardsBB = ThenTerm->getParent();
978 BasicBlock *CopyForwardBB = ElseTerm->getParent();
979 BasicBlock *ExitBB = InsertBefore->getParent();
980 ExitBB->setName("memmove_done");
981
982 Align PartSrcAlign(commonAlignment(SrcAlign, LoopOpSize));
983 Align PartDstAlign(commonAlignment(DstAlign, LoopOpSize));
984
985 // Helper function to generate a load/store pair of a given type in the
986 // residual. Used in the forward and backward branches.
987 auto GenerateResidualLdStPair = [&](Type *OpTy, IRBuilderBase &Builder,
988 uint64_t &BytesCopied) {
989 Align ResSrcAlign(commonAlignment(SrcAlign, BytesCopied));
990 Align ResDstAlign(commonAlignment(DstAlign, BytesCopied));
991
992 TypeSize OperandSize = DL.getTypeStoreSize(OpTy);
993
994 // If we used LoopOpType as GEP element type, we would iterate over the
995 // buffers in TypeStoreSize strides while copying TypeAllocSize bytes, i.e.,
996 // we would miss bytes if TypeStoreSize != TypeAllocSize. Therefore, use
997 // byte offsets computed from the TypeStoreSize.
998 Value *SrcGEP = Builder.CreateInBoundsGEP(
999 Int8Type, SrcAddr, ConstantInt::get(TypeOfCopyLen, BytesCopied));
1000 LoadInst *Load =
1001 Builder.CreateAlignedLoad(OpTy, SrcGEP, ResSrcAlign, SrcIsVolatile);
1002 Value *DstGEP = Builder.CreateInBoundsGEP(
1003 Int8Type, DstAddr, ConstantInt::get(TypeOfCopyLen, BytesCopied));
1004 Builder.CreateAlignedStore(Load, DstGEP, ResDstAlign, DstIsVolatile);
1005 BytesCopied += OperandSize;
1006 };
1007
1008 // Copying backwards.
1009 if (RemainingBytes != 0) {
1010 CopyBackwardsBB->setName("memmove_bwd_residual");
1011 uint64_t BytesCopied = BytesCopiedInLoop;
1012
1013 // Residual code is required to move the remaining bytes. We need the same
1014 // instructions as in the forward case, only in reverse. So we generate code
1015 // the same way, except that we change the IRBuilder insert point for each
1016 // load/store pair so that each one is inserted before the previous one
1017 // instead of after it.
1018 IRBuilder<> BwdResBuilder(CopyBackwardsBB,
1019 CopyBackwardsBB->getFirstNonPHIIt());
1020 BwdResBuilder.SetCurrentDebugLocation(DbgLoc);
1021 SmallVector<Type *, 5> RemainingOps;
1022 TTI.getMemcpyLoopResidualLoweringType(RemainingOps, Ctx, RemainingBytes,
1023 SrcAS, DstAS, PartSrcAlign,
1024 PartDstAlign);
1025 for (auto *OpTy : RemainingOps) {
1026 // reverse the order of the emitted operations
1027 BwdResBuilder.SetInsertPoint(CopyBackwardsBB,
1028 CopyBackwardsBB->getFirstNonPHIIt());
1029 GenerateResidualLdStPair(OpTy, BwdResBuilder, BytesCopied);
1030 }
1031 }
1032 if (BytesCopiedInLoop != 0) {
1033 BasicBlock *LoopBB = CopyBackwardsBB;
1034 BasicBlock *PredBB = OrigBB;
1035 if (RemainingBytes != 0) {
1036 // if we introduce residual code, it needs its separate BB
1037 LoopBB = CopyBackwardsBB->splitBasicBlock(
1038 CopyBackwardsBB->getTerminator(), "memmove_bwd_loop");
1039 PredBB = CopyBackwardsBB;
1040 } else {
1041 CopyBackwardsBB->setName("memmove_bwd_loop");
1042 }
1043 IRBuilder<> LoopBuilder(LoopBB->getTerminator());
1044 LoopBuilder.SetCurrentDebugLocation(DbgLoc);
1045 PHINode *LoopPhi = LoopBuilder.CreatePHI(ILengthType, 0);
1046 Value *Index = LoopBuilder.CreateSub(LoopPhi, CILoopOpSize, "bwd_index");
1047 Value *LoadGEP = LoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr, Index);
1048 Value *Element = LoopBuilder.CreateAlignedLoad(
1049 LoopOpType, LoadGEP, PartSrcAlign, SrcIsVolatile, "element");
1050 Value *StoreGEP = LoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, Index);
1051 LoopBuilder.CreateAlignedStore(Element, StoreGEP, PartDstAlign,
1052 DstIsVolatile);
1053
1054 // Replace the unconditional branch introduced by
1055 // SplitBlockAndInsertIfThenElse to turn LoopBB into a loop.
1056 Instruction *UncondTerm = LoopBB->getTerminator();
1057 LoopBuilder.CreateCondBr(LoopBuilder.CreateICmpEQ(Index, Zero), ExitBB,
1058 LoopBB);
1059 UncondTerm->eraseFromParent();
1060
1061 LoopPhi->addIncoming(Index, LoopBB);
1062 LoopPhi->addIncoming(LoopBound, PredBB);
1063 }
1064
1065 // Copying forward.
1066 BasicBlock *FwdResidualBB = CopyForwardBB;
1067 if (BytesCopiedInLoop != 0) {
1068 CopyForwardBB->setName("memmove_fwd_loop");
1069 BasicBlock *LoopBB = CopyForwardBB;
1070 BasicBlock *SuccBB = ExitBB;
1071 if (RemainingBytes != 0) {
1072 // if we introduce residual code, it needs its separate BB
1073 SuccBB = CopyForwardBB->splitBasicBlock(CopyForwardBB->getTerminator(),
1074 "memmove_fwd_residual");
1075 FwdResidualBB = SuccBB;
1076 }
1077 IRBuilder<> LoopBuilder(LoopBB->getTerminator());
1078 LoopBuilder.SetCurrentDebugLocation(DbgLoc);
1079 PHINode *LoopPhi = LoopBuilder.CreatePHI(ILengthType, 0, "fwd_index");
1080 Value *LoadGEP = LoopBuilder.CreateInBoundsGEP(Int8Type, SrcAddr, LoopPhi);
1081 Value *Element = LoopBuilder.CreateAlignedLoad(
1082 LoopOpType, LoadGEP, PartSrcAlign, SrcIsVolatile, "element");
1083 Value *StoreGEP = LoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, LoopPhi);
1084 LoopBuilder.CreateAlignedStore(Element, StoreGEP, PartDstAlign,
1085 DstIsVolatile);
1086 Value *Index = LoopBuilder.CreateAdd(LoopPhi, CILoopOpSize);
1087 LoopPhi->addIncoming(Index, LoopBB);
1088 LoopPhi->addIncoming(Zero, OrigBB);
1089
1090 // Replace the unconditional branch to turn LoopBB into a loop.
1091 Instruction *UncondTerm = LoopBB->getTerminator();
1092 LoopBuilder.CreateCondBr(LoopBuilder.CreateICmpEQ(Index, LoopBound), SuccBB,
1093 LoopBB);
1094 UncondTerm->eraseFromParent();
1095 }
1096
1097 if (RemainingBytes != 0) {
1098 uint64_t BytesCopied = BytesCopiedInLoop;
1099
1100 // Residual code is required to move the remaining bytes. In the forward
1101 // case, we emit it in the normal order.
1102 IRBuilder<> FwdResBuilder(FwdResidualBB->getTerminator());
1103 FwdResBuilder.SetCurrentDebugLocation(DbgLoc);
1104 SmallVector<Type *, 5> RemainingOps;
1105 TTI.getMemcpyLoopResidualLoweringType(RemainingOps, Ctx, RemainingBytes,
1106 SrcAS, DstAS, PartSrcAlign,
1107 PartDstAlign);
1108 for (auto *OpTy : RemainingOps)
1109 GenerateResidualLdStPair(OpTy, FwdResBuilder, BytesCopied);
1110 }
1111}
1112
1113/// Create a Value of \p DstType that consists of a sequence of copies of
1114/// \p SetValue, using bitcasts and a vector splat.
1116 Value *SetValue, Type *DstType) {
1117 TypeSize DstSize = DL.getTypeStoreSize(DstType);
1118 Type *SetValueType = SetValue->getType();
1119 TypeSize SetValueSize = DL.getTypeStoreSize(SetValueType);
1120 assert(SetValueSize == DL.getTypeAllocSize(SetValueType) &&
1121 "Store size and alloc size of SetValue's type must match");
1122 assert(SetValueSize != 0 && DstSize % SetValueSize == 0 &&
1123 "DstType size must be a multiple of SetValue size");
1124
1125 Value *Result = SetValue;
1126 if (DstSize != SetValueSize) {
1127 if (!SetValueType->isIntegerTy() && !SetValueType->isFloatingPointTy()) {
1128 // If the type cannot be put into a vector, bitcast to iN first.
1129 LLVMContext &Ctx = SetValue->getContext();
1130 Result = B.CreateBitCast(Result, Type::getIntNTy(Ctx, SetValueSize * 8),
1131 "setvalue.toint");
1132 }
1133 // Form a sufficiently large vector consisting of SetValue, repeated.
1134 Result =
1135 B.CreateVectorSplat(DstSize / SetValueSize, Result, "setvalue.splat");
1136 }
1137
1138 // The value has the right size, but we might have to bitcast it to the right
1139 // type.
1140 Result = B.CreateBitCast(Result, DstType, "setvalue.splat.cast");
1141 return Result;
1142}
1143
1144static void
1146 ConstantInt *Len, Value *SetValue, Align DstAlign,
1147 bool IsVolatile, const TargetTransformInfo *TTI,
1148 std::optional<uint64_t> AverageTripCount) {
1149 // No need to expand zero length memsets.
1150 if (Len->isZero())
1151 return;
1152
1153 BasicBlock *PreLoopBB = InsertBefore->getParent();
1154 Function *ParentFunc = PreLoopBB->getParent();
1155 const DataLayout &DL = ParentFunc->getDataLayout();
1156 LLVMContext &Ctx = PreLoopBB->getContext();
1157
1158 unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
1159
1160 Type *TypeOfLen = Len->getType();
1161 Type *Int8Type = Type::getInt8Ty(Ctx);
1162 assert(SetValue->getType() == Int8Type && "Can only set bytes");
1163
1164 Type *LoopOpType = Int8Type;
1165 if (TTI) {
1166 // Use the same memory access type as for a memcpy with the same Dst and Src
1167 // alignment and address space.
1168 LoopOpType = TTI->getMemcpyLoopLoweringType(
1169 Ctx, Len, DstAS, DstAS, DstAlign, DstAlign, std::nullopt);
1170 }
1171 TypeSize LoopOpSize = DL.getTypeStoreSize(LoopOpType);
1172 assert(LoopOpSize.isFixed() && "LoopOpType cannot be a scalable vector type");
1173
1174 uint64_t LoopEndCount =
1175 alignDown(Len->getZExtValue(), LoopOpSize.getFixedValue());
1176
1177 if (LoopEndCount != 0) {
1178 Value *SplatSetValue = nullptr;
1179 {
1180 IRBuilder<> PreLoopBuilder(InsertBefore);
1181 SplatSetValue =
1182 createMemSetSplat(DL, PreLoopBuilder, SetValue, LoopOpType);
1183 }
1184
1185 // Don't generate a residual loop, the remaining bytes are set with
1186 // straight-line code.
1187 LoopExpansionInfo LEI = insertLoopExpansion(
1188 InsertBefore, Len, LoopOpSize, 0, "static-memset", AverageTripCount);
1189 assert(LEI.MainLoopIP && LEI.MainLoopIndex &&
1190 "Main loop should be generated for non-zero loop count");
1191
1192 // Fill MainLoopBB
1193 IRBuilder<> MainLoopBuilder(LEI.MainLoopIP);
1194 Align PartDstAlign(commonAlignment(DstAlign, LoopOpSize));
1195
1196 Value *DstGEP =
1197 MainLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, LEI.MainLoopIndex);
1198
1199 MainLoopBuilder.CreateAlignedStore(SplatSetValue, DstGEP, PartDstAlign,
1200 IsVolatile);
1201
1202 assert(!LEI.ResidualLoopIP && !LEI.ResidualLoopIndex &&
1203 "No residual loop was requested");
1204 }
1205
1206 uint64_t BytesSet = LoopEndCount;
1207 uint64_t RemainingBytes = Len->getZExtValue() - BytesSet;
1208 if (RemainingBytes == 0)
1209 return;
1210
1211 IRBuilder<> RBuilder(InsertBefore);
1212
1213 assert(TTI && "there cannot be a residual loop without TTI");
1214 SmallVector<Type *, 5> RemainingOps;
1215 TTI->getMemcpyLoopResidualLoweringType(RemainingOps, Ctx, RemainingBytes,
1216 DstAS, DstAS, DstAlign, DstAlign,
1217 std::nullopt);
1218
1219 Type *PreviousOpTy = nullptr;
1220 Value *SplatSetValue = nullptr;
1221 for (auto *OpTy : RemainingOps) {
1222 TypeSize OperandSize = DL.getTypeStoreSize(OpTy);
1223 assert(OperandSize.isFixed() &&
1224 "Operand types cannot be scalable vector types");
1225 Align PartDstAlign(commonAlignment(DstAlign, BytesSet));
1226
1227 // Avoid recomputing the splat SetValue if it's the same as for the last
1228 // iteration.
1229 if (OpTy != PreviousOpTy)
1230 SplatSetValue = createMemSetSplat(DL, RBuilder, SetValue, OpTy);
1231
1232 Value *DstGEP = RBuilder.CreateInBoundsGEP(
1233 Int8Type, DstAddr, ConstantInt::get(TypeOfLen, BytesSet));
1234 RBuilder.CreateAlignedStore(SplatSetValue, DstGEP, PartDstAlign,
1235 IsVolatile);
1236 BytesSet += OperandSize;
1237 PreviousOpTy = OpTy;
1238 }
1239 assert(BytesSet == Len->getZExtValue() &&
1240 "Bytes set should match size in the call!");
1241}
1242
1243static void
1245 Value *Len, Value *SetValue, Align DstAlign,
1246 bool IsVolatile, const TargetTransformInfo *TTI,
1247 std::optional<uint64_t> AverageTripCount) {
1248 BasicBlock *PreLoopBB = InsertBefore->getParent();
1249 Function *ParentFunc = PreLoopBB->getParent();
1250 const DataLayout &DL = ParentFunc->getDataLayout();
1251 LLVMContext &Ctx = PreLoopBB->getContext();
1252
1253 unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
1254
1255 Type *Int8Type = Type::getInt8Ty(Ctx);
1256 assert(SetValue->getType() == Int8Type && "Can only set bytes");
1257
1258 Type *LoopOpType = Int8Type;
1259 if (TTI) {
1260 LoopOpType = TTI->getMemcpyLoopLoweringType(
1261 Ctx, Len, DstAS, DstAS, DstAlign, DstAlign, std::nullopt);
1262 }
1263 TypeSize LoopOpSize = DL.getTypeStoreSize(LoopOpType);
1264 assert(LoopOpSize.isFixed() && "LoopOpType cannot be a scalable vector type");
1265
1266 Type *ResidualLoopOpType = Int8Type;
1267 TypeSize ResidualLoopOpSize = DL.getTypeStoreSize(ResidualLoopOpType);
1268
1269 Value *SplatSetValue = SetValue;
1270 {
1271 IRBuilder<> PreLoopBuilder(InsertBefore);
1272 SplatSetValue = createMemSetSplat(DL, PreLoopBuilder, SetValue, LoopOpType);
1273 }
1274
1275 LoopExpansionInfo LEI =
1276 insertLoopExpansion(InsertBefore, Len, LoopOpSize, ResidualLoopOpSize,
1277 "dynamic-memset", AverageTripCount);
1278 assert(LEI.MainLoopIP && LEI.MainLoopIndex &&
1279 "Main loop should be generated for unknown size memset");
1280
1281 // Fill MainLoopBB
1282 IRBuilder<> MainLoopBuilder(LEI.MainLoopIP);
1283 Align PartDstAlign(commonAlignment(DstAlign, LoopOpSize));
1284
1285 Value *DstGEP =
1286 MainLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr, LEI.MainLoopIndex);
1287 MainLoopBuilder.CreateAlignedStore(SplatSetValue, DstGEP, PartDstAlign,
1288 IsVolatile);
1289
1290 // Fill ResidualLoopBB
1291 if (!LEI.ResidualLoopIP)
1292 return;
1293
1294 Align ResDstAlign(commonAlignment(PartDstAlign, ResidualLoopOpSize));
1295
1296 IRBuilder<> ResLoopBuilder(LEI.ResidualLoopIP);
1297
1298 Value *ResDstGEP = ResLoopBuilder.CreateInBoundsGEP(Int8Type, DstAddr,
1299 LEI.ResidualLoopIndex);
1300 ResLoopBuilder.CreateAlignedStore(SetValue, ResDstGEP, ResDstAlign,
1301 IsVolatile);
1302}
1303
1304static void createMemSetPatternLoop(Instruction *InsertBefore, Value *DstAddr,
1305 Value *Len, Value *SetValue, Align DstAlign,
1306 bool IsVolatile,
1307 const TargetTransformInfo *TTI,
1308 std::optional<uint64_t> AverageTripCount) {
1309 // No need to expand zero length memset.pattern.
1310 if (auto *CLen = dyn_cast<ConstantInt>(Len))
1311 if (CLen->isZero())
1312 return;
1313
1314 BasicBlock *PreLoopBB = InsertBefore->getParent();
1315 Function *ParentFunc = PreLoopBB->getParent();
1316 const DataLayout &DL = ParentFunc->getDataLayout();
1317 LLVMContext &Ctx = PreLoopBB->getContext();
1318
1319 unsigned DstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace();
1320
1321 Type *PreferredLoopOpType = SetValue->getType();
1322 if (TTI) {
1323 PreferredLoopOpType = TTI->getMemcpyLoopLoweringType(
1324 Ctx, Len, DstAS, DstAS, DstAlign, DstAlign, std::nullopt);
1325 }
1326 TypeSize PreferredLoopOpStoreSize = DL.getTypeStoreSize(PreferredLoopOpType);
1327 assert(PreferredLoopOpStoreSize.isFixed() &&
1328 "PreferredLoopOpType cannot be a scalable vector type");
1329
1330 TypeSize PreferredLoopOpAllocSize = DL.getTypeAllocSize(PreferredLoopOpType);
1331
1332 Type *OriginalType = SetValue->getType();
1333 TypeSize OriginalTypeStoreSize = DL.getTypeStoreSize(OriginalType);
1334 TypeSize OriginalTypeAllocSize = DL.getTypeAllocSize(OriginalType);
1335
1336 // The semantics of memset.pattern restrict what vectorization we can do: It
1337 // has to behave like a series of stores of the SetValue type at offsets that
1338 // are spaced by the alloc size of the SetValue type. If store and alloc size
1339 // of the SetValue type don't match, the bytes that aren't covered by these
1340 // stores must not be overwritten. We therefore only vectorize memset.pattern
1341 // if the store and alloc sizes of the SetValue are equal and properly divide
1342 // the size of the preferred lowering type (and only if store and alloc size
1343 // for the preferred lowering type are also equal).
1344
1345 unsigned MainLoopStep = 1;
1346 Type *MainLoopType = OriginalType;
1347 TypeSize MainLoopAllocSize = OriginalTypeAllocSize;
1348 unsigned ResidualLoopStep = 0;
1349 Type *ResidualLoopType = nullptr;
1350
1351 if (PreferredLoopOpStoreSize == PreferredLoopOpAllocSize &&
1352 OriginalTypeStoreSize == OriginalTypeAllocSize &&
1353 OriginalTypeStoreSize < PreferredLoopOpStoreSize &&
1354 PreferredLoopOpStoreSize % OriginalTypeStoreSize == 0) {
1355 // Multiple instances of SetValue can be combined to reach the preferred
1356 // loop op size.
1357 MainLoopStep = PreferredLoopOpStoreSize / OriginalTypeStoreSize;
1358 MainLoopType = PreferredLoopOpType;
1359 MainLoopAllocSize = PreferredLoopOpStoreSize;
1360
1361 ResidualLoopStep = 1;
1362 ResidualLoopType = OriginalType;
1363 }
1364
1365 // The step arguments here are in terms of the alloc size of the SetValue, not
1366 // in terms of bytes.
1367 LoopExpansionInfo LEI =
1368 insertLoopExpansion(InsertBefore, Len, MainLoopStep, ResidualLoopStep,
1369 "memset.pattern", AverageTripCount);
1370
1371 Align PartDstAlign(commonAlignment(DstAlign, MainLoopAllocSize));
1372
1373 if (LEI.MainLoopIP) {
1374 // Create the loop-invariant splat value before the loop.
1375 IRBuilder<> PreLoopBuilder(PreLoopBB->getTerminator());
1376 Value *MainLoopSetValue = SetValue;
1377 if (MainLoopType != OriginalType)
1378 MainLoopSetValue =
1379 createMemSetSplat(DL, PreLoopBuilder, SetValue, MainLoopType);
1380
1381 // Fill MainLoopBB
1382 IRBuilder<> MainLoopBuilder(LEI.MainLoopIP);
1383 Value *DstGEP = MainLoopBuilder.CreateInBoundsGEP(MainLoopType, DstAddr,
1384 LEI.MainLoopIndex);
1385 MainLoopBuilder.CreateAlignedStore(MainLoopSetValue, DstGEP, PartDstAlign,
1386 IsVolatile);
1387 }
1388
1389 if (!LEI.ResidualLoopIP)
1390 return;
1391
1392 // Fill ResidualLoopBB
1393 Align ResDstAlign(
1394 commonAlignment(PartDstAlign, DL.getTypeAllocSize(ResidualLoopType)));
1395
1396 IRBuilder<> ResLoopBuilder(LEI.ResidualLoopIP);
1397 Value *ResDstGEP = ResLoopBuilder.CreateInBoundsGEP(ResidualLoopType, DstAddr,
1398 LEI.ResidualLoopIndex);
1399 ResLoopBuilder.CreateAlignedStore(SetValue, ResDstGEP, ResDstAlign,
1400 IsVolatile);
1401}
1402
1403template <typename T>
1405 if (SE) {
1406 const SCEV *SrcSCEV = SE->getSCEV(Memcpy->getRawSource());
1407 const SCEV *DestSCEV = SE->getSCEV(Memcpy->getRawDest());
1408 if (SE->isKnownPredicateAt(CmpInst::ICMP_NE, SrcSCEV, DestSCEV, Memcpy))
1409 return false;
1410 }
1411 return true;
1412}
1413
1415 const TargetTransformInfo &TTI,
1416 ScalarEvolution *SE) {
1417 bool CanOverlap = canOverlap(Memcpy, SE);
1418 auto TripCount = getAverageMemOpLoopTripCount(*Memcpy);
1419 if (ConstantInt *CI = dyn_cast<ConstantInt>(Memcpy->getLength())) {
1421 /*InsertBefore=*/Memcpy,
1422 /*SrcAddr=*/Memcpy->getRawSource(),
1423 /*DstAddr=*/Memcpy->getRawDest(),
1424 /*CopyLen=*/CI,
1425 /*SrcAlign=*/Memcpy->getSourceAlign().valueOrOne(),
1426 /*DstAlign=*/Memcpy->getDestAlign().valueOrOne(),
1427 /*SrcIsVolatile=*/Memcpy->isVolatile(),
1428 /*DstIsVolatile=*/Memcpy->isVolatile(),
1429 /*CanOverlap=*/CanOverlap,
1430 /*TTI=*/TTI,
1431 /*AtomicElementSize=*/std::nullopt,
1432 /*AverageTripCount=*/TripCount);
1433 } else {
1435 /*InsertBefore=*/Memcpy,
1436 /*SrcAddr=*/Memcpy->getRawSource(),
1437 /*DstAddr=*/Memcpy->getRawDest(),
1438 /*CopyLen=*/Memcpy->getLength(),
1439 /*SrcAlign=*/Memcpy->getSourceAlign().valueOrOne(),
1440 /*DstAlign=*/Memcpy->getDestAlign().valueOrOne(),
1441 /*SrcIsVolatile=*/Memcpy->isVolatile(),
1442 /*DstIsVolatile=*/Memcpy->isVolatile(),
1443 /*CanOverlap=*/CanOverlap,
1444 /*TTI=*/TTI,
1445 /*AtomicElementSize=*/std::nullopt,
1446 /*AverageTripCount=*/TripCount);
1447 }
1448}
1449
1451 const TargetTransformInfo &TTI) {
1452 Value *CopyLen = Memmove->getLength();
1453 Value *SrcAddr = Memmove->getRawSource();
1454 Value *DstAddr = Memmove->getRawDest();
1455 Align SrcAlign = Memmove->getSourceAlign().valueOrOne();
1456 Align DstAlign = Memmove->getDestAlign().valueOrOne();
1457 bool SrcIsVolatile = Memmove->isVolatile();
1458 bool DstIsVolatile = SrcIsVolatile;
1459 IRBuilder<> CastBuilder(Memmove);
1460 CastBuilder.SetCurrentDebugLocation(Memmove->getStableDebugLoc());
1461
1462 unsigned SrcAS = SrcAddr->getType()->getPointerAddressSpace();
1463 unsigned DstAS = DstAddr->getType()->getPointerAddressSpace();
1464 if (SrcAS != DstAS) {
1465 if (!TTI.addrspacesMayAlias(SrcAS, DstAS)) {
1466 // We may not be able to emit a pointer comparison, but we don't have
1467 // to. Expand as memcpy.
1468 auto AverageTripCount = getAverageMemOpLoopTripCount(*Memmove);
1469 if (ConstantInt *CI = dyn_cast<ConstantInt>(CopyLen)) {
1471 /*InsertBefore=*/Memmove, SrcAddr, DstAddr, CI, SrcAlign, DstAlign,
1472 SrcIsVolatile, DstIsVolatile,
1473 /*CanOverlap=*/false, TTI, std::nullopt, AverageTripCount);
1474 } else {
1476 /*InsertBefore=*/Memmove, SrcAddr, DstAddr, CopyLen, SrcAlign,
1477 DstAlign, SrcIsVolatile, DstIsVolatile,
1478 /*CanOverlap=*/false, TTI, std::nullopt, AverageTripCount);
1479 }
1480
1481 return true;
1482 }
1483
1484 if (!(TTI.isValidAddrSpaceCast(DstAS, SrcAS) ||
1485 TTI.isValidAddrSpaceCast(SrcAS, DstAS))) {
1486 // We don't know generically if it's legal to introduce an
1487 // addrspacecast. We need to know either if it's legal to insert an
1488 // addrspacecast, or if the address spaces cannot alias.
1489 LLVM_DEBUG(
1490 dbgs() << "Do not know how to expand memmove between different "
1491 "address spaces\n");
1492 return false;
1493 }
1494 }
1495
1496 if (ConstantInt *CI = dyn_cast<ConstantInt>(CopyLen)) {
1498 /*InsertBefore=*/Memmove, SrcAddr, DstAddr, CI, SrcAlign, DstAlign,
1499 SrcIsVolatile, DstIsVolatile, TTI);
1500 } else {
1502 /*InsertBefore=*/Memmove, SrcAddr, DstAddr, CopyLen, SrcAlign, DstAlign,
1503 SrcIsVolatile, DstIsVolatile, TTI);
1504 }
1505 return true;
1506}
1507
1509 const TargetTransformInfo *TTI) {
1510 auto AverageTripCount = getAverageMemOpLoopTripCount(*Memset);
1511 if (ConstantInt *CI = dyn_cast<ConstantInt>(Memset->getLength())) {
1513 /*InsertBefore=*/Memset,
1514 /*DstAddr=*/Memset->getRawDest(),
1515 /*Len=*/CI,
1516 /*SetValue=*/Memset->getValue(),
1517 /*DstAlign=*/Memset->getDestAlign().valueOrOne(),
1518 /*IsVolatile=*/Memset->isVolatile(),
1519 /*TTI=*/TTI,
1520 /*AverageTripCount=*/AverageTripCount);
1521 } else {
1523 /*InsertBefore=*/Memset,
1524 /*DstAddr=*/Memset->getRawDest(),
1525 /*Len=*/Memset->getLength(),
1526 /*SetValue=*/Memset->getValue(),
1527 /*DstAlign=*/Memset->getDestAlign().valueOrOne(),
1528 /*IsVolatile=*/Memset->isVolatile(),
1529 /*TTI=*/TTI,
1530 /*AverageTripCount=*/AverageTripCount);
1531 }
1532}
1533
1535 const TargetTransformInfo &TTI) {
1536 expandMemSetAsLoop(MemSet, &TTI);
1537}
1538
1540 const TargetTransformInfo *TTI) {
1542 /*InsertBefore=*/Memset,
1543 /*DstAddr=*/Memset->getRawDest(),
1544 /*Len=*/Memset->getLength(),
1545 /*SetValue=*/Memset->getValue(),
1546 /*DstAlign=*/Memset->getDestAlign().valueOrOne(),
1547 /*IsVolatile=*/Memset->isVolatile(),
1548 /*TTI=*/TTI,
1549 /*AverageTripCount=*/getAverageMemOpLoopTripCount(*Memset));
1550}
1551
1556
1558 const TargetTransformInfo &TTI,
1559 ScalarEvolution *SE) {
1560 assert(AtomicMemcpy->isAtomic());
1561 if (ConstantInt *CI = dyn_cast<ConstantInt>(AtomicMemcpy->getLength())) {
1563 /*InsertBefore=*/AtomicMemcpy,
1564 /*SrcAddr=*/AtomicMemcpy->getRawSource(),
1565 /*DstAddr=*/AtomicMemcpy->getRawDest(),
1566 /*CopyLen=*/CI,
1567 /*SrcAlign=*/AtomicMemcpy->getSourceAlign().valueOrOne(),
1568 /*DstAlign=*/AtomicMemcpy->getDestAlign().valueOrOne(),
1569 /*SrcIsVolatile=*/AtomicMemcpy->isVolatile(),
1570 /*DstIsVolatile=*/AtomicMemcpy->isVolatile(),
1571 /*CanOverlap=*/false, // SrcAddr & DstAddr may not overlap by spec.
1572 /*TTI=*/TTI,
1573 /*AtomicElementSize=*/AtomicMemcpy->getElementSizeInBytes());
1574 } else {
1576 /*InsertBefore=*/AtomicMemcpy,
1577 /*SrcAddr=*/AtomicMemcpy->getRawSource(),
1578 /*DstAddr=*/AtomicMemcpy->getRawDest(),
1579 /*CopyLen=*/AtomicMemcpy->getLength(),
1580 /*SrcAlign=*/AtomicMemcpy->getSourceAlign().valueOrOne(),
1581 /*DstAlign=*/AtomicMemcpy->getDestAlign().valueOrOne(),
1582 /*SrcIsVolatile=*/AtomicMemcpy->isVolatile(),
1583 /*DstIsVolatile=*/AtomicMemcpy->isVolatile(),
1584 /*CanOverlap=*/false, // SrcAddr & DstAddr may not overlap by spec.
1585 /*TargetTransformInfo=*/TTI,
1586 /*AtomicElementSize=*/AtomicMemcpy->getElementSizeInBytes());
1587 }
1588}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF)
Definition Execution.cpp:41
#define DEBUG_TYPE
static Value * createMemSetSplat(const DataLayout &DL, IRBuilderBase &B, Value *SetValue, Type *DstType)
Create a Value of DstType that consists of a sequence of copies of SetValue, using bitcasts and a vec...
static std::pair< Value *, Value * > tryInsertCastToCommonAddrSpace(IRBuilderBase &B, Value *Addr1, Value *Addr2, const TargetTransformInfo &TTI)
static void createMemSetPatternLoop(Instruction *InsertBefore, Value *DstAddr, Value *Len, Value *SetValue, Align DstAlign, bool IsVolatile, const TargetTransformInfo *TTI, std::optional< uint64_t > AverageTripCount)
static bool canOverlap(MemTransferBase< T > *Memcpy, ScalarEvolution *SE)
static void createMemMoveLoopKnownSize(Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr, ConstantInt *CopyLen, Align SrcAlign, Align DstAlign, bool SrcIsVolatile, bool DstIsVolatile, const TargetTransformInfo &TTI)
static void createMemSetLoopUnknownSize(Instruction *InsertBefore, Value *DstAddr, Value *Len, Value *SetValue, Align DstAlign, bool IsVolatile, const TargetTransformInfo *TTI, std::optional< uint64_t > AverageTripCount)
static Value * getRuntimeLoopRemainder(IRBuilderBase &B, Value *Len, Value *OpSize, unsigned OpSizeVal)
static void createMemSetLoopKnownSize(Instruction *InsertBefore, Value *DstAddr, ConstantInt *Len, Value *SetValue, Align DstAlign, bool IsVolatile, const TargetTransformInfo *TTI, std::optional< uint64_t > AverageTripCount)
static Value * getRuntimeLoopUnits(IRBuilderBase &B, Value *Len, Value *OpSize, unsigned OpSizeVal, Value *RTLoopRemainder=nullptr)
static LoopExpansionInfo insertLoopExpansion(Instruction *InsertBefore, Value *Len, unsigned MainLoopStep, unsigned ResidualLoopStep, StringRef BBNamePrefix, std::optional< uint64_t > ExpectedUnits)
Insert the control flow and loop counters for a memcpy/memset loop expansion.
static void createMemMoveLoopUnknownSize(Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr, Value *CopyLen, Align SrcAlign, Align DstAlign, bool SrcIsVolatile, bool DstIsVolatile, const TargetTransformInfo &TTI)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
This file contains the declarations for profiling metadata utility functions.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
This class represents any memcpy intrinsic i.e.
uint32_t getElementSizeInBytes() const
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
@ ICMP_NE
not equal
Definition InstrTypes.h:762
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
This is the shared class of boolean and integer constants.
Definition Constants.h:87
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition Constants.h:219
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:360
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2406
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1942
CondBrInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Definition IRBuilder.h:1224
UnreachableInst * CreateUnreachable()
Definition IRBuilder.h:1366
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
Definition IRBuilder.h:221
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Definition IRBuilder.h:2027
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2394
UncondBrInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
Definition IRBuilder.h:1218
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2555
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2390
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1447
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1430
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:181
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1961
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2908
LLVM_ABI const DebugLoc & getStableDebugLoc() const
Fetch the debug location for this node, unless this is a debug intrinsic, in which case fetch the deb...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
An instruction for reading from memory.
void setAtomic(AtomicOrdering Ordering, SyncScope::ID SSID=SyncScope::System)
Sets the ordering constraint and the synchronization scope ID of this load instruction.
MDNode * createAnonymousAliasScope(MDNode *Domain, StringRef Name=StringRef())
Return metadata appropriate for an alias scope root node.
Definition MDBuilder.h:195
LLVM_ABI MDNode * createLikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards true destination.
Definition MDBuilder.cpp:43
MDNode * createAnonymousAliasScopeDomain(StringRef Name=StringRef())
Return metadata appropriate for an alias scope domain node.
Definition MDBuilder.h:188
Metadata node.
Definition Metadata.h:1069
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1567
This class wraps the llvm.memcpy intrinsic.
Value * getLength() const
Value * getRawDest() const
MaybeAlign getDestAlign() const
This is the common base class for memset/memcpy/memmove.
bool isVolatile() const
This class wraps the llvm.memmove intrinsic.
Value * getValue() const
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
This class wraps the llvm.experimental.memset.pattern intrinsic.
Common base class for all memory transfer intrinsics.
Value * getRawSource() const
Return the arguments to the instruction.
MaybeAlign getSourceAlign() const
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI bool isKnownPredicateAt(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
void setAtomic(AtomicOrdering Ordering, SyncScope::ID SSID=SyncScope::System)
Sets the ordering constraint and the synchronization scope ID of this store instruction.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:394
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:171
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void createMemCpyLoopKnownSize(Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr, ConstantInt *CopyLen, Align SrcAlign, Align DestAlign, bool SrcIsVolatile, bool DstIsVolatile, bool CanOverlap, const TargetTransformInfo &TTI, std::optional< uint32_t > AtomicCpySize=std::nullopt, std::optional< uint64_t > AverageTripCount=std::nullopt)
Emit a loop implementing the semantics of an llvm.memcpy whose size is a compile time constant.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI bool expandMemMoveAsLoop(MemMoveInst *MemMove, const TargetTransformInfo &TTI)
Expand MemMove as a loop.
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:541
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)
Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...
TargetTransformInfo TTI
LLVM_ABI void expandAtomicMemCpyAsLoop(AnyMemCpyInst *AtomicMemCpy, const TargetTransformInfo &TTI, ScalarEvolution *SE)
Expand AtomicMemCpy as a loop. AtomicMemCpy is not deleted.
LLVM_ABI void expandMemSetAsLoop(MemSetInst *MemSet, const TargetTransformInfo *TTI=nullptr)
Expand MemSet as a loop.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI void expandMemSetPatternAsLoop(MemSetPatternInst *MemSet, const TargetTransformInfo *TTI=nullptr)
Expand MemSetPattern as a loop.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
LLVM_ABI void expandMemCpyAsLoop(MemCpyInst *MemCpy, const TargetTransformInfo &TTI, ScalarEvolution *SE=nullptr)
Expand MemCpy as a loop. MemCpy is not deleted.
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
LLVM_ABI void createMemCpyLoopUnknownSize(Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr, Value *CopyLen, Align SrcAlign, Align DestAlign, bool SrcIsVolatile, bool DstIsVolatile, bool CanOverlap, const TargetTransformInfo &TTI, std::optional< unsigned > AtomicSize=std::nullopt, std::optional< uint64_t > AverageTripCount=std::nullopt)
Emit a loop implementing the semantics of llvm.memcpy where the size is not a compile-time constant.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:130