File indexing completed on 2026-05-10 08:44:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #ifndef LLVM_IR_INTRINSICINST_H
0024 #define LLVM_IR_INTRINSICINST_H
0025
0026 #include "llvm/IR/Constants.h"
0027 #include "llvm/IR/DebugInfoMetadata.h"
0028 #include "llvm/IR/DerivedTypes.h"
0029 #include "llvm/IR/FPEnv.h"
0030 #include "llvm/IR/Function.h"
0031 #include "llvm/IR/GlobalVariable.h"
0032 #include "llvm/IR/Instructions.h"
0033 #include "llvm/IR/Intrinsics.h"
0034 #include "llvm/IR/Value.h"
0035 #include "llvm/Support/Casting.h"
0036 #include "llvm/Support/MathExtras.h"
0037 #include <cassert>
0038 #include <cstdint>
0039 #include <optional>
0040
0041 namespace llvm {
0042
0043 class Metadata;
0044
0045
0046
0047
0048 class IntrinsicInst : public CallInst {
0049 public:
0050 IntrinsicInst() = delete;
0051 IntrinsicInst(const IntrinsicInst &) = delete;
0052 IntrinsicInst &operator=(const IntrinsicInst &) = delete;
0053
0054
0055 Intrinsic::ID getIntrinsicID() const {
0056 return getCalledFunction()->getIntrinsicID();
0057 }
0058
0059 bool isAssociative() const {
0060 switch (getIntrinsicID()) {
0061 case Intrinsic::smax:
0062 case Intrinsic::smin:
0063 case Intrinsic::umax:
0064 case Intrinsic::umin:
0065 return true;
0066 default:
0067 return false;
0068 }
0069 }
0070
0071
0072
0073 bool isCommutative() const {
0074 switch (getIntrinsicID()) {
0075 case Intrinsic::maxnum:
0076 case Intrinsic::minnum:
0077 case Intrinsic::maximum:
0078 case Intrinsic::minimum:
0079 case Intrinsic::maximumnum:
0080 case Intrinsic::minimumnum:
0081 case Intrinsic::smax:
0082 case Intrinsic::smin:
0083 case Intrinsic::umax:
0084 case Intrinsic::umin:
0085 case Intrinsic::sadd_sat:
0086 case Intrinsic::uadd_sat:
0087 case Intrinsic::sadd_with_overflow:
0088 case Intrinsic::uadd_with_overflow:
0089 case Intrinsic::smul_with_overflow:
0090 case Intrinsic::umul_with_overflow:
0091 case Intrinsic::smul_fix:
0092 case Intrinsic::umul_fix:
0093 case Intrinsic::smul_fix_sat:
0094 case Intrinsic::umul_fix_sat:
0095 case Intrinsic::fma:
0096 case Intrinsic::fmuladd:
0097 return true;
0098 default:
0099 return false;
0100 }
0101 }
0102
0103
0104 bool isAssumeLikeIntrinsic() const {
0105 switch (getIntrinsicID()) {
0106 default: break;
0107 case Intrinsic::assume:
0108 case Intrinsic::sideeffect:
0109 case Intrinsic::pseudoprobe:
0110 case Intrinsic::dbg_assign:
0111 case Intrinsic::dbg_declare:
0112 case Intrinsic::dbg_value:
0113 case Intrinsic::dbg_label:
0114 case Intrinsic::invariant_start:
0115 case Intrinsic::invariant_end:
0116 case Intrinsic::lifetime_start:
0117 case Intrinsic::lifetime_end:
0118 case Intrinsic::experimental_noalias_scope_decl:
0119 case Intrinsic::objectsize:
0120 case Intrinsic::ptr_annotation:
0121 case Intrinsic::var_annotation:
0122 return true;
0123 }
0124 return false;
0125 }
0126
0127
0128
0129 static bool mayLowerToFunctionCall(Intrinsic::ID IID);
0130
0131
0132 static bool classof(const CallInst *I) {
0133 if (const Function *CF = I->getCalledFunction())
0134 return CF->isIntrinsic();
0135 return false;
0136 }
0137 static bool classof(const Value *V) {
0138 return isa<CallInst>(V) && classof(cast<CallInst>(V));
0139 }
0140 };
0141
0142
0143 static inline bool isLifetimeIntrinsic(Intrinsic::ID ID) {
0144 switch (ID) {
0145 case Intrinsic::lifetime_start:
0146 case Intrinsic::lifetime_end:
0147 return true;
0148 default:
0149 return false;
0150 }
0151 }
0152
0153
0154 class LifetimeIntrinsic : public IntrinsicInst {
0155 public:
0156
0157
0158 static bool classof(const IntrinsicInst *I) {
0159 return isLifetimeIntrinsic(I->getIntrinsicID());
0160 }
0161 static bool classof(const Value *V) {
0162 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0163 }
0164
0165 };
0166
0167
0168 static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) {
0169 switch (ID) {
0170 case Intrinsic::dbg_declare:
0171 case Intrinsic::dbg_value:
0172 case Intrinsic::dbg_label:
0173 case Intrinsic::dbg_assign:
0174 return true;
0175 default:
0176 return false;
0177 }
0178 }
0179
0180
0181 class DbgInfoIntrinsic : public IntrinsicInst {
0182 public:
0183
0184
0185 static bool classof(const IntrinsicInst *I) {
0186 return isDbgInfoIntrinsic(I->getIntrinsicID());
0187 }
0188 static bool classof(const Value *V) {
0189 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0190 }
0191
0192 };
0193
0194
0195
0196
0197 class location_op_iterator
0198 : public iterator_facade_base<location_op_iterator,
0199 std::bidirectional_iterator_tag, Value *> {
0200 PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
0201
0202 public:
0203 location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
0204 location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
0205
0206 location_op_iterator(const location_op_iterator &R) : I(R.I) {}
0207 location_op_iterator &operator=(const location_op_iterator &R) {
0208 I = R.I;
0209 return *this;
0210 }
0211 bool operator==(const location_op_iterator &RHS) const { return I == RHS.I; }
0212 const Value *operator*() const {
0213 ValueAsMetadata *VAM = isa<ValueAsMetadata *>(I)
0214 ? cast<ValueAsMetadata *>(I)
0215 : *cast<ValueAsMetadata **>(I);
0216 return VAM->getValue();
0217 };
0218 Value *operator*() {
0219 ValueAsMetadata *VAM = isa<ValueAsMetadata *>(I)
0220 ? cast<ValueAsMetadata *>(I)
0221 : *cast<ValueAsMetadata **>(I);
0222 return VAM->getValue();
0223 }
0224 location_op_iterator &operator++() {
0225 if (isa<ValueAsMetadata *>(I))
0226 I = cast<ValueAsMetadata *>(I) + 1;
0227 else
0228 I = cast<ValueAsMetadata **>(I) + 1;
0229 return *this;
0230 }
0231 location_op_iterator &operator--() {
0232 if (isa<ValueAsMetadata *>(I))
0233 I = cast<ValueAsMetadata *>(I) - 1;
0234 else
0235 I = cast<ValueAsMetadata **>(I) - 1;
0236 return *this;
0237 }
0238 };
0239
0240
0241
0242
0243 class RawLocationWrapper {
0244 Metadata *RawLocation = nullptr;
0245
0246 public:
0247 RawLocationWrapper() = default;
0248 explicit RawLocationWrapper(Metadata *RawLocation)
0249 : RawLocation(RawLocation) {
0250
0251 assert(RawLocation && "unexpected null RawLocation");
0252 assert(isa<ValueAsMetadata>(RawLocation) || isa<DIArgList>(RawLocation) ||
0253 (isa<MDNode>(RawLocation) &&
0254 !cast<MDNode>(RawLocation)->getNumOperands()));
0255 }
0256 Metadata *getRawLocation() const { return RawLocation; }
0257
0258
0259
0260 iterator_range<location_op_iterator> location_ops() const;
0261 Value *getVariableLocationOp(unsigned OpIdx) const;
0262 unsigned getNumVariableLocationOps() const {
0263 if (hasArgList())
0264 return cast<DIArgList>(getRawLocation())->getArgs().size();
0265 return 1;
0266 }
0267 bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
0268 bool isKillLocation(const DIExpression *Expression) const {
0269
0270
0271 if (!hasArgList() && isa<MDNode>(getRawLocation()))
0272 return true;
0273
0274 if (getNumVariableLocationOps() == 0 && !Expression->isComplex())
0275 return true;
0276
0277
0278 return any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
0279 }
0280
0281 friend bool operator==(const RawLocationWrapper &A,
0282 const RawLocationWrapper &B) {
0283 return A.RawLocation == B.RawLocation;
0284 }
0285 friend bool operator!=(const RawLocationWrapper &A,
0286 const RawLocationWrapper &B) {
0287 return !(A == B);
0288 }
0289 friend bool operator>(const RawLocationWrapper &A,
0290 const RawLocationWrapper &B) {
0291 return A.RawLocation > B.RawLocation;
0292 }
0293 friend bool operator>=(const RawLocationWrapper &A,
0294 const RawLocationWrapper &B) {
0295 return A.RawLocation >= B.RawLocation;
0296 }
0297 friend bool operator<(const RawLocationWrapper &A,
0298 const RawLocationWrapper &B) {
0299 return A.RawLocation < B.RawLocation;
0300 }
0301 friend bool operator<=(const RawLocationWrapper &A,
0302 const RawLocationWrapper &B) {
0303 return A.RawLocation <= B.RawLocation;
0304 }
0305 };
0306
0307
0308 class DbgVariableIntrinsic : public DbgInfoIntrinsic {
0309 public:
0310
0311
0312
0313 iterator_range<location_op_iterator> location_ops() const;
0314
0315 Value *getVariableLocationOp(unsigned OpIdx) const;
0316
0317 void replaceVariableLocationOp(Value *OldValue, Value *NewValue,
0318 bool AllowEmpty = false);
0319 void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
0320
0321
0322
0323 void addVariableLocationOps(ArrayRef<Value *> NewValues,
0324 DIExpression *NewExpr);
0325
0326 void setVariable(DILocalVariable *NewVar) {
0327 setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar));
0328 }
0329
0330 void setExpression(DIExpression *NewExpr) {
0331 setArgOperand(2, MetadataAsValue::get(NewExpr->getContext(), NewExpr));
0332 }
0333
0334 unsigned getNumVariableLocationOps() const {
0335 return getWrappedLocation().getNumVariableLocationOps();
0336 }
0337
0338 bool hasArgList() const { return getWrappedLocation().hasArgList(); }
0339
0340
0341
0342
0343 bool isAddressOfVariable() const {
0344 return getIntrinsicID() == Intrinsic::dbg_declare;
0345 }
0346
0347
0348
0349
0350
0351 bool isValueOfVariable() const {
0352 return getIntrinsicID() == Intrinsic::dbg_value;
0353 }
0354
0355 void setKillLocation() {
0356
0357
0358 SmallPtrSet<Value *, 4> RemovedValues;
0359 for (Value *OldValue : location_ops()) {
0360 if (!RemovedValues.insert(OldValue).second)
0361 continue;
0362 Value *Poison = PoisonValue::get(OldValue->getType());
0363 replaceVariableLocationOp(OldValue, Poison);
0364 }
0365 }
0366
0367 bool isKillLocation() const {
0368 return getWrappedLocation().isKillLocation(getExpression());
0369 }
0370
0371 DILocalVariable *getVariable() const {
0372 return cast<DILocalVariable>(getRawVariable());
0373 }
0374
0375 DIExpression *getExpression() const {
0376 return cast<DIExpression>(getRawExpression());
0377 }
0378
0379 Metadata *getRawLocation() const {
0380 return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
0381 }
0382
0383 RawLocationWrapper getWrappedLocation() const {
0384 return RawLocationWrapper(getRawLocation());
0385 }
0386
0387 Metadata *getRawVariable() const {
0388 return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
0389 }
0390
0391 Metadata *getRawExpression() const {
0392 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
0393 }
0394
0395
0396
0397
0398 void setRawLocation(Metadata *Location) {
0399 return setArgOperand(0, MetadataAsValue::get(getContext(), Location));
0400 }
0401
0402
0403
0404 std::optional<uint64_t> getFragmentSizeInBits() const;
0405
0406
0407 std::optional<DIExpression::FragmentInfo> getFragment() const {
0408 return getExpression()->getFragmentInfo();
0409 }
0410
0411
0412
0413
0414 DIExpression::FragmentInfo getFragmentOrEntireVariable() const {
0415 DIExpression::FragmentInfo VariableSlice(0, 0);
0416
0417 if (auto Sz = getFragmentSizeInBits())
0418 VariableSlice.SizeInBits = *Sz;
0419 if (auto Frag = getExpression()->getFragmentInfo())
0420 VariableSlice.OffsetInBits = Frag->OffsetInBits;
0421 return VariableSlice;
0422 }
0423
0424
0425
0426 static bool classof(const IntrinsicInst *I) {
0427 switch (I->getIntrinsicID()) {
0428 case Intrinsic::dbg_declare:
0429 case Intrinsic::dbg_value:
0430 case Intrinsic::dbg_assign:
0431 return true;
0432 default:
0433 return false;
0434 }
0435 }
0436 static bool classof(const Value *V) {
0437 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0438 }
0439
0440 protected:
0441 void setArgOperand(unsigned i, Value *v) {
0442 DbgInfoIntrinsic::setArgOperand(i, v);
0443 }
0444 void setOperand(unsigned i, Value *v) { DbgInfoIntrinsic::setOperand(i, v); }
0445 };
0446
0447
0448 class DbgDeclareInst : public DbgVariableIntrinsic {
0449 public:
0450 Value *getAddress() const {
0451 assert(getNumVariableLocationOps() == 1 &&
0452 "dbg.declare must have exactly 1 location operand.");
0453 return getVariableLocationOp(0);
0454 }
0455
0456
0457
0458 static bool classof(const IntrinsicInst *I) {
0459 return I->getIntrinsicID() == Intrinsic::dbg_declare;
0460 }
0461 static bool classof(const Value *V) {
0462 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0463 }
0464
0465 };
0466
0467
0468 class DbgValueInst : public DbgVariableIntrinsic {
0469 public:
0470
0471
0472 Value *getValue(unsigned OpIdx = 0) const {
0473 return getVariableLocationOp(OpIdx);
0474 }
0475 iterator_range<location_op_iterator> getValues() const {
0476 return location_ops();
0477 }
0478
0479
0480
0481 static bool classof(const IntrinsicInst *I) {
0482 return I->getIntrinsicID() == Intrinsic::dbg_value ||
0483 I->getIntrinsicID() == Intrinsic::dbg_assign;
0484 }
0485 static bool classof(const Value *V) {
0486 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0487 }
0488
0489 };
0490
0491
0492 class DbgAssignIntrinsic : public DbgValueInst {
0493 enum Operands {
0494 OpValue,
0495 OpVar,
0496 OpExpr,
0497 OpAssignID,
0498 OpAddress,
0499 OpAddressExpr,
0500 };
0501
0502 public:
0503 Value *getAddress() const;
0504 Metadata *getRawAddress() const {
0505 return cast<MetadataAsValue>(getArgOperand(OpAddress))->getMetadata();
0506 }
0507 Metadata *getRawAssignID() const {
0508 return cast<MetadataAsValue>(getArgOperand(OpAssignID))->getMetadata();
0509 }
0510 DIAssignID *getAssignID() const { return cast<DIAssignID>(getRawAssignID()); }
0511 Metadata *getRawAddressExpression() const {
0512 return cast<MetadataAsValue>(getArgOperand(OpAddressExpr))->getMetadata();
0513 }
0514 DIExpression *getAddressExpression() const {
0515 return cast<DIExpression>(getRawAddressExpression());
0516 }
0517 void setAddressExpression(DIExpression *NewExpr) {
0518 setArgOperand(OpAddressExpr,
0519 MetadataAsValue::get(NewExpr->getContext(), NewExpr));
0520 }
0521 void setAssignId(DIAssignID *New);
0522 void setAddress(Value *V);
0523
0524 void setKillAddress();
0525
0526
0527
0528
0529 bool isKillAddress() const;
0530 void setValue(Value *V);
0531
0532
0533 static bool classof(const IntrinsicInst *I) {
0534 return I->getIntrinsicID() == Intrinsic::dbg_assign;
0535 }
0536 static bool classof(const Value *V) {
0537 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0538 }
0539
0540 };
0541
0542
0543 class DbgLabelInst : public DbgInfoIntrinsic {
0544 public:
0545 DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); }
0546 void setLabel(DILabel *NewLabel) {
0547 setArgOperand(0, MetadataAsValue::get(getContext(), NewLabel));
0548 }
0549
0550 Metadata *getRawLabel() const {
0551 return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
0552 }
0553
0554
0555
0556 static bool classof(const IntrinsicInst *I) {
0557 return I->getIntrinsicID() == Intrinsic::dbg_label;
0558 }
0559 static bool classof(const Value *V) {
0560 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0561 }
0562
0563 };
0564
0565
0566 class VPIntrinsic : public IntrinsicInst {
0567 public:
0568
0569
0570
0571 static Function *getOrInsertDeclarationForParams(Module *M, Intrinsic::ID,
0572 Type *ReturnType,
0573 ArrayRef<Value *> Params);
0574
0575 static std::optional<unsigned> getMaskParamPos(Intrinsic::ID IntrinsicID);
0576 static std::optional<unsigned> getVectorLengthParamPos(
0577 Intrinsic::ID IntrinsicID);
0578
0579
0580 static Intrinsic::ID getForOpcode(unsigned OC);
0581
0582
0583
0584 static Intrinsic::ID getForIntrinsic(Intrinsic::ID Id);
0585
0586
0587 static bool isVPIntrinsic(Intrinsic::ID);
0588
0589
0590 Value *getMaskParam() const;
0591 void setMaskParam(Value *);
0592
0593
0594 Value *getVectorLengthParam() const;
0595 void setVectorLengthParam(Value *);
0596
0597
0598 bool canIgnoreVectorLengthParam() const;
0599
0600
0601
0602 ElementCount getStaticVectorLength() const;
0603
0604
0605
0606 MaybeAlign getPointerAlignment() const;
0607
0608
0609
0610 Value *getMemoryPointerParam() const;
0611 static std::optional<unsigned> getMemoryPointerParamPos(Intrinsic::ID);
0612
0613
0614 Value *getMemoryDataParam() const;
0615 static std::optional<unsigned> getMemoryDataParamPos(Intrinsic::ID);
0616
0617
0618 static bool classof(const IntrinsicInst *I) {
0619 return isVPIntrinsic(I->getIntrinsicID());
0620 }
0621 static bool classof(const Value *V) {
0622 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0623 }
0624
0625
0626 std::optional<unsigned> getFunctionalOpcode() const {
0627 return getFunctionalOpcodeForVP(getIntrinsicID());
0628 }
0629
0630
0631 std::optional<unsigned> getFunctionalIntrinsicID() const {
0632 return getFunctionalIntrinsicIDForVP(getIntrinsicID());
0633 }
0634
0635
0636 std::optional<unsigned> getConstrainedIntrinsicID() const {
0637 return getConstrainedIntrinsicIDForVP(getIntrinsicID());
0638 }
0639
0640
0641 static std::optional<unsigned> getFunctionalOpcodeForVP(Intrinsic::ID ID);
0642
0643
0644 static std::optional<Intrinsic::ID>
0645 getFunctionalIntrinsicIDForVP(Intrinsic::ID ID);
0646
0647
0648 static std::optional<Intrinsic::ID>
0649 getConstrainedIntrinsicIDForVP(Intrinsic::ID ID);
0650 };
0651
0652
0653 class VPReductionIntrinsic : public VPIntrinsic {
0654 public:
0655 static bool isVPReduction(Intrinsic::ID ID);
0656
0657 unsigned getStartParamPos() const;
0658 unsigned getVectorParamPos() const;
0659
0660 static std::optional<unsigned> getStartParamPos(Intrinsic::ID ID);
0661 static std::optional<unsigned> getVectorParamPos(Intrinsic::ID ID);
0662
0663
0664
0665 static bool classof(const IntrinsicInst *I) {
0666 return VPReductionIntrinsic::isVPReduction(I->getIntrinsicID());
0667 }
0668 static bool classof(const Value *V) {
0669 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0670 }
0671
0672 };
0673
0674 class VPCastIntrinsic : public VPIntrinsic {
0675 public:
0676 static bool isVPCast(Intrinsic::ID ID);
0677
0678
0679
0680 static bool classof(const IntrinsicInst *I) {
0681 return VPCastIntrinsic::isVPCast(I->getIntrinsicID());
0682 }
0683 static bool classof(const Value *V) {
0684 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0685 }
0686
0687 };
0688
0689 class VPCmpIntrinsic : public VPIntrinsic {
0690 public:
0691 static bool isVPCmp(Intrinsic::ID ID);
0692
0693 CmpInst::Predicate getPredicate() const;
0694
0695
0696
0697 static bool classof(const IntrinsicInst *I) {
0698 return VPCmpIntrinsic::isVPCmp(I->getIntrinsicID());
0699 }
0700 static bool classof(const Value *V) {
0701 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0702 }
0703
0704 };
0705
0706 class VPBinOpIntrinsic : public VPIntrinsic {
0707 public:
0708 static bool isVPBinOp(Intrinsic::ID ID);
0709
0710
0711
0712 static bool classof(const IntrinsicInst *I) {
0713 return VPBinOpIntrinsic::isVPBinOp(I->getIntrinsicID());
0714 }
0715 static bool classof(const Value *V) {
0716 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0717 }
0718
0719 };
0720
0721
0722
0723 class ConstrainedFPIntrinsic : public IntrinsicInst {
0724 public:
0725 unsigned getNonMetadataArgCount() const;
0726 std::optional<RoundingMode> getRoundingMode() const;
0727 std::optional<fp::ExceptionBehavior> getExceptionBehavior() const;
0728 bool isDefaultFPEnvironment() const;
0729
0730
0731 static bool classof(const IntrinsicInst *I);
0732 static bool classof(const Value *V) {
0733 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0734 }
0735 };
0736
0737
0738 class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
0739 public:
0740 FCmpInst::Predicate getPredicate() const;
0741 bool isSignaling() const {
0742 return getIntrinsicID() == Intrinsic::experimental_constrained_fcmps;
0743 }
0744
0745
0746 static bool classof(const IntrinsicInst *I) {
0747 switch (I->getIntrinsicID()) {
0748 case Intrinsic::experimental_constrained_fcmp:
0749 case Intrinsic::experimental_constrained_fcmps:
0750 return true;
0751 default:
0752 return false;
0753 }
0754 }
0755 static bool classof(const Value *V) {
0756 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0757 }
0758 };
0759
0760
0761 class MinMaxIntrinsic : public IntrinsicInst {
0762 public:
0763 static bool classof(const IntrinsicInst *I) {
0764 switch (I->getIntrinsicID()) {
0765 case Intrinsic::umin:
0766 case Intrinsic::umax:
0767 case Intrinsic::smin:
0768 case Intrinsic::smax:
0769 return true;
0770 default:
0771 return false;
0772 }
0773 }
0774 static bool classof(const Value *V) {
0775 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0776 }
0777
0778 Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
0779 Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); }
0780
0781
0782 static ICmpInst::Predicate getPredicate(Intrinsic::ID ID) {
0783 switch (ID) {
0784 case Intrinsic::umin:
0785 return ICmpInst::Predicate::ICMP_ULT;
0786 case Intrinsic::umax:
0787 return ICmpInst::Predicate::ICMP_UGT;
0788 case Intrinsic::smin:
0789 return ICmpInst::Predicate::ICMP_SLT;
0790 case Intrinsic::smax:
0791 return ICmpInst::Predicate::ICMP_SGT;
0792 default:
0793 llvm_unreachable("Invalid intrinsic");
0794 }
0795 }
0796
0797
0798 ICmpInst::Predicate getPredicate() const {
0799 return getPredicate(getIntrinsicID());
0800 }
0801
0802
0803 static bool isSigned(Intrinsic::ID ID) {
0804 return ICmpInst::isSigned(getPredicate(ID));
0805 };
0806
0807
0808 bool isSigned() const { return isSigned(getIntrinsicID()); };
0809
0810
0811
0812
0813 static APInt getSaturationPoint(Intrinsic::ID ID, unsigned numBits) {
0814 switch (ID) {
0815 case Intrinsic::umin:
0816 return APInt::getMinValue(numBits);
0817 case Intrinsic::umax:
0818 return APInt::getMaxValue(numBits);
0819 case Intrinsic::smin:
0820 return APInt::getSignedMinValue(numBits);
0821 case Intrinsic::smax:
0822 return APInt::getSignedMaxValue(numBits);
0823 default:
0824 llvm_unreachable("Invalid intrinsic");
0825 }
0826 }
0827
0828
0829
0830
0831 APInt getSaturationPoint(unsigned numBits) const {
0832 return getSaturationPoint(getIntrinsicID(), numBits);
0833 }
0834
0835
0836
0837
0838 static Constant *getSaturationPoint(Intrinsic::ID ID, Type *Ty) {
0839 return Constant::getIntegerValue(
0840 Ty, getSaturationPoint(ID, Ty->getScalarSizeInBits()));
0841 }
0842
0843
0844
0845
0846 Constant *getSaturationPoint(Type *Ty) const {
0847 return getSaturationPoint(getIntrinsicID(), Ty);
0848 }
0849 };
0850
0851
0852 class CmpIntrinsic : public IntrinsicInst {
0853 public:
0854 static bool classof(const IntrinsicInst *I) {
0855 switch (I->getIntrinsicID()) {
0856 case Intrinsic::scmp:
0857 case Intrinsic::ucmp:
0858 return true;
0859 default:
0860 return false;
0861 }
0862 }
0863 static bool classof(const Value *V) {
0864 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0865 }
0866
0867 Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
0868 Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); }
0869
0870 static bool isSigned(Intrinsic::ID ID) { return ID == Intrinsic::scmp; }
0871 bool isSigned() const { return isSigned(getIntrinsicID()); }
0872
0873 static CmpInst::Predicate getGTPredicate(Intrinsic::ID ID) {
0874 return isSigned(ID) ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
0875 }
0876 CmpInst::Predicate getGTPredicate() const {
0877 return getGTPredicate(getIntrinsicID());
0878 }
0879
0880 static CmpInst::Predicate getLTPredicate(Intrinsic::ID ID) {
0881 return isSigned(ID) ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
0882 }
0883 CmpInst::Predicate getLTPredicate() const {
0884 return getLTPredicate(getIntrinsicID());
0885 }
0886 };
0887
0888
0889
0890 class BinaryOpIntrinsic : public IntrinsicInst {
0891 public:
0892 static bool classof(const IntrinsicInst *I) {
0893 switch (I->getIntrinsicID()) {
0894 case Intrinsic::uadd_with_overflow:
0895 case Intrinsic::sadd_with_overflow:
0896 case Intrinsic::usub_with_overflow:
0897 case Intrinsic::ssub_with_overflow:
0898 case Intrinsic::umul_with_overflow:
0899 case Intrinsic::smul_with_overflow:
0900 case Intrinsic::uadd_sat:
0901 case Intrinsic::sadd_sat:
0902 case Intrinsic::usub_sat:
0903 case Intrinsic::ssub_sat:
0904 return true;
0905 default:
0906 return false;
0907 }
0908 }
0909 static bool classof(const Value *V) {
0910 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0911 }
0912
0913 Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
0914 Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); }
0915
0916
0917 Instruction::BinaryOps getBinaryOp() const;
0918
0919
0920 bool isSigned() const;
0921
0922
0923 unsigned getNoWrapKind() const;
0924 };
0925
0926
0927 class WithOverflowInst : public BinaryOpIntrinsic {
0928 public:
0929 static bool classof(const IntrinsicInst *I) {
0930 switch (I->getIntrinsicID()) {
0931 case Intrinsic::uadd_with_overflow:
0932 case Intrinsic::sadd_with_overflow:
0933 case Intrinsic::usub_with_overflow:
0934 case Intrinsic::ssub_with_overflow:
0935 case Intrinsic::umul_with_overflow:
0936 case Intrinsic::smul_with_overflow:
0937 return true;
0938 default:
0939 return false;
0940 }
0941 }
0942 static bool classof(const Value *V) {
0943 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0944 }
0945 };
0946
0947
0948 class SaturatingInst : public BinaryOpIntrinsic {
0949 public:
0950 static bool classof(const IntrinsicInst *I) {
0951 switch (I->getIntrinsicID()) {
0952 case Intrinsic::uadd_sat:
0953 case Intrinsic::sadd_sat:
0954 case Intrinsic::usub_sat:
0955 case Intrinsic::ssub_sat:
0956 return true;
0957 default:
0958 return false;
0959 }
0960 }
0961 static bool classof(const Value *V) {
0962 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0963 }
0964 };
0965
0966
0967
0968
0969
0970 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
0971 private:
0972 enum { ARG_DEST = 0, ARG_LENGTH = 2 };
0973
0974 public:
0975 Value *getRawDest() const {
0976 return const_cast<Value *>(getArgOperand(ARG_DEST));
0977 }
0978 const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
0979 Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
0980
0981 Value *getLength() const {
0982 return const_cast<Value *>(getArgOperand(ARG_LENGTH));
0983 }
0984 const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
0985 Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
0986
0987
0988
0989
0990 Value *getDest() const { return getRawDest()->stripPointerCasts(); }
0991
0992 unsigned getDestAddressSpace() const {
0993 return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
0994 }
0995
0996
0997
0998 LLVM_DEPRECATED("Use getDestAlign() instead", "getDestAlign")
0999 unsigned getDestAlignment() const {
1000 if (auto MA = getParamAlign(ARG_DEST))
1001 return MA->value();
1002 return 0;
1003 }
1004 MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); }
1005
1006
1007 void setDest(Value *Ptr) {
1008 assert(getRawDest()->getType() == Ptr->getType() &&
1009 "setDest called with pointer of wrong type!");
1010 setArgOperand(ARG_DEST, Ptr);
1011 }
1012
1013 void setDestAlignment(MaybeAlign Alignment) {
1014 removeParamAttr(ARG_DEST, Attribute::Alignment);
1015 if (Alignment)
1016 addParamAttr(ARG_DEST,
1017 Attribute::getWithAlignment(getContext(), *Alignment));
1018 }
1019 void setDestAlignment(Align Alignment) {
1020 removeParamAttr(ARG_DEST, Attribute::Alignment);
1021 addParamAttr(ARG_DEST,
1022 Attribute::getWithAlignment(getContext(), Alignment));
1023 }
1024
1025 void setLength(Value *L) {
1026 assert(getLength()->getType() == L->getType() &&
1027 "setLength called with value of wrong type!");
1028 setArgOperand(ARG_LENGTH, L);
1029 }
1030 };
1031
1032
1033
1034 template <class BaseCL> class MemTransferBase : public BaseCL {
1035 private:
1036 enum { ARG_SOURCE = 1 };
1037
1038 public:
1039
1040 Value *getRawSource() const {
1041 return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
1042 }
1043 const Use &getRawSourceUse() const {
1044 return BaseCL::getArgOperandUse(ARG_SOURCE);
1045 }
1046 Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
1047
1048
1049
1050
1051 Value *getSource() const { return getRawSource()->stripPointerCasts(); }
1052
1053 unsigned getSourceAddressSpace() const {
1054 return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
1055 }
1056
1057
1058
1059 LLVM_DEPRECATED("Use getSourceAlign() instead", "getSourceAlign")
1060 unsigned getSourceAlignment() const {
1061 if (auto MA = BaseCL::getParamAlign(ARG_SOURCE))
1062 return MA->value();
1063 return 0;
1064 }
1065
1066 MaybeAlign getSourceAlign() const {
1067 return BaseCL::getParamAlign(ARG_SOURCE);
1068 }
1069
1070 void setSource(Value *Ptr) {
1071 assert(getRawSource()->getType() == Ptr->getType() &&
1072 "setSource called with pointer of wrong type!");
1073 BaseCL::setArgOperand(ARG_SOURCE, Ptr);
1074 }
1075
1076 void setSourceAlignment(MaybeAlign Alignment) {
1077 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
1078 if (Alignment)
1079 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
1080 BaseCL::getContext(), *Alignment));
1081 }
1082
1083 void setSourceAlignment(Align Alignment) {
1084 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
1085 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
1086 BaseCL::getContext(), Alignment));
1087 }
1088 };
1089
1090
1091
1092 template <class BaseCL> class MemSetBase : public BaseCL {
1093 private:
1094 enum { ARG_VALUE = 1 };
1095
1096 public:
1097 Value *getValue() const {
1098 return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
1099 }
1100 const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); }
1101 Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
1102
1103 void setValue(Value *Val) {
1104 assert(getValue()->getType() == Val->getType() &&
1105 "setValue called with value of wrong type!");
1106 BaseCL::setArgOperand(ARG_VALUE, Val);
1107 }
1108 };
1109
1110
1111
1112 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
1113 private:
1114 enum { ARG_ELEMENTSIZE = 3 };
1115
1116 public:
1117 Value *getRawElementSizeInBytes() const {
1118 return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
1119 }
1120
1121 ConstantInt *getElementSizeInBytesCst() const {
1122 return cast<ConstantInt>(getRawElementSizeInBytes());
1123 }
1124
1125 uint32_t getElementSizeInBytes() const {
1126 return getElementSizeInBytesCst()->getZExtValue();
1127 }
1128
1129 void setElementSizeInBytes(Constant *V) {
1130 assert(V->getType() == Type::getInt8Ty(getContext()) &&
1131 "setElementSizeInBytes called with value of wrong type!");
1132 setArgOperand(ARG_ELEMENTSIZE, V);
1133 }
1134
1135 static bool classof(const IntrinsicInst *I) {
1136 switch (I->getIntrinsicID()) {
1137 case Intrinsic::memcpy_element_unordered_atomic:
1138 case Intrinsic::memmove_element_unordered_atomic:
1139 case Intrinsic::memset_element_unordered_atomic:
1140 return true;
1141 default:
1142 return false;
1143 }
1144 }
1145 static bool classof(const Value *V) {
1146 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1147 }
1148 };
1149
1150
1151
1152 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
1153 public:
1154 static bool classof(const IntrinsicInst *I) {
1155 return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
1156 }
1157 static bool classof(const Value *V) {
1158 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1159 }
1160 };
1161
1162
1163
1164 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
1165 public:
1166 static bool classof(const IntrinsicInst *I) {
1167 switch (I->getIntrinsicID()) {
1168 case Intrinsic::memcpy_element_unordered_atomic:
1169 case Intrinsic::memmove_element_unordered_atomic:
1170 return true;
1171 default:
1172 return false;
1173 }
1174 }
1175 static bool classof(const Value *V) {
1176 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1177 }
1178 };
1179
1180
1181
1182 class AtomicMemCpyInst : public AtomicMemTransferInst {
1183 public:
1184 static bool classof(const IntrinsicInst *I) {
1185 return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
1186 }
1187 static bool classof(const Value *V) {
1188 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1189 }
1190 };
1191
1192
1193
1194 class AtomicMemMoveInst : public AtomicMemTransferInst {
1195 public:
1196 static bool classof(const IntrinsicInst *I) {
1197 return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
1198 }
1199 static bool classof(const Value *V) {
1200 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1201 }
1202 };
1203
1204
1205 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
1206 private:
1207 enum { ARG_VOLATILE = 3 };
1208
1209 public:
1210 ConstantInt *getVolatileCst() const {
1211 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
1212 }
1213
1214 bool isVolatile() const { return !getVolatileCst()->isZero(); }
1215
1216 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
1217
1218
1219 static bool classof(const IntrinsicInst *I) {
1220 switch (I->getIntrinsicID()) {
1221 case Intrinsic::memcpy:
1222 case Intrinsic::memmove:
1223 case Intrinsic::memset:
1224 case Intrinsic::memset_inline:
1225 case Intrinsic::memcpy_inline:
1226 return true;
1227 default:
1228 return false;
1229 }
1230 }
1231 static bool classof(const Value *V) {
1232 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1233 }
1234 };
1235
1236
1237 class MemSetInst : public MemSetBase<MemIntrinsic> {
1238 public:
1239
1240 static bool classof(const IntrinsicInst *I) {
1241 switch (I->getIntrinsicID()) {
1242 case Intrinsic::memset:
1243 case Intrinsic::memset_inline:
1244 return true;
1245 default:
1246 return false;
1247 }
1248 }
1249 static bool classof(const Value *V) {
1250 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1251 }
1252 };
1253
1254
1255 class MemSetInlineInst : public MemSetInst {
1256 public:
1257
1258 static bool classof(const IntrinsicInst *I) {
1259 return I->getIntrinsicID() == Intrinsic::memset_inline;
1260 }
1261 static bool classof(const Value *V) {
1262 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1263 }
1264 };
1265
1266
1267 class MemSetPatternIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
1268 private:
1269 enum { ARG_VOLATILE = 3 };
1270
1271 public:
1272 ConstantInt *getVolatileCst() const {
1273 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
1274 }
1275
1276 bool isVolatile() const { return !getVolatileCst()->isZero(); }
1277
1278 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
1279
1280
1281 static bool classof(const IntrinsicInst *I) {
1282 return I->getIntrinsicID() == Intrinsic::experimental_memset_pattern;
1283 }
1284 static bool classof(const Value *V) {
1285 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1286 }
1287 };
1288
1289
1290 class MemSetPatternInst : public MemSetBase<MemSetPatternIntrinsic> {
1291 public:
1292
1293 static bool classof(const IntrinsicInst *I) {
1294 return I->getIntrinsicID() == Intrinsic::experimental_memset_pattern;
1295 }
1296 static bool classof(const Value *V) {
1297 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1298 }
1299 };
1300
1301
1302 class MemTransferInst : public MemTransferBase<MemIntrinsic> {
1303 public:
1304
1305 static bool classof(const IntrinsicInst *I) {
1306 switch (I->getIntrinsicID()) {
1307 case Intrinsic::memcpy:
1308 case Intrinsic::memmove:
1309 case Intrinsic::memcpy_inline:
1310 return true;
1311 default:
1312 return false;
1313 }
1314 }
1315 static bool classof(const Value *V) {
1316 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1317 }
1318 };
1319
1320
1321 class MemCpyInst : public MemTransferInst {
1322 public:
1323
1324 static bool classof(const IntrinsicInst *I) {
1325 return I->getIntrinsicID() == Intrinsic::memcpy ||
1326 I->getIntrinsicID() == Intrinsic::memcpy_inline;
1327 }
1328 static bool classof(const Value *V) {
1329 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1330 }
1331 };
1332
1333
1334 class MemMoveInst : public MemTransferInst {
1335 public:
1336
1337 static bool classof(const IntrinsicInst *I) {
1338 return I->getIntrinsicID() == Intrinsic::memmove;
1339 }
1340 static bool classof(const Value *V) {
1341 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1342 }
1343 };
1344
1345
1346 class MemCpyInlineInst : public MemCpyInst {
1347 public:
1348
1349 static bool classof(const IntrinsicInst *I) {
1350 return I->getIntrinsicID() == Intrinsic::memcpy_inline;
1351 }
1352 static bool classof(const Value *V) {
1353 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1354 }
1355 };
1356
1357
1358
1359
1360
1361 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
1362 public:
1363 bool isVolatile() const {
1364
1365 if (auto *MI = dyn_cast<MemIntrinsic>(this))
1366 return MI->isVolatile();
1367 return false;
1368 }
1369
1370 static bool classof(const IntrinsicInst *I) {
1371 switch (I->getIntrinsicID()) {
1372 case Intrinsic::memcpy:
1373 case Intrinsic::memcpy_inline:
1374 case Intrinsic::memmove:
1375 case Intrinsic::memset:
1376 case Intrinsic::memset_inline:
1377 case Intrinsic::memcpy_element_unordered_atomic:
1378 case Intrinsic::memmove_element_unordered_atomic:
1379 case Intrinsic::memset_element_unordered_atomic:
1380 return true;
1381 default:
1382 return false;
1383 }
1384 }
1385 static bool classof(const Value *V) {
1386 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1387 }
1388 };
1389
1390
1391
1392
1393 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
1394 public:
1395 static bool classof(const IntrinsicInst *I) {
1396 switch (I->getIntrinsicID()) {
1397 case Intrinsic::memset:
1398 case Intrinsic::memset_inline:
1399 case Intrinsic::memset_element_unordered_atomic:
1400 return true;
1401 default:
1402 return false;
1403 }
1404 }
1405 static bool classof(const Value *V) {
1406 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1407 }
1408 };
1409
1410
1411
1412
1413 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
1414 public:
1415 static bool classof(const IntrinsicInst *I) {
1416 switch (I->getIntrinsicID()) {
1417 case Intrinsic::memcpy:
1418 case Intrinsic::memcpy_inline:
1419 case Intrinsic::memmove:
1420 case Intrinsic::memcpy_element_unordered_atomic:
1421 case Intrinsic::memmove_element_unordered_atomic:
1422 return true;
1423 default:
1424 return false;
1425 }
1426 }
1427 static bool classof(const Value *V) {
1428 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1429 }
1430 };
1431
1432
1433
1434
1435 class AnyMemCpyInst : public AnyMemTransferInst {
1436 public:
1437 static bool classof(const IntrinsicInst *I) {
1438 switch (I->getIntrinsicID()) {
1439 case Intrinsic::memcpy:
1440 case Intrinsic::memcpy_inline:
1441 case Intrinsic::memcpy_element_unordered_atomic:
1442 return true;
1443 default:
1444 return false;
1445 }
1446 }
1447 static bool classof(const Value *V) {
1448 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1449 }
1450 };
1451
1452
1453
1454
1455 class AnyMemMoveInst : public AnyMemTransferInst {
1456 public:
1457 static bool classof(const IntrinsicInst *I) {
1458 switch (I->getIntrinsicID()) {
1459 case Intrinsic::memmove:
1460 case Intrinsic::memmove_element_unordered_atomic:
1461 return true;
1462 default:
1463 return false;
1464 }
1465 }
1466 static bool classof(const Value *V) {
1467 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1468 }
1469 };
1470
1471
1472 class VAStartInst : public IntrinsicInst {
1473 public:
1474 static bool classof(const IntrinsicInst *I) {
1475 return I->getIntrinsicID() == Intrinsic::vastart;
1476 }
1477 static bool classof(const Value *V) {
1478 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1479 }
1480
1481 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
1482 };
1483
1484
1485 class VAEndInst : public IntrinsicInst {
1486 public:
1487 static bool classof(const IntrinsicInst *I) {
1488 return I->getIntrinsicID() == Intrinsic::vaend;
1489 }
1490 static bool classof(const Value *V) {
1491 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1492 }
1493
1494 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
1495 };
1496
1497
1498 class VACopyInst : public IntrinsicInst {
1499 public:
1500 static bool classof(const IntrinsicInst *I) {
1501 return I->getIntrinsicID() == Intrinsic::vacopy;
1502 }
1503 static bool classof(const Value *V) {
1504 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1505 }
1506
1507 Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); }
1508 Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); }
1509 };
1510
1511
1512 class InstrProfInstBase : public IntrinsicInst {
1513 protected:
1514 static bool isCounterBase(const IntrinsicInst &I) {
1515 switch (I.getIntrinsicID()) {
1516 case Intrinsic::instrprof_cover:
1517 case Intrinsic::instrprof_increment:
1518 case Intrinsic::instrprof_increment_step:
1519 case Intrinsic::instrprof_callsite:
1520 case Intrinsic::instrprof_timestamp:
1521 case Intrinsic::instrprof_value_profile:
1522 return true;
1523 }
1524 return false;
1525 }
1526 static bool isMCDCBitmapBase(const IntrinsicInst &I) {
1527 switch (I.getIntrinsicID()) {
1528 case Intrinsic::instrprof_mcdc_parameters:
1529 case Intrinsic::instrprof_mcdc_tvbitmap_update:
1530 return true;
1531 }
1532 return false;
1533 }
1534
1535 public:
1536 static bool classof(const Value *V) {
1537 if (const auto *Instr = dyn_cast<IntrinsicInst>(V))
1538 return isCounterBase(*Instr) || isMCDCBitmapBase(*Instr);
1539 return false;
1540 }
1541
1542
1543 GlobalVariable *getName() const {
1544 return cast<GlobalVariable>(getNameValue());
1545 }
1546
1547
1548
1549
1550 Value *getNameValue() const {
1551 return const_cast<Value *>(getArgOperand(0))->stripPointerCasts();
1552 }
1553
1554 void setNameValue(Value *V) { setArgOperand(0, V); }
1555
1556
1557 ConstantInt *getHash() const {
1558 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
1559 }
1560 };
1561
1562
1563 class InstrProfCntrInstBase : public InstrProfInstBase {
1564 public:
1565 static bool classof(const Value *V) {
1566 if (const auto *Instr = dyn_cast<IntrinsicInst>(V))
1567 return InstrProfInstBase::isCounterBase(*Instr);
1568 return false;
1569 }
1570
1571
1572 ConstantInt *getNumCounters() const;
1573
1574 ConstantInt *getIndex() const;
1575 void setIndex(uint32_t Idx);
1576 };
1577
1578
1579 class InstrProfCoverInst : public InstrProfCntrInstBase {
1580 public:
1581 static bool classof(const IntrinsicInst *I) {
1582 return I->getIntrinsicID() == Intrinsic::instrprof_cover;
1583 }
1584 static bool classof(const Value *V) {
1585 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1586 }
1587 };
1588
1589
1590 class InstrProfIncrementInst : public InstrProfCntrInstBase {
1591 public:
1592 static bool classof(const IntrinsicInst *I) {
1593 return I->getIntrinsicID() == Intrinsic::instrprof_increment ||
1594 I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
1595 }
1596 static bool classof(const Value *V) {
1597 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1598 }
1599 Value *getStep() const;
1600 };
1601
1602
1603 class InstrProfIncrementInstStep : public InstrProfIncrementInst {
1604 public:
1605 static bool classof(const IntrinsicInst *I) {
1606 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
1607 }
1608 static bool classof(const Value *V) {
1609 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1610 }
1611 };
1612
1613
1614
1615
1616
1617 class InstrProfCallsite : public InstrProfCntrInstBase {
1618 public:
1619 static bool classof(const IntrinsicInst *I) {
1620 return I->getIntrinsicID() == Intrinsic::instrprof_callsite;
1621 }
1622 static bool classof(const Value *V) {
1623 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1624 }
1625
1626 static bool canInstrumentCallsite(const CallBase &CB) {
1627 return !CB.isInlineAsm() &&
1628 (CB.isIndirectCall() ||
1629 (CB.getCalledFunction() && !CB.getCalledFunction()->isIntrinsic()));
1630 }
1631 Value *getCallee() const;
1632 void setCallee(Value *Callee);
1633 };
1634
1635
1636 class InstrProfTimestampInst : public InstrProfCntrInstBase {
1637 public:
1638 static bool classof(const IntrinsicInst *I) {
1639 return I->getIntrinsicID() == Intrinsic::instrprof_timestamp;
1640 }
1641 static bool classof(const Value *V) {
1642 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1643 }
1644 };
1645
1646
1647 class InstrProfValueProfileInst : public InstrProfCntrInstBase {
1648 public:
1649 static bool classof(const IntrinsicInst *I) {
1650 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
1651 }
1652 static bool classof(const Value *V) {
1653 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1654 }
1655
1656 Value *getTargetValue() const {
1657 return cast<Value>(const_cast<Value *>(getArgOperand(2)));
1658 }
1659
1660 ConstantInt *getValueKind() const {
1661 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
1662 }
1663
1664
1665 ConstantInt *getIndex() const {
1666 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
1667 }
1668 };
1669
1670
1671 class InstrProfMCDCBitmapInstBase : public InstrProfInstBase {
1672 public:
1673 static bool classof(const IntrinsicInst *I) {
1674 return InstrProfInstBase::isMCDCBitmapBase(*I);
1675 }
1676 static bool classof(const Value *V) {
1677 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1678 }
1679
1680
1681
1682 ConstantInt *getNumBitmapBits() const {
1683 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
1684 }
1685
1686
1687
1688 auto getNumBitmapBytes() const {
1689 return alignTo(getNumBitmapBits()->getZExtValue(), CHAR_BIT) / CHAR_BIT;
1690 }
1691 };
1692
1693
1694 class InstrProfMCDCBitmapParameters : public InstrProfMCDCBitmapInstBase {
1695 public:
1696 static bool classof(const IntrinsicInst *I) {
1697 return I->getIntrinsicID() == Intrinsic::instrprof_mcdc_parameters;
1698 }
1699 static bool classof(const Value *V) {
1700 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1701 }
1702 };
1703
1704
1705 class InstrProfMCDCTVBitmapUpdate : public InstrProfMCDCBitmapInstBase {
1706 public:
1707 static bool classof(const IntrinsicInst *I) {
1708 return I->getIntrinsicID() == Intrinsic::instrprof_mcdc_tvbitmap_update;
1709 }
1710 static bool classof(const Value *V) {
1711 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1712 }
1713
1714
1715
1716 ConstantInt *getBitmapIndex() const {
1717 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
1718 }
1719
1720
1721
1722 Value *getMCDCCondBitmapAddr() const {
1723 return cast<Value>(const_cast<Value *>(getArgOperand(3)));
1724 }
1725 };
1726
1727 class PseudoProbeInst : public IntrinsicInst {
1728 public:
1729 static bool classof(const IntrinsicInst *I) {
1730 return I->getIntrinsicID() == Intrinsic::pseudoprobe;
1731 }
1732
1733 static bool classof(const Value *V) {
1734 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1735 }
1736
1737 ConstantInt *getFuncGuid() const {
1738 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0)));
1739 }
1740
1741 ConstantInt *getIndex() const {
1742 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
1743 }
1744
1745 ConstantInt *getAttributes() const {
1746 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
1747 }
1748
1749 ConstantInt *getFactor() const {
1750 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
1751 }
1752 };
1753
1754 class NoAliasScopeDeclInst : public IntrinsicInst {
1755 public:
1756 static bool classof(const IntrinsicInst *I) {
1757 return I->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl;
1758 }
1759
1760 static bool classof(const Value *V) {
1761 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1762 }
1763
1764 MDNode *getScopeList() const {
1765 auto *MV =
1766 cast<MetadataAsValue>(getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
1767 return cast<MDNode>(MV->getMetadata());
1768 }
1769
1770 void setScopeList(MDNode *ScopeList) {
1771 setOperand(Intrinsic::NoAliasScopeDeclScopeArg,
1772 MetadataAsValue::get(getContext(), ScopeList));
1773 }
1774 };
1775
1776
1777
1778 class GCProjectionInst : public IntrinsicInst {
1779 public:
1780 static bool classof(const IntrinsicInst *I) {
1781 return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate ||
1782 I->getIntrinsicID() == Intrinsic::experimental_gc_result;
1783 }
1784
1785 static bool classof(const Value *V) {
1786 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1787 }
1788
1789
1790
1791 bool isTiedToInvoke() const {
1792 const Value *Token = getArgOperand(0);
1793
1794 return isa<LandingPadInst>(Token) || isa<InvokeInst>(Token);
1795 }
1796
1797
1798 const Value *getStatepoint() const;
1799 };
1800
1801
1802 class GCRelocateInst : public GCProjectionInst {
1803 public:
1804 static bool classof(const IntrinsicInst *I) {
1805 return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
1806 }
1807
1808 static bool classof(const Value *V) {
1809 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1810 }
1811
1812
1813
1814
1815 unsigned getBasePtrIndex() const {
1816 return cast<ConstantInt>(getArgOperand(1))->getZExtValue();
1817 }
1818
1819
1820
1821 unsigned getDerivedPtrIndex() const {
1822 return cast<ConstantInt>(getArgOperand(2))->getZExtValue();
1823 }
1824
1825 Value *getBasePtr() const;
1826 Value *getDerivedPtr() const;
1827 };
1828
1829
1830 class GCResultInst : public GCProjectionInst {
1831 public:
1832 static bool classof(const IntrinsicInst *I) {
1833 return I->getIntrinsicID() == Intrinsic::experimental_gc_result;
1834 }
1835
1836 static bool classof(const Value *V) {
1837 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1838 }
1839 };
1840
1841
1842
1843 class AssumeInst : public IntrinsicInst {
1844 public:
1845 static bool classof(const IntrinsicInst *I) {
1846 return I->getIntrinsicID() == Intrinsic::assume;
1847 }
1848 static bool classof(const Value *V) {
1849 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1850 }
1851 };
1852
1853
1854 static inline bool isConvergenceControlIntrinsic(unsigned IntrinsicID) {
1855 switch (IntrinsicID) {
1856 default:
1857 return false;
1858 case Intrinsic::experimental_convergence_anchor:
1859 case Intrinsic::experimental_convergence_entry:
1860 case Intrinsic::experimental_convergence_loop:
1861 return true;
1862 }
1863 }
1864
1865
1866 class ConvergenceControlInst : public IntrinsicInst {
1867 public:
1868 static bool classof(const IntrinsicInst *I) {
1869 return isConvergenceControlIntrinsic(I->getIntrinsicID());
1870 }
1871
1872 static bool classof(const Value *V) {
1873 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1874 }
1875
1876 bool isAnchor() const {
1877 return getIntrinsicID() == Intrinsic::experimental_convergence_anchor;
1878 }
1879 bool isEntry() const {
1880 return getIntrinsicID() == Intrinsic::experimental_convergence_entry;
1881 }
1882 bool isLoop() const {
1883 return getIntrinsicID() == Intrinsic::experimental_convergence_loop;
1884 }
1885 };
1886
1887 }
1888
1889 #endif