LLVM 24.0.0git
PreISelIntrinsicLowering.cpp
Go to the documentation of this file.
1//===- PreISelIntrinsicLowering.cpp - Pre-ISel intrinsic lowering pass ----===//
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//
9// This pass implements IR lowering for the llvm.memcpy, llvm.memmove,
10// llvm.memset, llvm.load.relative and llvm.objc.* intrinsics.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/STLExtras.h"
24#include "llvm/CodeGen/Passes.h"
29#include "llvm/IR/Function.h"
30#include "llvm/IR/GlobalValue.h"
31#include "llvm/IR/IRBuilder.h"
34#include "llvm/IR/Metadata.h"
35#include "llvm/IR/Module.h"
38#include "llvm/IR/Type.h"
39#include "llvm/IR/Use.h"
41#include "llvm/Pass.h"
48
49using namespace llvm;
50
51#define DEBUG_TYPE "pre-isel-intrinsic-lowering"
52
53/// Threshold to leave statically sized memory intrinsic calls. Calls of known
54/// size larger than this will be expanded by the pass. Calls of unknown or
55/// lower size will be left for expansion in codegen.
57 "mem-intrinsic-expand-size",
58 cl::desc("Set minimum mem intrinsic size to expand in IR"), cl::init(-1),
60
61/// Maximum bound of a memset with non-constant length for it to be expanded
62/// inline. Overrides TargetTransformInfo::getMaxBoundedMemSetInlineSize.
64 "bounded-memset-inline-size",
65 cl::desc("Set maximum bound of a variable-length memset to expand inline"),
67
68namespace {
69
70struct PreISelIntrinsicLowering {
71 const TargetMachine &TM;
72 const ModuleLibcallLoweringInfo &ModuleLibcalls;
73 const function_ref<TargetTransformInfo &(Function &)> LookupTTI;
74 const function_ref<TargetLibraryInfo &(Function &)> LookupTLI;
75 const function_ref<AssumptionCache &(Function &)> LookupAC;
76
77 /// If this is true, assume it's preferably to leave memory intrinsic calls
78 /// for replacement with a library call later. Otherwise this depends on
79 /// TargetLoweringInfo availability of the corresponding function.
80 const bool UseMemIntrinsicLibFunc;
81
82 explicit PreISelIntrinsicLowering(
83 const TargetMachine &TM_,
84 const ModuleLibcallLoweringInfo &ModuleLibcalls_,
88 bool UseMemIntrinsicLibFunc_ = true)
89 : TM(TM_), ModuleLibcalls(ModuleLibcalls_), LookupTTI(LookupTTI_),
90 LookupTLI(LookupTLI_), LookupAC(LookupAC_),
91 UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) {}
92
93 static bool shouldExpandMemIntrinsicWithSize(Value *Size,
94 const TargetTransformInfo &TTI);
95 bool tryExpandBoundedMemSet(MemSetInst *Memset,
96 const TargetTransformInfo &TTI) const;
97 bool
98 expandMemIntrinsicUses(Function &F,
99 DenseMap<Constant *, GlobalVariable *> &CMap) const;
100 bool lowerIntrinsics(Module &M) const;
101};
102
103} // namespace
104
105template <class T> static bool forEachCall(Function &Intrin, T Callback) {
106 // Lowering all intrinsics in a function will delete multiple uses, so we
107 // can't use an early-inc-range. In case some remain, we don't want to look
108 // at them again. Unfortunately, Value::UseList is private, so we can't use a
109 // simple Use**. If LastUse is null, the next use to consider is
110 // Intrin.use_begin(), otherwise it's LastUse->getNext().
111 Use *LastUse = nullptr;
112 bool Changed = false;
113 while (!Intrin.use_empty() && (!LastUse || LastUse->getNext())) {
114 Use *U = LastUse ? LastUse->getNext() : &*Intrin.use_begin();
115 bool Removed = false;
116 // An intrinsic cannot have its address taken, so it cannot be an argument
117 // operand. It might be used as operand in debug metadata, though.
118 if (auto CI = dyn_cast<CallInst>(U->getUser()))
119 Changed |= Removed = Callback(CI);
120 if (!Removed)
121 LastUse = U;
122 }
123 return Changed;
124}
125
127 if (F.use_empty())
128 return false;
129
130 bool Changed = false;
131 Type *Int32Ty = Type::getInt32Ty(F.getContext());
132
133 for (Use &U : llvm::make_early_inc_range(F.uses())) {
134 auto CI = dyn_cast<CallInst>(U.getUser());
135 if (!CI || CI->getCalledOperand() != &F)
136 continue;
137
138 IRBuilder<> B(CI);
139 Value *Ptr = CI->getArgOperand(0);
140 Value *OffsetPtr = B.CreatePtrAddWithSExtOrTrunc(Ptr, CI->getArgOperand(1));
141 Value *OffsetI32 = B.CreateAlignedLoad(Int32Ty, OffsetPtr, Align(4));
142
143 Value *ResultPtr = B.CreatePtrAddWithSExtOrTrunc(Ptr, OffsetI32);
144
145 CI->replaceAllUsesWith(ResultPtr);
146 CI->eraseFromParent();
147 Changed = true;
148 }
149
150 return Changed;
151}
152
153/// Lower @llvm.can.load.speculatively using target-specific expansion.
154/// Targets may provide their own expansion via
155/// TargetLowering::emitCanLoadSpeculatively; the default expansion
156/// conservatively returns false.
158 return forEachCall(F, [&](CallInst *CI) {
159 const TargetLowering *TLI =
161
162 IRBuilder<> Builder(CI);
163 // A null result means the target cannot answer; lower to false.
164 Value *Result = TLI->emitCanLoadSpeculatively(Builder, CI->getArgOperand(0),
165 CI->getArgOperand(1));
166 if (!Result)
167 Result = Builder.getFalse();
168
169 CI->replaceAllUsesWith(Result);
170 CI->eraseFromParent();
171 return true;
172 });
173}
174
175// ObjCARC has knowledge about whether an obj-c runtime function needs to be
176// always tail-called or never tail-called.
185
186static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn,
187 bool setNonLazyBind = false) {
189 "Pre-ISel intrinsics do lower into regular function calls");
190 if (F.use_empty())
191 return false;
192
193 // FIXME: When RuntimeLibcalls is an analysis, check if the function is really
194 // supported, and go through RTLIB::Libcall.
196
197 // If we haven't already looked up this function, check to see if the
198 // program already contains a function with this name.
199 Module *M = F.getParent();
200 FunctionCallee FCache =
201 M->getOrInsertFunction(NewFnName, F.getFunctionType());
202
203 if (Function *Fn = dyn_cast<Function>(FCache.getCallee())) {
204 Fn->setLinkage(F.getLinkage());
205 if (setNonLazyBind && !Fn->isWeakForLinker()) {
206 // If we have Native ARC, set nonlazybind attribute for these APIs for
207 // performance.
208 Fn->addFnAttr(Attribute::NonLazyBind);
209 }
210 }
211
213
214 for (Use &U : llvm::make_early_inc_range(F.uses())) {
215 auto *CB = cast<CallBase>(U.getUser());
216
217 if (CB->getCalledFunction() != &F) {
219 "use expected to be the argument of operand bundle "
220 "\"clang.arc.attachedcall\"");
221 U.set(FCache.getCallee());
222 continue;
223 }
224
225 auto *CI = cast<CallInst>(CB);
226 assert(CI->getCalledFunction() && "Cannot lower an indirect call!");
227
228 IRBuilder<> Builder(CI->getIterator());
229 SmallVector<Value *, 8> Args(CI->args());
231 CI->getOperandBundlesAsDefs(BundleList);
232 CallInst *NewCI = Builder.CreateCall(FCache, Args, BundleList);
233 NewCI->setName(CI->getName());
234
235 // Try to set the most appropriate TailCallKind based on both the current
236 // attributes and the ones that we could get from ObjCARC's special
237 // knowledge of the runtime functions.
238 //
239 // std::max respects both requirements of notail and tail here:
240 // * notail on either the call or from ObjCARC becomes notail
241 // * tail on either side is stronger than none, but not notail
242 CallInst::TailCallKind TCK = CI->getTailCallKind();
243 NewCI->setTailCallKind(std::max(TCK, OverridingTCK));
244
245 // Transfer the 'returned' attribute from the intrinsic to the call site.
246 // By applying this only to intrinsic call sites, we avoid applying it to
247 // non-ARC explicit calls to things like objc_retain which have not been
248 // auto-upgraded to use the intrinsics.
249 unsigned Index;
250 if (F.getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) &&
251 Index)
252 NewCI->addParamAttr(Index - AttributeList::FirstArgIndex,
253 Attribute::Returned);
254
255 if (!CI->use_empty())
256 CI->replaceAllUsesWith(NewCI);
257 CI->eraseFromParent();
258 }
259
260 return true;
261}
262
263// TODO: Should refine based on estimated number of accesses (e.g. does it
264// require splitting based on alignment)
265bool PreISelIntrinsicLowering::shouldExpandMemIntrinsicWithSize(
267 ConstantInt *CI = dyn_cast<ConstantInt>(Size);
268 if (!CI)
269 return true;
270 uint64_t Threshold = MemIntrinsicExpandSizeThresholdOpt.getNumOccurrences()
273 uint64_t SizeVal = CI->getZExtValue();
274
275 // Treat a threshold of 0 as a special case to force expansion of all
276 // intrinsics, including size 0.
277 return SizeVal > Threshold || Threshold == 0;
278}
279
280static bool canEmitLibcall(const ModuleLibcallLoweringInfo &ModuleLowering,
281 const TargetMachine &TM, Function *F,
282 RTLIB::Libcall LC) {
283 // TODO: Should this consider the address space of the memcpy?
285 getLibcallLowering(ModuleLowering, *TM.getSubtargetImpl(*F));
286 return Lowering.getLibcallImpl(LC) != RTLIB::Unsupported;
287}
288
289static bool canEmitMemcpy(const ModuleLibcallLoweringInfo &ModuleLowering,
290 const TargetMachine &TM, Function *F) {
291 // TODO: Should this consider the address space of the memcpy?
293 getLibcallLowering(ModuleLowering, *TM.getSubtargetImpl(*F));
294 return Lowering.getMemcpyImpl() != RTLIB::Unsupported;
295}
296
297// Expand a memset whose length is not constant but is known to be small, which
298// is faster than calling the library.
299bool PreISelIntrinsicLowering::tryExpandBoundedMemSet(
300 MemSetInst *Memset, const TargetTransformInfo &TTI) const {
301 // This pass runs even at -O0, so skip if e.g. llc -O0 is used.
302 if (TM.getOptLevel() == CodeGenOptLevel::None)
303 return false;
304
305 Value *Len = Memset->getLength();
306 Function *F = Memset->getFunction();
307 if (isa<Constant>(Len) || Memset->isVolatile() || F->hasOptNone() ||
308 F->hasMinSize())
309 return false;
310 uint64_t Threshold = BoundedMemSetInlineSizeOpt.getNumOccurrences()
313 if (!Threshold)
314 return false;
315
316 // Bounds from (1) assumptions, e.g. __builtin_assume(len <= 32)
317 // and (2) known bits and ranges on instructions themselves, and...
318 SimplifyQuery SQ(Memset->getDataLayout(), Memset);
319 SQ.AC = &LookupAC(*F);
320 KnownBits Known = computeKnownBits(Len, SQ);
322 {Len, Known}, /*ForSigned=*/false, SQ);
323
324 // ... (3) range attr on the memset.
325 Attribute RangeAttr = Memset->getParamAttr(
326 Memset->getLengthUse().getOperandNo(), Attribute::Range);
327 if (RangeAttr.isValid())
328 CR = CR.intersectWith(RangeAttr.getRange());
329
330 if (CR.isEmptySet() || CR.getUnsignedMax().ugt(Threshold))
331 return false;
332
335 return true;
336}
337
338// Return a value appropriate for use with the memset_pattern16 libcall, if
339// possible and if we know how. (Adapted from equivalent helper in
340// LoopIdiomRecognize).
341static Constant *
343 const RTLIB::RuntimeLibcallsInfo &RTLCI) {
344 // TODO: This could check for UndefValue because it can be merged into any
345 // other valid pattern.
346
347 // Don't emit libcalls if a non-default address space is being used.
348 if (Inst->getRawDest()->getType()->getPointerAddressSpace() != 0)
349 return nullptr;
350
351 Value *V = Inst->getValue();
352 Type *VTy = V->getType();
353 const DataLayout &DL = Inst->getDataLayout();
354
355 if (!RTLCI.isAvailable(RTLIB::impl_memset_pattern16))
356 return nullptr;
357
358 // If the value isn't a constant, we can't promote it to being in a constant
359 // array. We could theoretically do a store to an alloca or something, but
360 // that doesn't seem worthwhile.
362 if (!C || isa<ConstantExpr>(C))
363 return nullptr;
364
365 // Only handle simple values that are a power of two bytes in size.
366 uint64_t Size = DL.getTypeSizeInBits(VTy);
367 if (!DL.typeSizeEqualsStoreSize(VTy) || !isPowerOf2_64(Size))
368 return nullptr;
369
370 // Don't care enough about darwin/ppc to implement this.
371 if (DL.isBigEndian())
372 return nullptr;
373
374 // Convert to size in bytes.
375 Size /= 8;
376
377 // TODO: If CI is larger than 16-bytes, we can try slicing it in half to see
378 // if the top and bottom are the same (e.g. for vectors and large integers).
379 if (Size > 16)
380 return nullptr;
381
382 // If the constant is exactly 16 bytes, just use it.
383 if (Size == 16)
384 return C;
385
386 // Otherwise, we'll use an array of the constants.
387 uint64_t ArraySize = 16 / Size;
388 ArrayType *AT = ArrayType::get(V->getType(), ArraySize);
389 return ConstantArray::get(AT, std::vector<Constant *>(ArraySize, C));
390}
391
392// TODO: Handle atomic memcpy and memcpy.inline
393// TODO: Pass ScalarEvolution
394bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
395 Function &F, DenseMap<Constant *, GlobalVariable *> &CMap) const {
396 Intrinsic::ID ID = F.getIntrinsicID();
397 bool Changed = false;
398
399 for (User *U : llvm::make_early_inc_range(F.users())) {
401
402 switch (ID) {
403 case Intrinsic::memcpy: {
404 auto *Memcpy = cast<MemCpyInst>(Inst);
405 Function *ParentFunc = Memcpy->getFunction();
406 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
407 if (shouldExpandMemIntrinsicWithSize(Memcpy->getLength(), TTI)) {
408 if (UseMemIntrinsicLibFunc &&
409 canEmitMemcpy(ModuleLibcalls, TM, ParentFunc))
410 break;
411
412 // TODO: For optsize, emit the loop into a separate function
413 expandMemCpyAsLoop(Memcpy, TTI);
414 Changed = true;
415 Memcpy->eraseFromParent();
416 }
417
418 break;
419 }
420 case Intrinsic::memcpy_inline: {
421 // Only expand llvm.memcpy.inline with non-constant length in this
422 // codepath, leaving the current SelectionDAG expansion for constant
423 // length memcpy intrinsics undisturbed.
424 auto *Memcpy = cast<MemCpyInst>(Inst);
425 if (isa<ConstantInt>(Memcpy->getLength()))
426 break;
427
428 Function *ParentFunc = Memcpy->getFunction();
429 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
430 expandMemCpyAsLoop(Memcpy, TTI);
431 Changed = true;
432 Memcpy->eraseFromParent();
433 break;
434 }
435 case Intrinsic::memmove: {
436 auto *Memmove = cast<MemMoveInst>(Inst);
437 Function *ParentFunc = Memmove->getFunction();
438 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
439 if (shouldExpandMemIntrinsicWithSize(Memmove->getLength(), TTI)) {
440 if (UseMemIntrinsicLibFunc &&
441 canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMMOVE))
442 break;
443
444 if (expandMemMoveAsLoop(Memmove, TTI)) {
445 Changed = true;
446 Memmove->eraseFromParent();
447 }
448 }
449
450 break;
451 }
452 case Intrinsic::memset: {
453 auto *Memset = cast<MemSetInst>(Inst);
454 Function *ParentFunc = Memset->getFunction();
455 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
456 if (tryExpandBoundedMemSet(Memset, TTI)) {
457 Changed = true;
458 Memset->eraseFromParent();
459 break;
460 }
461 if (shouldExpandMemIntrinsicWithSize(Memset->getLength(), TTI)) {
462 if (UseMemIntrinsicLibFunc &&
463 canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMSET))
464 break;
465
466 expandMemSetAsLoop(Memset, TTI);
467 Changed = true;
468 Memset->eraseFromParent();
469 }
470
471 break;
472 }
473 case Intrinsic::memset_inline: {
474 // Only expand llvm.memset.inline with non-constant length in this
475 // codepath, leaving the current SelectionDAG expansion for constant
476 // length memset intrinsics undisturbed.
477 auto *Memset = cast<MemSetInst>(Inst);
478 if (isa<ConstantInt>(Memset->getLength()))
479 break;
480
481 Function *ParentFunc = Memset->getFunction();
482 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
483 expandMemSetAsLoop(Memset, TTI);
484 Changed = true;
485 Memset->eraseFromParent();
486 break;
487 }
488 case Intrinsic::experimental_memset_pattern: {
489 auto *Memset = cast<MemSetPatternInst>(Inst);
490 Function *ParentFunc = Memset->getFunction();
491 const RTLIB::RuntimeLibcallsInfo &RTLCI =
492 ModuleLibcalls.getRuntimeLibcallsInfo();
493 Constant *PatternValue = getMemSetPattern16Value(Memset, RTLCI);
494 if (!PatternValue) {
495 // If it isn't possible to emit a memset_pattern16 libcall, expand to
496 // a loop instead.
497 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
499 Changed = true;
500 Memset->eraseFromParent();
501 break;
502 }
503 // FIXME: There is currently no profitability calculation for emitting
504 // the libcall vs expanding the memset.pattern directly.
505 IRBuilder<> Builder(Inst);
506 Module *M = Memset->getModule();
507 const DataLayout &DL = Memset->getDataLayout();
508
509 FunctionCallee MSP =
510 RTLCI.getOrInsertLibcallDecl(*M, RTLIB::impl_memset_pattern16);
511 Type *SizeTTy = MSP.getFunctionType()->getParamType(2);
512
513 // Otherwise we should form a memset_pattern16. PatternValue is known
514 // to be an constant array of 16-bytes. Put the value into a mergable
515 // global.
516 assert(Memset->getRawDest()->getType()->getPointerAddressSpace() == 0 &&
517 "Should have skipped if non-zero AS");
518 GlobalVariable *GV;
519 auto It = CMap.find(PatternValue);
520 if (It != CMap.end()) {
521 GV = It->second;
522 } else {
523 GV = new GlobalVariable(
524 *M, PatternValue->getType(), /*isConstant=*/true,
525 GlobalValue::PrivateLinkage, PatternValue, ".memset_pattern");
526 GV->setUnnamedAddr(
527 GlobalValue::UnnamedAddr::Global); // Ok to merge these.
528 // TODO: Consider relaxing alignment requirement.
529 GV->setAlignment(Align(16));
530 CMap[PatternValue] = GV;
531 }
532 Value *PatternPtr = GV;
533 Value *NumBytes = Builder.CreateMul(
534 ConstantInt::get(SizeTTy,
535 DL.getTypeAllocSize(Memset->getValue()->getType())),
536 Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy));
537 CallInst *MemsetPattern16Call =
538 Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes});
539 MemsetPattern16Call->setCallingConv(
540 RTLCI.getLibcallImplCallingConv(RTLIB::impl_memset_pattern16));
541 MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());
542 // Preserve any call site attributes on the destination pointer
543 // argument (e.g. alignment).
544 AttrBuilder ArgAttrs(Memset->getContext(),
545 Memset->getAttributes().getParamAttrs(0));
546 MemsetPattern16Call->setAttributes(
547 MemsetPattern16Call->getAttributes().addParamAttributes(
548 Memset->getContext(), 0, ArgAttrs));
549 Changed = true;
550 Memset->eraseFromParent();
551 break;
552 }
553 default:
554 llvm_unreachable("unhandled intrinsic");
555 }
556 }
557
558 return Changed;
559}
560
562 if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deactivation_symbol))
563 return cast<GlobalValue>(Bundle->Inputs[0]);
564 return nullptr;
565}
566
568 Module &M = *Intr.getParent();
569 if (Triple(M.getTargetTriple()).isArm64e())
570 return false;
571
572 Type *Int64Ty = Type::getInt64Ty(M.getContext());
573
574 assert(Intr.getIntrinsicID() == Intrinsic::ptrauth_sign ||
575 Intr.getIntrinsicID() == Intrinsic::ptrauth_auth);
576 auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
577 FunctionCallee EmuIntr = M.getOrInsertFunction(
578 Intr.getIntrinsicID() == Intrinsic::ptrauth_auth ? "__emupac_autda"
579 : "__emupac_pacda",
580 EmuFnTy);
581
582 for (User *U : llvm::make_early_inc_range(Intr.users())) {
583 auto *Call = cast<CallInst>(U);
584 // We only support the DA key for now.
585 if (auto *Key = dyn_cast<ConstantInt>(Call->getArgOperand(1));
586 !Key || Key->getZExtValue() != /*AArch64PACKey::DA*/ 2)
587 continue;
588
589 Function *F = Call->getParent()->getParent();
590 Attribute FSAttr = F->getFnAttribute("target-features");
591 if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
592 continue;
593
594 std::vector<OperandBundleDef> DSBundle;
595 if (auto *DS = getDeactivationSymbol(Call))
596 DSBundle.push_back(OperandBundleDef("deactivation-symbol", DS));
597
599 auto *EmuCall = B.CreateCall(
600 EmuIntr, {Call->getArgOperand(0), Call->getArgOperand(2)}, DSBundle);
601 Call->replaceAllUsesWith(EmuCall);
602 Call->eraseFromParent();
603 }
604 return true;
605}
606
608 Module &M = *Intr.getParent();
609
610 SmallPtrSet<GlobalValue *, 2> DSsToDeactivate;
611
612 Type *Int8Ty = Type::getInt8Ty(M.getContext());
613 Type *Int64Ty = Type::getInt64Ty(M.getContext());
614 PointerType *PtrTy = PointerType::get(M.getContext(), 0);
615
616 for (User *U : llvm::make_early_inc_range(Intr.users())) {
617 auto *Call = cast<CallInst>(U);
618
619 auto *Pointer = Call->getArgOperand(0);
620 bool UseHWEncoding =
621 cast<ConstantInt>(Call->getArgOperand(2))->getZExtValue();
622 if (!UseHWEncoding)
623 reportFatalUsageError("software encoding currently unsupported");
624
625 auto *DS = getDeactivationSymbol(Call);
626
627 for (Use &U : llvm::make_early_inc_range(Call->uses())) {
628 // Comparisons against null cannot be used to recover the original
629 // pointer so we replace them with comparisons against the original
630 // pointer.
631 if (auto *CI = dyn_cast<ICmpInst>(U.getUser())) {
632 if (auto *Op = dyn_cast<Constant>(CI->getOperand(0))) {
633 if (Op->isNullValue()) {
634 CI->setOperand(1, Pointer);
635 continue;
636 }
637 }
638 if (auto *Op = dyn_cast<Constant>(CI->getOperand(1))) {
639 if (Op->isNullValue()) {
640 CI->setOperand(0, Pointer);
641 continue;
642 }
643 }
644 }
645
646 // If we are here, this means that we couldn't rewrite away this use of
647 // the intrinsic. Any load or store uses were removed by InstCombine, and
648 // in general, we can't rewrite away non-load/store uses of
649 // llvm.protected.field.ptr because doing so could expose the encoded
650 // pointer value to the program. Replace it with the pointer operand, and
651 // arrange to define a deactivation symbol.
652 U.set(Pointer);
653 if (DS)
654 DSsToDeactivate.insert(DS);
655 }
656
657 Call->eraseFromParent();
658 }
659
660 if (!DSsToDeactivate.empty()) {
661 // This is an AArch64 NOP instruction. When the deactivation symbol support
662 // is expanded to more architectures, there will likely need to be an API
663 // for retrieving this constant.
664 Constant *Nop =
665 ConstantExpr::getIntToPtr(ConstantInt::get(Int64Ty, 0xd503201f), PtrTy);
666 for (GlobalValue *OldDS : DSsToDeactivate) {
668 Int8Ty, 0, GlobalValue::ExternalLinkage, OldDS->getName(), Nop, &M);
669 DS->setVisibility(GlobalValue::HiddenVisibility);
670 DS->takeName(OldDS);
671 OldDS->replaceAllUsesWith(DS);
672 OldDS->eraseFromParent();
673 }
674 }
675 return true;
676}
677
678static bool expandCondLoop(Function &Intr) {
679 for (User *U : llvm::make_early_inc_range(Intr.users())) {
680 auto *Call = cast<CallInst>(U);
681
682 auto *Br = cast<UncondBrInst>(
683 SplitBlockAndInsertIfThen(Call->getArgOperand(0), Call, false,
685 *Call->getFunction(), DEBUG_TYPE)));
686 Br->setSuccessor(Br->getParent());
687 Call->eraseFromParent();
688 }
689 return true;
690}
691
692static bool expandLoopTrap(Function &Intr) {
693 for (User *U : make_early_inc_range(Intr.users())) {
694 auto *Call = cast<CallInst>(U);
695 if (!Call->getParent()->isEntryBlock() &&
696 std::all_of(Call->getParent()->begin(), BasicBlock::iterator(Call),
697 [](Instruction &I) { return !I.mayHaveSideEffects(); })) {
698 for (auto *BB : predecessors(Call->getParent())) {
699 auto *BI = dyn_cast<CondBrInst>(BB->getTerminator());
700 if (!BI)
701 continue;
702 IRBuilder<> B(BI);
703 Value *Cond;
704 // The looptrap can either be on the true branch or the false branch.
705 // We insert the cond loop before the branch, which uses the branch's
706 // original condition for going to the looptrap as its condition, and
707 // force the branch to take whichever path does not lead to the
708 // looptrap, as the original path to the looptrap is now unreachable
709 // thanks to the cond loop. The codegenprepare pass will clean up our
710 // "unconditional conditional branch" by combining the two basic blocks
711 // if possible, or replacing it with an unconditional branch.
712 if (BI->getSuccessor(0) == Call->getParent()) {
713 // The looptrap is on the true branch.
714 Cond = BI->getCondition();
715 BI->setCondition(ConstantInt::getFalse(BI->getContext()));
716 } else {
717 // The looptrap is on the false branch, which means that we need to
718 // invert the condition.
719 Cond = B.CreateNot(BI->getCondition());
720 BI->setCondition(ConstantInt::getTrue(BI->getContext()));
721 }
722 B.CreateIntrinsic(Intrinsic::cond_loop, Cond);
723 }
724 }
726 B.CreateIntrinsic(Intrinsic::cond_loop,
727 ConstantInt::getTrue(Call->getContext()));
728 Call->eraseFromParent();
729 }
730 return true;
731}
732
733bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
734 // Map unique constants to globals.
735 DenseMap<Constant *, GlobalVariable *> CMap;
736 bool Changed = false;
737 for (Function &F : M) {
738 switch (F.getIntrinsicID()) {
739 default:
740 break;
741 case Intrinsic::memcpy:
742 case Intrinsic::memcpy_inline:
743 case Intrinsic::memmove:
744 case Intrinsic::memset:
745 case Intrinsic::memset_inline:
746 case Intrinsic::experimental_memset_pattern:
747 Changed |= expandMemIntrinsicUses(F, CMap);
748 break;
749 case Intrinsic::load_relative:
751 break;
752 case Intrinsic::can_load_speculatively:
754 break;
755 case Intrinsic::is_constant:
756 case Intrinsic::objectsize:
757 Changed |= forEachCall(F, [&](CallInst *CI) {
758 Function *Parent = CI->getParent()->getParent();
759 TargetLibraryInfo &TLI = LookupTLI(*Parent);
760 // Intrinsics in unreachable code are not lowered.
761 bool Changed = lowerConstantIntrinsics(*Parent, TLI, /*DT=*/nullptr);
762 return Changed;
763 });
764 break;
765#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
766 case Intrinsic::VPID:
767#include "llvm/IR/VPIntrinsics.def"
768 forEachCall(F, [&](CallInst *CI) {
769 Function *Parent = CI->getParent()->getParent();
770 const TargetTransformInfo &TTI = LookupTTI(*Parent);
771 auto *VPI = cast<VPIntrinsic>(CI);
773 // Expansion of VP intrinsics may change the IR but not actually
774 // replace the intrinsic, so update Changed for the pass
775 // and compute Removed for forEachCall.
776 Changed |= ED != VPExpansionDetails::IntrinsicUnchanged;
777 bool Removed = ED == VPExpansionDetails::IntrinsicReplaced;
778 return Removed;
779 });
780 break;
781 case Intrinsic::objc_autorelease:
782 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autorelease);
783 break;
784 case Intrinsic::objc_autoreleasePoolPop:
785 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPop);
786 break;
787 case Intrinsic::objc_autoreleasePoolPush:
788 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPush);
789 break;
790 case Intrinsic::objc_autoreleaseReturnValue:
791 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleaseReturnValue);
792 break;
793 case Intrinsic::objc_copyWeak:
794 Changed |= lowerObjCCall(F, RTLIB::impl_objc_copyWeak);
795 break;
796 case Intrinsic::objc_destroyWeak:
797 Changed |= lowerObjCCall(F, RTLIB::impl_objc_destroyWeak);
798 break;
799 case Intrinsic::objc_initWeak:
800 Changed |= lowerObjCCall(F, RTLIB::impl_objc_initWeak);
801 break;
802 case Intrinsic::objc_loadWeak:
803 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeak);
804 break;
805 case Intrinsic::objc_loadWeakRetained:
806 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeakRetained);
807 break;
808 case Intrinsic::objc_moveWeak:
809 Changed |= lowerObjCCall(F, RTLIB::impl_objc_moveWeak);
810 break;
811 case Intrinsic::objc_release:
812 Changed |= lowerObjCCall(F, RTLIB::impl_objc_release, true);
813 break;
814 case Intrinsic::objc_retain:
815 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain, true);
816 break;
817 case Intrinsic::objc_retainAutorelease:
818 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainAutorelease);
819 break;
820 case Intrinsic::objc_retainAutoreleaseReturnValue:
821 Changed |=
822 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleaseReturnValue);
823 break;
824 case Intrinsic::objc_retainAutoreleasedReturnValue:
825 Changed |=
826 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleasedReturnValue);
827 break;
828 case Intrinsic::objc_claimAutoreleasedReturnValue:
829 Changed |=
830 lowerObjCCall(F, RTLIB::impl_objc_claimAutoreleasedReturnValue);
831 break;
832 case Intrinsic::objc_retainBlock:
833 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainBlock);
834 break;
835 case Intrinsic::objc_storeStrong:
836 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeStrong);
837 break;
838 case Intrinsic::objc_storeWeak:
839 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeWeak);
840 break;
841 case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
842 Changed |=
843 lowerObjCCall(F, RTLIB::impl_objc_unsafeClaimAutoreleasedReturnValue);
844 break;
845 case Intrinsic::objc_retainedObject:
846 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainedObject);
847 break;
848 case Intrinsic::objc_unretainedObject:
849 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedObject);
850 break;
851 case Intrinsic::objc_unretainedPointer:
852 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedPointer);
853 break;
854 case Intrinsic::objc_retain_autorelease:
855 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain_autorelease);
856 break;
857 case Intrinsic::objc_sync_enter:
858 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_enter);
859 break;
860 case Intrinsic::objc_sync_exit:
861 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_exit);
862 break;
863 case Intrinsic::acos:
864 case Intrinsic::asin:
865 case Intrinsic::atan:
866 case Intrinsic::cos:
867 case Intrinsic::cosh:
868 case Intrinsic::exp:
869 case Intrinsic::exp2:
870 case Intrinsic::exp10:
871 case Intrinsic::log:
872 case Intrinsic::log2:
873 case Intrinsic::log10:
874 case Intrinsic::sin:
875 case Intrinsic::sinh:
876 case Intrinsic::tan:
877 case Intrinsic::tanh:
878 Changed |= forEachCall(F, [&](CallInst *CI) {
879 Type *Ty = CI->getArgOperand(0)->getType();
881 return false;
882 const TargetLowering *TL = TM.getSubtargetImpl(F)->getTargetLowering();
883 unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
884 assert(Op != ISD::DELETED_NODE && "unsupported intrinsic");
885 if (!TL->isOperationExpand(Op, EVT::getEVT(Ty)))
886 return false;
888 });
889 break;
890 case Intrinsic::modf:
891 case Intrinsic::sincos:
892 case Intrinsic::sincospi:
893 Changed |= forEachCall(F, [&](CallInst *CI) {
894 Type *Ty = CI->getArgOperand(0)->getType();
896 return false;
897 const TargetSubtargetInfo *Subtarget = TM.getSubtargetImpl(F);
898 const TargetLowering *TL = Subtarget->getTargetLowering();
899 unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
900 assert(Op != ISD::DELETED_NODE && "unsupported intrinsic");
901 EVT VT = EVT::getEVT(Ty);
902 if (!TL->isOperationExpand(Op, VT))
903 return false;
904 // The vector legalizer can expand these to a vector math library call.
905 RTLIB::Libcall LC;
906 switch (Op) {
907 case ISD::FMODF:
908 LC = RTLIB::getMODF(VT);
909 break;
910 case ISD::FSINCOS:
911 LC = RTLIB::getSINCOS(VT);
912 break;
913 case ISD::FSINCOSPI:
914 LC = RTLIB::getSINCOSPI(VT);
915 break;
916 default:
917 llvm_unreachable("unexpected intrinsic");
918 }
919
920 const LibcallLoweringInfo &Libcalls =
921 getLibcallLowering(ModuleLibcalls, *Subtarget);
922 if (Libcalls.getVectorLibcallImplOrMasked(LC) != RTLIB::Unsupported)
923 return false;
925 });
926 break;
927 case Intrinsic::ptrauth_sign:
928 case Intrinsic::ptrauth_auth:
930 break;
931 case Intrinsic::protected_field_ptr:
933 break;
934 case Intrinsic::cond_loop:
935 if (!TM.canLowerCondLoop())
937 break;
938 case Intrinsic::looptrap:
940 if (!TM.canLowerCondLoop())
941 if (auto *CondLoop = M.getFunction("llvm.cond.loop"))
942 Changed |= expandCondLoop(*CondLoop);
943 break;
944 }
945 }
946 return Changed;
947}
948
949namespace {
950
951class PreISelIntrinsicLoweringLegacyPass : public ModulePass {
952public:
953 static char ID;
954
955 PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {}
956
957 void getAnalysisUsage(AnalysisUsage &AU) const override {
958 AU.addRequired<TargetTransformInfoWrapperPass>();
959 AU.addRequired<TargetLibraryInfoWrapperPass>();
960 AU.addRequired<LibcallLoweringInfoWrapper>();
961 AU.addRequired<TargetPassConfig>();
962 AU.addRequired<AssumptionCacheTracker>();
963 }
964
965 bool runOnModule(Module &M) override {
966 const ModuleLibcallLoweringInfo &ModuleLibcalls =
967 getAnalysis<LibcallLoweringInfoWrapper>().getResult(M);
968
969 auto LookupTTI = [this](Function &F) -> TargetTransformInfo & {
970 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
971 };
972 auto LookupTLI = [this](Function &F) -> TargetLibraryInfo & {
973 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
974 };
975 auto LookupAC = [this](Function &F) -> AssumptionCache & {
976 return this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
977 };
978
979 const auto &TM = getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
980 PreISelIntrinsicLowering Lowering(TM, ModuleLibcalls, LookupTTI, LookupTLI,
981 LookupAC);
982 return Lowering.lowerIntrinsics(M);
983 }
984};
985
986} // end anonymous namespace
987
988char PreISelIntrinsicLoweringLegacyPass::ID;
989
990INITIALIZE_PASS_BEGIN(PreISelIntrinsicLoweringLegacyPass,
991 "pre-isel-intrinsic-lowering",
992 "Pre-ISel Intrinsic Lowering", false, false)
999INITIALIZE_PASS_END(PreISelIntrinsicLoweringLegacyPass,
1000 "pre-isel-intrinsic-lowering",
1001 "Pre-ISel Intrinsic Lowering", false, false)
1002
1004 return new PreISelIntrinsicLoweringLegacyPass();
1005}
1006
1009 const ModuleLibcallLoweringInfo &LibcallLowering =
1010 MAM.getResult<LibcallLoweringModuleAnalysis>(M);
1011
1012 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
1013
1014 auto LookupTTI = [&FAM](Function &F) -> TargetTransformInfo & {
1015 return FAM.getResult<TargetIRAnalysis>(F);
1016 };
1017 auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
1018 return FAM.getResult<TargetLibraryAnalysis>(F);
1019 };
1020 auto LookupAC = [&FAM](Function &F) -> AssumptionCache & {
1021 return FAM.getResult<AssumptionAnalysis>(F);
1022 };
1023
1024 PreISelIntrinsicLowering Lowering(TM, LibcallLowering, LookupTTI, LookupTLI,
1025 LookupAC);
1026 if (!Lowering.lowerIntrinsics(M))
1027 return PreservedAnalyses::all();
1028 else
1029 return PreservedAnalyses::none();
1030}
const AArch64Subtarget & Subtarget
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool setNonLazyBind(Function &F)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define DEBUG_TYPE
Module.h This file contains the declarations for the Module class.
This defines the Use class.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file contains the declarations for metadata subclasses.
#define T
This file defines ARC utility functions which are used by various parts of the compiler.
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static cl::opt< int64_t > MemIntrinsicExpandSizeThresholdOpt("mem-intrinsic-expand-size", cl::desc("Set minimum mem intrinsic size to expand in IR"), cl::init(-1), cl::Hidden)
Threshold to leave statically sized memory intrinsic calls.
static bool lowerCanLoadSpeculatively(Function &F, const TargetMachine &TM)
Lower @llvm.can.load.speculatively using target-specific expansion.
static GlobalValue * getDeactivationSymbol(CallInst *Call)
static cl::opt< uint64_t > BoundedMemSetInlineSizeOpt("bounded-memset-inline-size", cl::desc("Set maximum bound of a variable-length memset to expand inline"), cl::Hidden)
Maximum bound of a memset with non-constant length for it to be expanded inline.
static bool canEmitMemcpy(const ModuleLibcallLoweringInfo &ModuleLowering, const TargetMachine &TM, Function *F)
static bool forEachCall(Function &Intrin, T Callback)
static bool expandLoopTrap(Function &Intr)
static bool expandCondLoop(Function &Intr)
static Constant * getMemSetPattern16Value(MemSetPatternInst *Inst, const RTLIB::RuntimeLibcallsInfo &RTLCI)
pre isel intrinsic Pre ISel Intrinsic Lowering
static bool canEmitLibcall(const ModuleLibcallLoweringInfo &ModuleLowering, const TargetMachine &TM, Function *F, RTLIB::Libcall LC)
static CallInst::TailCallKind getOverridingTailCallKind(const Function &F)
static bool expandPtrauthForEmuPAC(Function &Intr)
static bool expandProtectedFieldPtr(Function &Intr)
static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn, bool setNonLazyBind=false)
static bool lowerLoadRelative(Function &F)
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
This file contains some templates that are useful if you are working with the STL at all.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
const AArch64TargetLowering * getTargetLowering() const override
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition APInt.h:1186
AnalysisUsage & addRequired()
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:262
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
void setCallingConv(CallingConv::ID CC)
Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Get the attribute of a given kind from a given arg.
void setAttributes(AttributeList A)
Set the attributes for this call.
Value * getArgOperand(unsigned i) const
AttributeList getAttributes() const
Return the attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
This class represents a function call, abstracting a target machine's calling convention.
void setTailCallKind(TailCallKind TCK)
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
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
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
This is an important base class in LLVM.
Definition Constant.h:44
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionType * getFunctionType()
Type * getParamType(unsigned i) const
Parameter type accessors.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition Function.h:247
const Function & getFunction() const
Definition Function.h:167
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:692
void setUnnamedAddr(UnnamedAddr Val)
Module * getParent()
Get the module that this global value is contained inside of...
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2987
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
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 AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI bool mayLowerToFunctionCall(Intrinsic::ID IID)
Check if the intrinsic might lower into a regular function call in the course of IR transformations.
Tracks which library functions to use for a particular subtarget or function.
RTLIB::LibcallImpl getVectorLibcallImplOrMasked(RTLIB::Libcall Call) const
Return the implementation for Call, or for its masked variant if Call has no implementation.
Value * getLength() const
Value * getRawDest() const
const Use & getLengthUse() const
bool isVolatile() const
Value * getValue() const
This class wraps the llvm.experimental.memset.pattern intrinsic.
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
const RTLIB::RuntimeLibcallsInfo & getRuntimeLibcallsInfo() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:253
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition StringRef.h:446
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool isOperationExpand(unsigned Op, EVT VT) const
Return true if the specified operation is illegal on this target or unlikely to be made legal with cu...
int IntrinsicIDToISD(Intrinsic::ID ID) const
Get the ISD node that corresponds to the Intrinsic ID.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual bool canLowerCondLoop() const
Returns whether the backend can lower the llvm.cond.loop intrinsic.
Target-Independent Code Generator Pass Configuration Options.
virtual const TargetLowering * getTargetLowering() const
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM_ABI uint64_t getMaxBoundedMemSetInlineSize() const
Returns the maximum length in bytes for which a memset with a non-constant length,...
LLVM_ABI uint64_t getMaxMemIntrinsicInlineSizeThreshold() const
Returns the maximum memset / memcpy size in bytes that still makes it profitable to inline the call.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
Definition Triple.h:1221
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
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
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition Use.cpp:35
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
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
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:548
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
iterator_range< user_iterator > users()
Definition Value.h:428
use_iterator use_begin()
Definition Value.h:366
bool use_empty() const
Definition Value.h:348
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:47
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
initializer< Ty > init(const Ty &Val)
LLVM_ABI bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword.
LLVM_ABI bool IsAlwaysTail(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the "tail" keyword...
ARCInstKind
Equivalence classes of instructions in the ARC Model.
LLVM_ABI ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
std::optional< Function * > getAttachedARCFunction(const CallBase *CB)
This function returns operand bundle clang_arc_attachedcall's argument, which is the address of the A...
Definition ObjCARCUtil.h:43
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 bool lowerUnaryVectorIntrinsicAsLoop(Module &M, CallInst *CI)
Lower CI as a loop.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo &TLI, DominatorTree *DT)
LLVM_ABI bool expandMemMoveAsLoop(MemMoveInst *MemMove, const TargetTransformInfo &TTI)
Expand MemMove as a loop.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI ModulePass * createPreISelIntrinsicLoweringPass()
This pass lowers the @llvm.load.relative and @llvm.objc.
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI MDNode * getExplicitlyUnknownBranchWeightsIfProfiled(Function &F, StringRef PassName)
Returns a metadata node containing unknown branch weights if the function has an entry count,...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI VPExpansionDetails expandVectorPredicationIntrinsic(VPIntrinsic &VPI, const TargetTransformInfo &TTI)
Expand a vector predication intrinsic.
TargetTransformInfo TTI
OperandBundleDefT< Value * > OperandBundleDef
Definition AutoUpgrade.h:34
LLVM_ABI ConstantRange computeConstantRangeIncludingKnownBits(const WithCache< const Value * > &V, bool ForSigned, const SimplifyQuery &SQ)
Combine constant ranges from computeConstantRange() and computeKnownBits().
DWARFExpression::Operation Op
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.
auto predecessors(const MachineBasicBlock *BB)
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 ...
VPExpansionDetails
Represents the details the expansion of a VP intrinsic.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A simple container for information about the supported runtime calls.
LLVM_ABI FunctionCallee getOrInsertLibcallDecl(Module &M, RTLIB::LibcallImpl LibcallImpl) const
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
bool isAvailable(RTLIB::LibcallImpl Impl) const
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.