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"
49
50using namespace llvm;
51
52#define DEBUG_TYPE "pre-isel-intrinsic-lowering"
53
54/// Threshold to leave statically sized memory intrinsic calls. Calls of known
55/// size larger than this will be expanded by the pass. Calls of unknown or
56/// lower size will be left for expansion in codegen.
58 "mem-intrinsic-expand-size",
59 cl::desc("Set minimum mem intrinsic size to expand in IR"), cl::init(-1),
61
62/// Maximum bound of a memset with non-constant length for it to be expanded
63/// inline. Overrides TargetTransformInfo::getMaxBoundedMemSetInlineSize.
65 "bounded-memset-inline-size",
66 cl::desc("Set maximum bound of a variable-length memset to expand inline"),
68
69namespace {
70
71struct PreISelIntrinsicLowering {
72 const TargetMachine *TM;
73 const ModuleLibcallLoweringInfo &ModuleLibcalls;
74 const function_ref<TargetTransformInfo &(Function &)> LookupTTI;
75 const function_ref<TargetLibraryInfo &(Function &)> LookupTLI;
76 const function_ref<AssumptionCache &(Function &)> LookupAC;
77
78 /// If this is true, assume it's preferably to leave memory intrinsic calls
79 /// for replacement with a library call later. Otherwise this depends on
80 /// TargetLoweringInfo availability of the corresponding function.
81 const bool UseMemIntrinsicLibFunc;
82
83 explicit PreISelIntrinsicLowering(
84 const TargetMachine *TM_,
85 const ModuleLibcallLoweringInfo &ModuleLibcalls_,
89 bool UseMemIntrinsicLibFunc_ = true)
90 : TM(TM_), ModuleLibcalls(ModuleLibcalls_), LookupTTI(LookupTTI_),
91 LookupTLI(LookupTLI_), LookupAC(LookupAC_),
92 UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) {}
93
94 static bool shouldExpandMemIntrinsicWithSize(Value *Size,
95 const TargetTransformInfo &TTI);
96 bool tryExpandBoundedMemSet(MemSetInst *Memset,
97 const TargetTransformInfo &TTI) const;
98 bool
99 expandMemIntrinsicUses(Function &F,
100 DenseMap<Constant *, GlobalVariable *> &CMap) const;
101 bool lowerIntrinsics(Module &M) const;
102};
103
104} // namespace
105
106template <class T> static bool forEachCall(Function &Intrin, T Callback) {
107 // Lowering all intrinsics in a function will delete multiple uses, so we
108 // can't use an early-inc-range. In case some remain, we don't want to look
109 // at them again. Unfortunately, Value::UseList is private, so we can't use a
110 // simple Use**. If LastUse is null, the next use to consider is
111 // Intrin.use_begin(), otherwise it's LastUse->getNext().
112 Use *LastUse = nullptr;
113 bool Changed = false;
114 while (!Intrin.use_empty() && (!LastUse || LastUse->getNext())) {
115 Use *U = LastUse ? LastUse->getNext() : &*Intrin.use_begin();
116 bool Removed = false;
117 // An intrinsic cannot have its address taken, so it cannot be an argument
118 // operand. It might be used as operand in debug metadata, though.
119 if (auto CI = dyn_cast<CallInst>(U->getUser()))
120 Changed |= Removed = Callback(CI);
121 if (!Removed)
122 LastUse = U;
123 }
124 return Changed;
125}
126
128 if (F.use_empty())
129 return false;
130
131 bool Changed = false;
132 Type *Int32Ty = Type::getInt32Ty(F.getContext());
133
134 for (Use &U : llvm::make_early_inc_range(F.uses())) {
135 auto CI = dyn_cast<CallInst>(U.getUser());
136 if (!CI || CI->getCalledOperand() != &F)
137 continue;
138
139 IRBuilder<> B(CI);
140 Value *Ptr = CI->getArgOperand(0);
141 Value *OffsetPtr = B.CreatePtrAddWithSExtOrTrunc(Ptr, CI->getArgOperand(1));
142 Value *OffsetI32 = B.CreateAlignedLoad(Int32Ty, OffsetPtr, Align(4));
143
144 Value *ResultPtr = B.CreatePtrAddWithSExtOrTrunc(Ptr, OffsetI32);
145
146 CI->replaceAllUsesWith(ResultPtr);
147 CI->eraseFromParent();
148 Changed = true;
149 }
150
151 return Changed;
152}
153
154/// Lower @llvm.can.load.speculatively using target-specific expansion.
155/// Targets may provide their own expansion via
156/// TargetLowering::emitCanLoadSpeculatively; the default expansion
157/// conservatively returns false.
159 if (!TM)
160 return false;
161
162 return forEachCall(F, [&](CallInst *CI) {
163 const TargetLowering *TLI =
165
166 IRBuilder<> Builder(CI);
167 // A null result means the target cannot answer; lower to false.
168 Value *Result = TLI->emitCanLoadSpeculatively(Builder, CI->getArgOperand(0),
169 CI->getArgOperand(1));
170 if (!Result)
171 Result = Builder.getFalse();
172
173 CI->replaceAllUsesWith(Result);
174 CI->eraseFromParent();
175 return true;
176 });
177}
178
179// ObjCARC has knowledge about whether an obj-c runtime function needs to be
180// always tail-called or never tail-called.
189
190static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn,
191 bool setNonLazyBind = false) {
193 "Pre-ISel intrinsics do lower into regular function calls");
194 if (F.use_empty())
195 return false;
196
197 // FIXME: When RuntimeLibcalls is an analysis, check if the function is really
198 // supported, and go through RTLIB::Libcall.
200
201 // If we haven't already looked up this function, check to see if the
202 // program already contains a function with this name.
203 Module *M = F.getParent();
204 FunctionCallee FCache =
205 M->getOrInsertFunction(NewFnName, F.getFunctionType());
206
207 if (Function *Fn = dyn_cast<Function>(FCache.getCallee())) {
208 Fn->setLinkage(F.getLinkage());
209 if (setNonLazyBind && !Fn->isWeakForLinker()) {
210 // If we have Native ARC, set nonlazybind attribute for these APIs for
211 // performance.
212 Fn->addFnAttr(Attribute::NonLazyBind);
213 }
214 }
215
217
218 for (Use &U : llvm::make_early_inc_range(F.uses())) {
219 auto *CB = cast<CallBase>(U.getUser());
220
221 if (CB->getCalledFunction() != &F) {
223 "use expected to be the argument of operand bundle "
224 "\"clang.arc.attachedcall\"");
225 U.set(FCache.getCallee());
226 continue;
227 }
228
229 auto *CI = cast<CallInst>(CB);
230 assert(CI->getCalledFunction() && "Cannot lower an indirect call!");
231
232 IRBuilder<> Builder(CI->getIterator());
233 SmallVector<Value *, 8> Args(CI->args());
235 CI->getOperandBundlesAsDefs(BundleList);
236 CallInst *NewCI = Builder.CreateCall(FCache, Args, BundleList);
237 NewCI->setName(CI->getName());
238
239 // Try to set the most appropriate TailCallKind based on both the current
240 // attributes and the ones that we could get from ObjCARC's special
241 // knowledge of the runtime functions.
242 //
243 // std::max respects both requirements of notail and tail here:
244 // * notail on either the call or from ObjCARC becomes notail
245 // * tail on either side is stronger than none, but not notail
246 CallInst::TailCallKind TCK = CI->getTailCallKind();
247 NewCI->setTailCallKind(std::max(TCK, OverridingTCK));
248
249 // Transfer the 'returned' attribute from the intrinsic to the call site.
250 // By applying this only to intrinsic call sites, we avoid applying it to
251 // non-ARC explicit calls to things like objc_retain which have not been
252 // auto-upgraded to use the intrinsics.
253 unsigned Index;
254 if (F.getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) &&
255 Index)
256 NewCI->addParamAttr(Index - AttributeList::FirstArgIndex,
257 Attribute::Returned);
258
259 if (!CI->use_empty())
260 CI->replaceAllUsesWith(NewCI);
261 CI->eraseFromParent();
262 }
263
264 return true;
265}
266
267// TODO: Should refine based on estimated number of accesses (e.g. does it
268// require splitting based on alignment)
269bool PreISelIntrinsicLowering::shouldExpandMemIntrinsicWithSize(
271 ConstantInt *CI = dyn_cast<ConstantInt>(Size);
272 if (!CI)
273 return true;
274 uint64_t Threshold = MemIntrinsicExpandSizeThresholdOpt.getNumOccurrences()
277 uint64_t SizeVal = CI->getZExtValue();
278
279 // Treat a threshold of 0 as a special case to force expansion of all
280 // intrinsics, including size 0.
281 return SizeVal > Threshold || Threshold == 0;
282}
283
284static bool canEmitLibcall(const ModuleLibcallLoweringInfo &ModuleLowering,
285 const TargetMachine *TM, Function *F,
286 RTLIB::Libcall LC) {
287 // TODO: Should this consider the address space of the memcpy?
288 if (!TM)
289 return true;
291 getLibcallLowering(ModuleLowering, *TM->getSubtargetImpl(*F));
292 return Lowering.getLibcallImpl(LC) != RTLIB::Unsupported;
293}
294
295static bool canEmitMemcpy(const ModuleLibcallLoweringInfo &ModuleLowering,
296 const TargetMachine *TM, Function *F) {
297 // TODO: Should this consider the address space of the memcpy?
298 if (!TM)
299 return true;
301 getLibcallLowering(ModuleLowering, *TM->getSubtargetImpl(*F));
302 return Lowering.getMemcpyImpl() != RTLIB::Unsupported;
303}
304
305// Expand a memset whose length is not constant but is known to be small, which
306// is faster than calling the library.
307bool PreISelIntrinsicLowering::tryExpandBoundedMemSet(
308 MemSetInst *Memset, const TargetTransformInfo &TTI) const {
309 // This pass runs even at -O0, so skip if e.g. llc -O0 is used.
310 if (!TM || TM->getOptLevel() == CodeGenOptLevel::None)
311 return false;
312
313 Value *Len = Memset->getLength();
314 Function *F = Memset->getFunction();
315 if (isa<Constant>(Len) || Memset->isVolatile() || F->hasOptNone() ||
316 F->hasMinSize())
317 return false;
318 uint64_t Threshold = BoundedMemSetInlineSizeOpt.getNumOccurrences()
321 if (!Threshold)
322 return false;
323
324 // Bounds from (1) assumptions, e.g. __builtin_assume(len <= 32)
325 // and (2) known bits and ranges on instructions themselves, and...
326 SimplifyQuery SQ(Memset->getDataLayout(), Memset);
327 SQ.AC = &LookupAC(*F);
328 KnownBits Known = computeKnownBits(Len, SQ);
330 {Len, Known}, /*ForSigned=*/false, SQ);
331
332 // ... (3) range attr on the memset.
333 Attribute RangeAttr = Memset->getParamAttr(
334 Memset->getLengthUse().getOperandNo(), Attribute::Range);
335 if (RangeAttr.isValid())
336 CR = CR.intersectWith(RangeAttr.getRange());
337
338 if (CR.isEmptySet() || CR.getUnsignedMax().ugt(Threshold))
339 return false;
340
343 return true;
344}
345
346// Return a value appropriate for use with the memset_pattern16 libcall, if
347// possible and if we know how. (Adapted from equivalent helper in
348// LoopIdiomRecognize).
350 const TargetLibraryInfo &TLI) {
351 // TODO: This could check for UndefValue because it can be merged into any
352 // other valid pattern.
353
354 // Don't emit libcalls if a non-default address space is being used.
355 if (Inst->getRawDest()->getType()->getPointerAddressSpace() != 0)
356 return nullptr;
357
358 Value *V = Inst->getValue();
359 Type *VTy = V->getType();
360 const DataLayout &DL = Inst->getDataLayout();
361 Module *M = Inst->getModule();
362
363 if (!isLibFuncEmittable(M, &TLI, LibFunc_memset_pattern16))
364 return nullptr;
365
366 // If the value isn't a constant, we can't promote it to being in a constant
367 // array. We could theoretically do a store to an alloca or something, but
368 // that doesn't seem worthwhile.
370 if (!C || isa<ConstantExpr>(C))
371 return nullptr;
372
373 // Only handle simple values that are a power of two bytes in size.
374 uint64_t Size = DL.getTypeSizeInBits(VTy);
375 if (!DL.typeSizeEqualsStoreSize(VTy) || !isPowerOf2_64(Size))
376 return nullptr;
377
378 // Don't care enough about darwin/ppc to implement this.
379 if (DL.isBigEndian())
380 return nullptr;
381
382 // Convert to size in bytes.
383 Size /= 8;
384
385 // TODO: If CI is larger than 16-bytes, we can try slicing it in half to see
386 // if the top and bottom are the same (e.g. for vectors and large integers).
387 if (Size > 16)
388 return nullptr;
389
390 // If the constant is exactly 16 bytes, just use it.
391 if (Size == 16)
392 return C;
393
394 // Otherwise, we'll use an array of the constants.
395 uint64_t ArraySize = 16 / Size;
396 ArrayType *AT = ArrayType::get(V->getType(), ArraySize);
397 return ConstantArray::get(AT, std::vector<Constant *>(ArraySize, C));
398}
399
400// TODO: Handle atomic memcpy and memcpy.inline
401// TODO: Pass ScalarEvolution
402bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
403 Function &F, DenseMap<Constant *, GlobalVariable *> &CMap) const {
404 Intrinsic::ID ID = F.getIntrinsicID();
405 bool Changed = false;
406
407 for (User *U : llvm::make_early_inc_range(F.users())) {
409
410 switch (ID) {
411 case Intrinsic::memcpy: {
412 auto *Memcpy = cast<MemCpyInst>(Inst);
413 Function *ParentFunc = Memcpy->getFunction();
414 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
415 if (shouldExpandMemIntrinsicWithSize(Memcpy->getLength(), TTI)) {
416 if (UseMemIntrinsicLibFunc &&
417 canEmitMemcpy(ModuleLibcalls, TM, ParentFunc))
418 break;
419
420 // TODO: For optsize, emit the loop into a separate function
421 expandMemCpyAsLoop(Memcpy, TTI);
422 Changed = true;
423 Memcpy->eraseFromParent();
424 }
425
426 break;
427 }
428 case Intrinsic::memcpy_inline: {
429 // Only expand llvm.memcpy.inline with non-constant length in this
430 // codepath, leaving the current SelectionDAG expansion for constant
431 // length memcpy intrinsics undisturbed.
432 auto *Memcpy = cast<MemCpyInst>(Inst);
433 if (isa<ConstantInt>(Memcpy->getLength()))
434 break;
435
436 Function *ParentFunc = Memcpy->getFunction();
437 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
438 expandMemCpyAsLoop(Memcpy, TTI);
439 Changed = true;
440 Memcpy->eraseFromParent();
441 break;
442 }
443 case Intrinsic::memmove: {
444 auto *Memmove = cast<MemMoveInst>(Inst);
445 Function *ParentFunc = Memmove->getFunction();
446 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
447 if (shouldExpandMemIntrinsicWithSize(Memmove->getLength(), TTI)) {
448 if (UseMemIntrinsicLibFunc &&
449 canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMMOVE))
450 break;
451
452 if (expandMemMoveAsLoop(Memmove, TTI)) {
453 Changed = true;
454 Memmove->eraseFromParent();
455 }
456 }
457
458 break;
459 }
460 case Intrinsic::memset: {
461 auto *Memset = cast<MemSetInst>(Inst);
462 Function *ParentFunc = Memset->getFunction();
463 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
464 if (tryExpandBoundedMemSet(Memset, TTI)) {
465 Changed = true;
466 Memset->eraseFromParent();
467 break;
468 }
469 if (shouldExpandMemIntrinsicWithSize(Memset->getLength(), TTI)) {
470 if (UseMemIntrinsicLibFunc &&
471 canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMSET))
472 break;
473
474 expandMemSetAsLoop(Memset, TTI);
475 Changed = true;
476 Memset->eraseFromParent();
477 }
478
479 break;
480 }
481 case Intrinsic::memset_inline: {
482 // Only expand llvm.memset.inline with non-constant length in this
483 // codepath, leaving the current SelectionDAG expansion for constant
484 // length memset intrinsics undisturbed.
485 auto *Memset = cast<MemSetInst>(Inst);
486 if (isa<ConstantInt>(Memset->getLength()))
487 break;
488
489 Function *ParentFunc = Memset->getFunction();
490 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
491 expandMemSetAsLoop(Memset, TTI);
492 Changed = true;
493 Memset->eraseFromParent();
494 break;
495 }
496 case Intrinsic::experimental_memset_pattern: {
497 auto *Memset = cast<MemSetPatternInst>(Inst);
498 Function *ParentFunc = Memset->getFunction();
499 const TargetLibraryInfo &TLI = LookupTLI(*ParentFunc);
500 Constant *PatternValue = getMemSetPattern16Value(Memset, TLI);
501 if (!PatternValue) {
502 // If it isn't possible to emit a memset_pattern16 libcall, expand to
503 // a loop instead.
504 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
506 Changed = true;
507 Memset->eraseFromParent();
508 break;
509 }
510 // FIXME: There is currently no profitability calculation for emitting
511 // the libcall vs expanding the memset.pattern directly.
512 IRBuilder<> Builder(Inst);
513 Module *M = Memset->getModule();
514 const DataLayout &DL = Memset->getDataLayout();
515
516 Type *DestPtrTy = Memset->getRawDest()->getType();
517 Type *SizeTTy = TLI.getSizeTType(*M);
518 StringRef FuncName = "memset_pattern16";
519 FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16,
520 Builder.getVoidTy(), DestPtrTy,
521 Builder.getPtrTy(), SizeTTy);
523
524 // Otherwise we should form a memset_pattern16. PatternValue is known
525 // to be an constant array of 16-bytes. Put the value into a mergable
526 // global.
527 assert(Memset->getRawDest()->getType()->getPointerAddressSpace() == 0 &&
528 "Should have skipped if non-zero AS");
529 GlobalVariable *GV;
530 auto It = CMap.find(PatternValue);
531 if (It != CMap.end()) {
532 GV = It->second;
533 } else {
534 GV = new GlobalVariable(
535 *M, PatternValue->getType(), /*isConstant=*/true,
536 GlobalValue::PrivateLinkage, PatternValue, ".memset_pattern");
537 GV->setUnnamedAddr(
538 GlobalValue::UnnamedAddr::Global); // Ok to merge these.
539 // TODO: Consider relaxing alignment requirement.
540 GV->setAlignment(Align(16));
541 CMap[PatternValue] = GV;
542 }
543 Value *PatternPtr = GV;
544 Value *NumBytes = Builder.CreateMul(
545 TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()),
546 *M),
547 Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy));
548 CallInst *MemsetPattern16Call =
549 Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes});
550 MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());
551 // Preserve any call site attributes on the destination pointer
552 // argument (e.g. alignment).
553 AttrBuilder ArgAttrs(Memset->getContext(),
554 Memset->getAttributes().getParamAttrs(0));
555 MemsetPattern16Call->setAttributes(
556 MemsetPattern16Call->getAttributes().addParamAttributes(
557 Memset->getContext(), 0, ArgAttrs));
558 Changed = true;
559 Memset->eraseFromParent();
560 break;
561 }
562 default:
563 llvm_unreachable("unhandled intrinsic");
564 }
565 }
566
567 return Changed;
568}
569
571 if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deactivation_symbol))
572 return cast<GlobalValue>(Bundle->Inputs[0]);
573 return nullptr;
574}
575
577 Module &M = *Intr.getParent();
578 if (Triple(M.getTargetTriple()).isArm64e())
579 return false;
580
581 Type *Int64Ty = Type::getInt64Ty(M.getContext());
582
583 assert(Intr.getIntrinsicID() == Intrinsic::ptrauth_sign ||
584 Intr.getIntrinsicID() == Intrinsic::ptrauth_auth);
585 auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
586 FunctionCallee EmuIntr = M.getOrInsertFunction(
587 Intr.getIntrinsicID() == Intrinsic::ptrauth_auth ? "__emupac_autda"
588 : "__emupac_pacda",
589 EmuFnTy);
590
591 for (User *U : llvm::make_early_inc_range(Intr.users())) {
592 auto *Call = cast<CallInst>(U);
593 // We only support the DA key for now.
594 if (auto *Key = dyn_cast<ConstantInt>(Call->getArgOperand(1));
595 !Key || Key->getZExtValue() != /*AArch64PACKey::DA*/ 2)
596 continue;
597
598 Function *F = Call->getParent()->getParent();
599 Attribute FSAttr = F->getFnAttribute("target-features");
600 if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
601 continue;
602
603 std::vector<OperandBundleDef> DSBundle;
604 if (auto *DS = getDeactivationSymbol(Call))
605 DSBundle.push_back(OperandBundleDef("deactivation-symbol", DS));
606
608 auto *EmuCall = B.CreateCall(
609 EmuIntr, {Call->getArgOperand(0), Call->getArgOperand(2)}, DSBundle);
610 Call->replaceAllUsesWith(EmuCall);
611 Call->eraseFromParent();
612 }
613 return true;
614}
615
617 Module &M = *Intr.getParent();
618
619 SmallPtrSet<GlobalValue *, 2> DSsToDeactivate;
620
621 Type *Int8Ty = Type::getInt8Ty(M.getContext());
622 Type *Int64Ty = Type::getInt64Ty(M.getContext());
623 PointerType *PtrTy = PointerType::get(M.getContext(), 0);
624
625 for (User *U : llvm::make_early_inc_range(Intr.users())) {
626 auto *Call = cast<CallInst>(U);
627
628 auto *Pointer = Call->getArgOperand(0);
629 bool UseHWEncoding =
630 cast<ConstantInt>(Call->getArgOperand(2))->getZExtValue();
631 if (!UseHWEncoding)
632 reportFatalUsageError("software encoding currently unsupported");
633
634 auto *DS = getDeactivationSymbol(Call);
635 OperandBundleDef DSBundle("deactivation-symbol", DS);
636
637 for (Use &U : llvm::make_early_inc_range(Call->uses())) {
638 // Comparisons against null cannot be used to recover the original
639 // pointer so we replace them with comparisons against the original
640 // pointer.
641 if (auto *CI = dyn_cast<ICmpInst>(U.getUser())) {
642 if (auto *Op = dyn_cast<Constant>(CI->getOperand(0))) {
643 if (Op->isNullValue()) {
644 CI->setOperand(1, Pointer);
645 continue;
646 }
647 }
648 if (auto *Op = dyn_cast<Constant>(CI->getOperand(1))) {
649 if (Op->isNullValue()) {
650 CI->setOperand(0, Pointer);
651 continue;
652 }
653 }
654 }
655
656 // If we are here, this means that we couldn't rewrite away this use of
657 // the intrinsic. Any load or store uses were removed by InstCombine, and
658 // in general, we can't rewrite away non-load/store uses of
659 // llvm.protected.field.ptr because doing so could expose the encoded
660 // pointer value to the program. Replace it with the pointer operand, and
661 // arrange to define a deactivation symbol.
662 U.set(Pointer);
663 if (DS)
664 DSsToDeactivate.insert(DS);
665 }
666
667 Call->eraseFromParent();
668 }
669
670 if (!DSsToDeactivate.empty()) {
671 // This is an AArch64 NOP instruction. When the deactivation symbol support
672 // is expanded to more architectures, there will likely need to be an API
673 // for retrieving this constant.
674 Constant *Nop =
675 ConstantExpr::getIntToPtr(ConstantInt::get(Int64Ty, 0xd503201f), PtrTy);
676 for (GlobalValue *OldDS : DSsToDeactivate) {
678 Int8Ty, 0, GlobalValue::ExternalLinkage, OldDS->getName(), Nop, &M);
679 DS->setVisibility(GlobalValue::HiddenVisibility);
680 DS->takeName(OldDS);
681 OldDS->replaceAllUsesWith(DS);
682 OldDS->eraseFromParent();
683 }
684 }
685 return true;
686}
687
688static bool expandCondLoop(Function &Intr) {
689 for (User *U : llvm::make_early_inc_range(Intr.users())) {
690 auto *Call = cast<CallInst>(U);
691
692 auto *Br = cast<UncondBrInst>(
693 SplitBlockAndInsertIfThen(Call->getArgOperand(0), Call, false,
695 *Call->getFunction(), DEBUG_TYPE)));
696 Br->setSuccessor(Br->getParent());
697 Call->eraseFromParent();
698 }
699 return true;
700}
701
702static bool expandLoopTrap(Function &Intr) {
703 for (User *U : make_early_inc_range(Intr.users())) {
704 auto *Call = cast<CallInst>(U);
705 if (!Call->getParent()->isEntryBlock() &&
706 std::all_of(Call->getParent()->begin(), BasicBlock::iterator(Call),
707 [](Instruction &I) { return !I.mayHaveSideEffects(); })) {
708 for (auto *BB : predecessors(Call->getParent())) {
709 auto *BI = dyn_cast<CondBrInst>(BB->getTerminator());
710 if (!BI)
711 continue;
712 IRBuilder<> B(BI);
713 Value *Cond;
714 // The looptrap can either be on the true branch or the false branch.
715 // We insert the cond loop before the branch, which uses the branch's
716 // original condition for going to the looptrap as its condition, and
717 // force the branch to take whichever path does not lead to the
718 // looptrap, as the original path to the looptrap is now unreachable
719 // thanks to the cond loop. The codegenprepare pass will clean up our
720 // "unconditional conditional branch" by combining the two basic blocks
721 // if possible, or replacing it with an unconditional branch.
722 if (BI->getSuccessor(0) == Call->getParent()) {
723 // The looptrap is on the true branch.
724 Cond = BI->getCondition();
725 BI->setCondition(ConstantInt::getFalse(BI->getContext()));
726 } else {
727 // The looptrap is on the false branch, which means that we need to
728 // invert the condition.
729 Cond = B.CreateNot(BI->getCondition());
730 BI->setCondition(ConstantInt::getTrue(BI->getContext()));
731 }
732 B.CreateIntrinsic(Intrinsic::cond_loop, Cond);
733 }
734 }
736 B.CreateIntrinsic(Intrinsic::cond_loop,
737 ConstantInt::getTrue(Call->getContext()));
738 Call->eraseFromParent();
739 }
740 return true;
741}
742
743bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
744 // Map unique constants to globals.
745 DenseMap<Constant *, GlobalVariable *> CMap;
746 bool Changed = false;
747 for (Function &F : M) {
748 switch (F.getIntrinsicID()) {
749 default:
750 break;
751 case Intrinsic::memcpy:
752 case Intrinsic::memcpy_inline:
753 case Intrinsic::memmove:
754 case Intrinsic::memset:
755 case Intrinsic::memset_inline:
756 case Intrinsic::experimental_memset_pattern:
757 Changed |= expandMemIntrinsicUses(F, CMap);
758 break;
759 case Intrinsic::load_relative:
761 break;
762 case Intrinsic::can_load_speculatively:
764 break;
765 case Intrinsic::is_constant:
766 case Intrinsic::objectsize:
767 Changed |= forEachCall(F, [&](CallInst *CI) {
768 Function *Parent = CI->getParent()->getParent();
769 TargetLibraryInfo &TLI = LookupTLI(*Parent);
770 // Intrinsics in unreachable code are not lowered.
771 bool Changed = lowerConstantIntrinsics(*Parent, TLI, /*DT=*/nullptr);
772 return Changed;
773 });
774 break;
775#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
776 case Intrinsic::VPID:
777#include "llvm/IR/VPIntrinsics.def"
778 forEachCall(F, [&](CallInst *CI) {
779 Function *Parent = CI->getParent()->getParent();
780 const TargetTransformInfo &TTI = LookupTTI(*Parent);
781 auto *VPI = cast<VPIntrinsic>(CI);
783 // Expansion of VP intrinsics may change the IR but not actually
784 // replace the intrinsic, so update Changed for the pass
785 // and compute Removed for forEachCall.
786 Changed |= ED != VPExpansionDetails::IntrinsicUnchanged;
787 bool Removed = ED == VPExpansionDetails::IntrinsicReplaced;
788 return Removed;
789 });
790 break;
791 case Intrinsic::objc_autorelease:
792 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autorelease);
793 break;
794 case Intrinsic::objc_autoreleasePoolPop:
795 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPop);
796 break;
797 case Intrinsic::objc_autoreleasePoolPush:
798 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPush);
799 break;
800 case Intrinsic::objc_autoreleaseReturnValue:
801 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleaseReturnValue);
802 break;
803 case Intrinsic::objc_copyWeak:
804 Changed |= lowerObjCCall(F, RTLIB::impl_objc_copyWeak);
805 break;
806 case Intrinsic::objc_destroyWeak:
807 Changed |= lowerObjCCall(F, RTLIB::impl_objc_destroyWeak);
808 break;
809 case Intrinsic::objc_initWeak:
810 Changed |= lowerObjCCall(F, RTLIB::impl_objc_initWeak);
811 break;
812 case Intrinsic::objc_loadWeak:
813 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeak);
814 break;
815 case Intrinsic::objc_loadWeakRetained:
816 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeakRetained);
817 break;
818 case Intrinsic::objc_moveWeak:
819 Changed |= lowerObjCCall(F, RTLIB::impl_objc_moveWeak);
820 break;
821 case Intrinsic::objc_release:
822 Changed |= lowerObjCCall(F, RTLIB::impl_objc_release, true);
823 break;
824 case Intrinsic::objc_retain:
825 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain, true);
826 break;
827 case Intrinsic::objc_retainAutorelease:
828 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainAutorelease);
829 break;
830 case Intrinsic::objc_retainAutoreleaseReturnValue:
831 Changed |=
832 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleaseReturnValue);
833 break;
834 case Intrinsic::objc_retainAutoreleasedReturnValue:
835 Changed |=
836 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleasedReturnValue);
837 break;
838 case Intrinsic::objc_claimAutoreleasedReturnValue:
839 Changed |=
840 lowerObjCCall(F, RTLIB::impl_objc_claimAutoreleasedReturnValue);
841 break;
842 case Intrinsic::objc_retainBlock:
843 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainBlock);
844 break;
845 case Intrinsic::objc_storeStrong:
846 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeStrong);
847 break;
848 case Intrinsic::objc_storeWeak:
849 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeWeak);
850 break;
851 case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
852 Changed |=
853 lowerObjCCall(F, RTLIB::impl_objc_unsafeClaimAutoreleasedReturnValue);
854 break;
855 case Intrinsic::objc_retainedObject:
856 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainedObject);
857 break;
858 case Intrinsic::objc_unretainedObject:
859 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedObject);
860 break;
861 case Intrinsic::objc_unretainedPointer:
862 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedPointer);
863 break;
864 case Intrinsic::objc_retain_autorelease:
865 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain_autorelease);
866 break;
867 case Intrinsic::objc_sync_enter:
868 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_enter);
869 break;
870 case Intrinsic::objc_sync_exit:
871 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_exit);
872 break;
873 case Intrinsic::acos:
874 case Intrinsic::asin:
875 case Intrinsic::atan:
876 case Intrinsic::cos:
877 case Intrinsic::cosh:
878 case Intrinsic::exp:
879 case Intrinsic::exp2:
880 case Intrinsic::exp10:
881 case Intrinsic::log:
882 case Intrinsic::log2:
883 case Intrinsic::log10:
884 case Intrinsic::sin:
885 case Intrinsic::sinh:
886 case Intrinsic::tan:
887 case Intrinsic::tanh:
888 Changed |= forEachCall(F, [&](CallInst *CI) {
889 Type *Ty = CI->getArgOperand(0)->getType();
891 return false;
892 const TargetLowering *TL = TM->getSubtargetImpl(F)->getTargetLowering();
893 unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
894 assert(Op != ISD::DELETED_NODE && "unsupported intrinsic");
895 if (!TL->isOperationExpand(Op, EVT::getEVT(Ty)))
896 return false;
898 });
899 break;
900 case Intrinsic::modf:
901 case Intrinsic::sincos:
902 case Intrinsic::sincospi:
903 Changed |= forEachCall(F, [&](CallInst *CI) {
904 Type *Ty = CI->getArgOperand(0)->getType();
906 return false;
907 const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(F);
908 const TargetLowering *TL = Subtarget->getTargetLowering();
909 unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
910 assert(Op != ISD::DELETED_NODE && "unsupported intrinsic");
911 EVT VT = EVT::getEVT(Ty);
912 if (!TL->isOperationExpand(Op, VT))
913 return false;
914 // The vector legalizer can expand these to a vector math library call.
915 RTLIB::Libcall LC;
916 switch (Op) {
917 case ISD::FMODF:
918 LC = RTLIB::getMODF(VT);
919 break;
920 case ISD::FSINCOS:
921 LC = RTLIB::getSINCOS(VT);
922 break;
923 case ISD::FSINCOSPI:
924 LC = RTLIB::getSINCOSPI(VT);
925 break;
926 default:
927 llvm_unreachable("unexpected intrinsic");
928 }
929
930 const LibcallLoweringInfo &Libcalls =
931 getLibcallLowering(ModuleLibcalls, *Subtarget);
932 if (Libcalls.getVectorLibcallImplOrMasked(LC) != RTLIB::Unsupported)
933 return false;
935 });
936 break;
937 case Intrinsic::ptrauth_sign:
938 case Intrinsic::ptrauth_auth:
940 break;
941 case Intrinsic::protected_field_ptr:
943 break;
944 case Intrinsic::cond_loop:
945 if (!TM->canLowerCondLoop())
947 break;
948 case Intrinsic::looptrap:
950 if (!TM->canLowerCondLoop())
951 if (auto *CondLoop = M.getFunction("llvm.cond.loop"))
952 Changed |= expandCondLoop(*CondLoop);
953 break;
954 }
955 }
956 return Changed;
957}
958
959namespace {
960
961class PreISelIntrinsicLoweringLegacyPass : public ModulePass {
962public:
963 static char ID;
964
965 PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {}
966
967 void getAnalysisUsage(AnalysisUsage &AU) const override {
968 AU.addRequired<TargetTransformInfoWrapperPass>();
969 AU.addRequired<TargetLibraryInfoWrapperPass>();
970 AU.addRequired<LibcallLoweringInfoWrapper>();
971 AU.addRequired<TargetPassConfig>();
972 AU.addRequired<AssumptionCacheTracker>();
973 }
974
975 bool runOnModule(Module &M) override {
976 const ModuleLibcallLoweringInfo &ModuleLibcalls =
977 getAnalysis<LibcallLoweringInfoWrapper>().getResult(M);
978
979 auto LookupTTI = [this](Function &F) -> TargetTransformInfo & {
980 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
981 };
982 auto LookupTLI = [this](Function &F) -> TargetLibraryInfo & {
983 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
984 };
985 auto LookupAC = [this](Function &F) -> AssumptionCache & {
986 return this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
987 };
988
989 const auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
990 PreISelIntrinsicLowering Lowering(TM, ModuleLibcalls, LookupTTI, LookupTLI,
991 LookupAC);
992 return Lowering.lowerIntrinsics(M);
993 }
994};
995
996} // end anonymous namespace
997
998char PreISelIntrinsicLoweringLegacyPass::ID;
999
1000INITIALIZE_PASS_BEGIN(PreISelIntrinsicLoweringLegacyPass,
1001 "pre-isel-intrinsic-lowering",
1002 "Pre-ISel Intrinsic Lowering", false, false)
1009INITIALIZE_PASS_END(PreISelIntrinsicLoweringLegacyPass,
1010 "pre-isel-intrinsic-lowering",
1011 "Pre-ISel Intrinsic Lowering", false, false)
1012
1014 return new PreISelIntrinsicLoweringLegacyPass();
1015}
1016
1019 const ModuleLibcallLoweringInfo &LibcallLowering =
1020 MAM.getResult<LibcallLoweringModuleAnalysis>(M);
1021
1022 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
1023
1024 auto LookupTTI = [&FAM](Function &F) -> TargetTransformInfo & {
1025 return FAM.getResult<TargetIRAnalysis>(F);
1026 };
1027 auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
1028 return FAM.getResult<TargetLibraryAnalysis>(F);
1029 };
1030 auto LookupAC = [&FAM](Function &F) -> AssumptionCache & {
1031 return FAM.getResult<AssumptionAnalysis>(F);
1032 };
1033
1034 PreISelIntrinsicLowering Lowering(TM, LibcallLowering, LookupTTI, LookupTLI,
1035 LookupAC);
1036 if (!Lowering.lowerIntrinsics(M))
1037 return PreservedAnalyses::all();
1038 else
1039 return PreservedAnalyses::none();
1040}
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 canEmitMemcpy(const ModuleLibcallLoweringInfo &ModuleLowering, const TargetMachine *TM, Function *F)
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 canEmitLibcall(const ModuleLibcallLoweringInfo &ModuleLowering, const TargetMachine *TM, Function *F, RTLIB::Libcall LC)
static bool forEachCall(Function &Intrin, T Callback)
static bool expandLoopTrap(Function &Intr)
static bool expandCondLoop(Function &Intr)
pre isel intrinsic Pre ISel Intrinsic Lowering
static bool lowerCanLoadSpeculatively(Function &F, const TargetMachine *TM)
Lower @llvm.can.load.speculatively using target-specific expansion.
static CallInst::TailCallKind getOverridingTailCallKind(const Function &F)
static bool expandPtrauthForEmuPAC(Function &Intr)
static Constant * getMemSetPattern16Value(MemSetPatternInst *Inst, const TargetLibraryInfo &TLI)
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
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...
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:2949
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.
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:1220
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
LLVM_ABI bool inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name, const TargetLibraryInfo &TLI)
Analyze the name and prototype of the given function and set any applicable attributes.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
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 >
LLVM_ABI FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, LibFunc TheLibFunc, FunctionType *T, AttributeList AttributeList)
Calls getOrInsertFunction() and then makes sure to add mandatory argument attributes.
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)
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.