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