- //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file defines classes that make it really easy to deal with intrinsic 
- // functions with the isa/dyncast family of functions.  In particular, this 
- // allows you to do things like: 
- // 
- //     if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) 
- //        ... MCI->getDest() ... MCI->getSource() ... 
- // 
- // All intrinsic function calls are instances of the call instruction, so these 
- // are all subclasses of the CallInst class.  Note that none of these classes 
- // has state or virtual methods, which is an important part of this gross/neat 
- // hack working. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_IR_INTRINSICINST_H 
- #define LLVM_IR_INTRINSICINST_H 
-   
- #include "llvm/IR/Constants.h" 
- #include "llvm/IR/DebugInfoMetadata.h" 
- #include "llvm/IR/DerivedTypes.h" 
- #include "llvm/IR/FPEnv.h" 
- #include "llvm/IR/Function.h" 
- #include "llvm/IR/GlobalVariable.h" 
- #include "llvm/IR/Instructions.h" 
- #include "llvm/IR/Intrinsics.h" 
- #include "llvm/IR/Value.h" 
- #include "llvm/Support/Casting.h" 
- #include <cassert> 
- #include <cstdint> 
- #include <optional> 
-   
- namespace llvm { 
-   
- class Metadata; 
-   
- /// A wrapper class for inspecting calls to intrinsic functions. 
- /// This allows the standard isa/dyncast/cast functionality to work with calls 
- /// to intrinsic functions. 
- class IntrinsicInst : public CallInst { 
- public: 
-   IntrinsicInst() = delete; 
-   IntrinsicInst(const IntrinsicInst &) = delete; 
-   IntrinsicInst &operator=(const IntrinsicInst &) = delete; 
-   
-   /// Return the intrinsic ID of this intrinsic. 
-   Intrinsic::ID getIntrinsicID() const { 
-     return getCalledFunction()->getIntrinsicID(); 
-   } 
-   
-   /// Return true if swapping the first two arguments to the intrinsic produces 
-   /// the same result. 
-   bool isCommutative() const { 
-     switch (getIntrinsicID()) { 
-     case Intrinsic::maxnum: 
-     case Intrinsic::minnum: 
-     case Intrinsic::maximum: 
-     case Intrinsic::minimum: 
-     case Intrinsic::smax: 
-     case Intrinsic::smin: 
-     case Intrinsic::umax: 
-     case Intrinsic::umin: 
-     case Intrinsic::sadd_sat: 
-     case Intrinsic::uadd_sat: 
-     case Intrinsic::sadd_with_overflow: 
-     case Intrinsic::uadd_with_overflow: 
-     case Intrinsic::smul_with_overflow: 
-     case Intrinsic::umul_with_overflow: 
-     case Intrinsic::smul_fix: 
-     case Intrinsic::umul_fix: 
-     case Intrinsic::smul_fix_sat: 
-     case Intrinsic::umul_fix_sat: 
-     case Intrinsic::fma: 
-     case Intrinsic::fmuladd: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   
-   /// Checks if the intrinsic is an annotation. 
-   bool isAssumeLikeIntrinsic() const { 
-     switch (getIntrinsicID()) { 
-     default: break; 
-     case Intrinsic::assume: 
-     case Intrinsic::sideeffect: 
-     case Intrinsic::pseudoprobe: 
-     case Intrinsic::dbg_assign: 
-     case Intrinsic::dbg_declare: 
-     case Intrinsic::dbg_value: 
-     case Intrinsic::dbg_label: 
-     case Intrinsic::invariant_start: 
-     case Intrinsic::invariant_end: 
-     case Intrinsic::lifetime_start: 
-     case Intrinsic::lifetime_end: 
-     case Intrinsic::experimental_noalias_scope_decl: 
-     case Intrinsic::objectsize: 
-     case Intrinsic::ptr_annotation: 
-     case Intrinsic::var_annotation: 
-       return true; 
-     } 
-     return false; 
-   } 
-   
-   /// Check if the intrinsic might lower into a regular function call in the 
-   /// course of IR transformations 
-   static bool mayLowerToFunctionCall(Intrinsic::ID IID); 
-   
-   /// Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const CallInst *I) { 
-     if (const Function *CF = I->getCalledFunction()) 
-       return CF->isIntrinsic(); 
-     return false; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<CallInst>(V) && classof(cast<CallInst>(V)); 
-   } 
- }; 
-   
- /// Check if \p ID corresponds to a lifetime intrinsic. 
- static inline bool isLifetimeIntrinsic(Intrinsic::ID ID) { 
-   switch (ID) { 
-   case Intrinsic::lifetime_start: 
-   case Intrinsic::lifetime_end: 
-     return true; 
-   default: 
-     return false; 
-   } 
- } 
-   
- /// This is the common base class for lifetime intrinsics. 
- class LifetimeIntrinsic : public IntrinsicInst { 
- public: 
-   /// \name Casting methods 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return isLifetimeIntrinsic(I->getIntrinsicID()); 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- /// Check if \p ID corresponds to a debug info intrinsic. 
- static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) { 
-   switch (ID) { 
-   case Intrinsic::dbg_declare: 
-   case Intrinsic::dbg_value: 
-   case Intrinsic::dbg_addr: 
-   case Intrinsic::dbg_label: 
-   case Intrinsic::dbg_assign: 
-     return true; 
-   default: 
-     return false; 
-   } 
- } 
-   
- /// This is the common base class for debug info intrinsics. 
- class DbgInfoIntrinsic : public IntrinsicInst { 
- public: 
-   /// \name Casting methods 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return isDbgInfoIntrinsic(I->getIntrinsicID()); 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- /// This is the common base class for debug info intrinsics for variables. 
- class DbgVariableIntrinsic : public DbgInfoIntrinsic { 
- public: 
-   // Iterator for ValueAsMetadata that internally uses direct pointer iteration 
-   // over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the 
-   // ValueAsMetadata . 
-   class location_op_iterator 
-       : public iterator_facade_base<location_op_iterator, 
-                                     std::bidirectional_iterator_tag, Value *> { 
-     PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I; 
-   
-   public: 
-     location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {} 
-     location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {} 
-   
-     location_op_iterator(const location_op_iterator &R) : I(R.I) {} 
-     location_op_iterator &operator=(const location_op_iterator &R) { 
-       I = R.I; 
-       return *this; 
-     } 
-     bool operator==(const location_op_iterator &RHS) const { 
-       return I == RHS.I; 
-     } 
-     const Value *operator*() const { 
-       ValueAsMetadata *VAM = I.is<ValueAsMetadata *>() 
-                                  ? I.get<ValueAsMetadata *>() 
-                                  : *I.get<ValueAsMetadata **>(); 
-       return VAM->getValue(); 
-     }; 
-     Value *operator*() { 
-       ValueAsMetadata *VAM = I.is<ValueAsMetadata *>() 
-                                  ? I.get<ValueAsMetadata *>() 
-                                  : *I.get<ValueAsMetadata **>(); 
-       return VAM->getValue(); 
-     } 
-     location_op_iterator &operator++() { 
-       if (I.is<ValueAsMetadata *>()) 
-         I = I.get<ValueAsMetadata *>() + 1; 
-       else 
-         I = I.get<ValueAsMetadata **>() + 1; 
-       return *this; 
-     } 
-     location_op_iterator &operator--() { 
-       if (I.is<ValueAsMetadata *>()) 
-         I = I.get<ValueAsMetadata *>() - 1; 
-       else 
-         I = I.get<ValueAsMetadata **>() - 1; 
-       return *this; 
-     } 
-   }; 
-   
-   /// Get the locations corresponding to the variable referenced by the debug 
-   /// info intrinsic.  Depending on the intrinsic, this could be the 
-   /// variable's value or its address. 
-   iterator_range<location_op_iterator> location_ops() const; 
-   
-   Value *getVariableLocationOp(unsigned OpIdx) const; 
-   
-   void replaceVariableLocationOp(Value *OldValue, Value *NewValue); 
-   void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue); 
-   /// Adding a new location operand will always result in this intrinsic using 
-   /// an ArgList, and must always be accompanied by a new expression that uses 
-   /// the new operand. 
-   void addVariableLocationOps(ArrayRef<Value *> NewValues, 
-                               DIExpression *NewExpr); 
-   
-   void setVariable(DILocalVariable *NewVar) { 
-     setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar)); 
-   } 
-   
-   void setExpression(DIExpression *NewExpr) { 
-     setArgOperand(2, MetadataAsValue::get(NewExpr->getContext(), NewExpr)); 
-   } 
-   
-   unsigned getNumVariableLocationOps() const { 
-     if (hasArgList()) 
-       return cast<DIArgList>(getRawLocation())->getArgs().size(); 
-     return 1; 
-   } 
-   
-   bool hasArgList() const { return isa<DIArgList>(getRawLocation()); } 
-   
-   /// Does this describe the address of a local variable. True for dbg.addr and 
-   /// dbg.declare, but not dbg.value, which describes its value, or dbg.assign, 
-   /// which describes a combination of the variable's value and address. 
-   bool isAddressOfVariable() const { 
-     return getIntrinsicID() != Intrinsic::dbg_value && 
-            getIntrinsicID() != Intrinsic::dbg_assign; 
-   } 
-   
-   void setKillLocation() { 
-     // TODO: When/if we remove duplicate values from DIArgLists, we don't need 
-     // this set anymore. 
-     SmallPtrSet<Value *, 4> RemovedValues; 
-     for (Value *OldValue : location_ops()) { 
-       if (!RemovedValues.insert(OldValue).second) 
-         continue; 
-       Value *Poison = PoisonValue::get(OldValue->getType()); 
-       replaceVariableLocationOp(OldValue, Poison); 
-     } 
-   } 
-   
-   bool isKillLocation() const { 
-     return (getNumVariableLocationOps() == 0 && 
-             !getExpression()->isComplex()) || 
-            any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); }); 
-   } 
-   
-   DILocalVariable *getVariable() const { 
-     return cast<DILocalVariable>(getRawVariable()); 
-   } 
-   
-   DIExpression *getExpression() const { 
-     return cast<DIExpression>(getRawExpression()); 
-   } 
-   
-   Metadata *getRawLocation() const { 
-     return cast<MetadataAsValue>(getArgOperand(0))->getMetadata(); 
-   } 
-   
-   Metadata *getRawVariable() const { 
-     return cast<MetadataAsValue>(getArgOperand(1))->getMetadata(); 
-   } 
-   
-   Metadata *getRawExpression() const { 
-     return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 
-   } 
-   
-   /// Use of this should generally be avoided; instead, 
-   /// replaceVariableLocationOp and addVariableLocationOps should be used where 
-   /// possible to avoid creating invalid state. 
-   void setRawLocation(Metadata *Location) { 
-     return setArgOperand(0, MetadataAsValue::get(getContext(), Location)); 
-   } 
-   
-   /// Get the size (in bits) of the variable, or fragment of the variable that 
-   /// is described. 
-   std::optional<uint64_t> getFragmentSizeInBits() const; 
-   
-   /// Get the FragmentInfo for the variable. 
-   std::optional<DIExpression::FragmentInfo> getFragment() const { 
-     return getExpression()->getFragmentInfo(); 
-   } 
-   
-   /// \name Casting methods 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::dbg_declare: 
-     case Intrinsic::dbg_value: 
-     case Intrinsic::dbg_addr: 
-     case Intrinsic::dbg_assign: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- protected: 
-   void setArgOperand(unsigned i, Value *v) { 
-     DbgInfoIntrinsic::setArgOperand(i, v); 
-   } 
-   void setOperand(unsigned i, Value *v) { DbgInfoIntrinsic::setOperand(i, v); } 
- }; 
-   
- /// This represents the llvm.dbg.declare instruction. 
- class DbgDeclareInst : public DbgVariableIntrinsic { 
- public: 
-   Value *getAddress() const { 
-     assert(getNumVariableLocationOps() == 1 && 
-            "dbg.declare must have exactly 1 location operand."); 
-     return getVariableLocationOp(0); 
-   } 
-   
-   /// \name Casting methods 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::dbg_declare; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- /// This represents the llvm.dbg.addr instruction. 
- class DbgAddrIntrinsic : public DbgVariableIntrinsic { 
- public: 
-   Value *getAddress() const { 
-     assert(getNumVariableLocationOps() == 1 && 
-            "dbg.addr must have exactly 1 location operand."); 
-     return getVariableLocationOp(0); 
-   } 
-   
-   /// \name Casting methods 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::dbg_addr; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This represents the llvm.dbg.value instruction. 
- class DbgValueInst : public DbgVariableIntrinsic { 
- public: 
-   // The default argument should only be used in ISel, and the default option 
-   // should be removed once ISel support for multiple location ops is complete. 
-   Value *getValue(unsigned OpIdx = 0) const { 
-     return getVariableLocationOp(OpIdx); 
-   } 
-   iterator_range<location_op_iterator> getValues() const { 
-     return location_ops(); 
-   } 
-   
-   /// \name Casting methods 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::dbg_value || 
-            I->getIntrinsicID() == Intrinsic::dbg_assign; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- /// This represents the llvm.dbg.assign instruction. 
- class DbgAssignIntrinsic : public DbgValueInst { 
-   enum Operands { 
-     OpValue, 
-     OpVar, 
-     OpExpr, 
-     OpAssignID, 
-     OpAddress, 
-     OpAddressExpr, 
-   }; 
-   
- public: 
-   Value *getAddress() const; 
-   Metadata *getRawAddress() const { 
-     return cast<MetadataAsValue>(getArgOperand(OpAddress))->getMetadata(); 
-   } 
-   Metadata *getRawAssignID() const { 
-     return cast<MetadataAsValue>(getArgOperand(OpAssignID))->getMetadata(); 
-   } 
-   DIAssignID *getAssignID() const { return cast<DIAssignID>(getRawAssignID()); } 
-   Metadata *getRawAddressExpression() const { 
-     return cast<MetadataAsValue>(getArgOperand(OpAddressExpr))->getMetadata(); 
-   } 
-   DIExpression *getAddressExpression() const { 
-     return cast<DIExpression>(getRawAddressExpression()); 
-   } 
-   void setAddressExpression(DIExpression *NewExpr) { 
-     setArgOperand(OpAddressExpr, 
-                   MetadataAsValue::get(NewExpr->getContext(), NewExpr)); 
-   } 
-   void setAssignId(DIAssignID *New); 
-   void setAddress(Value *V); 
-   /// Kill the address component. 
-   void setKillAddress(); 
-   /// Check whether this kills the address component. This doesn't take into 
-   /// account the position of the intrinsic, therefore a returned value of false 
-   /// does not guarentee the address is a valid location for the variable at the 
-   /// intrinsic's position in IR. 
-   bool isKillAddress() const; 
-   void setValue(Value *V); 
-   /// \name Casting methods 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::dbg_assign; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- /// This represents the llvm.dbg.label instruction. 
- class DbgLabelInst : public DbgInfoIntrinsic { 
- public: 
-   DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); } 
-   
-   Metadata *getRawLabel() const { 
-     return cast<MetadataAsValue>(getArgOperand(0))->getMetadata(); 
-   } 
-   
-   /// Methods for support type inquiry through isa, cast, and dyn_cast: 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::dbg_label; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- /// This is the common base class for vector predication intrinsics. 
- class VPIntrinsic : public IntrinsicInst { 
- public: 
-   /// \brief Declares a llvm.vp.* intrinsic in \p M that matches the parameters 
-   /// \p Params. Additionally, the load and gather intrinsics require 
-   /// \p ReturnType to be specified. 
-   static Function *getDeclarationForParams(Module *M, Intrinsic::ID, 
-                                            Type *ReturnType, 
-                                            ArrayRef<Value *> Params); 
-   
-   static std::optional<unsigned> getMaskParamPos(Intrinsic::ID IntrinsicID); 
-   static std::optional<unsigned> getVectorLengthParamPos( 
-       Intrinsic::ID IntrinsicID); 
-   
-   /// The llvm.vp.* intrinsics for this instruction Opcode 
-   static Intrinsic::ID getForOpcode(unsigned OC); 
-   
-   // Whether \p ID is a VP intrinsic ID. 
-   static bool isVPIntrinsic(Intrinsic::ID); 
-   
-   /// \return The mask parameter or nullptr. 
-   Value *getMaskParam() const; 
-   void setMaskParam(Value *); 
-   
-   /// \return The vector length parameter or nullptr. 
-   Value *getVectorLengthParam() const; 
-   void setVectorLengthParam(Value *); 
-   
-   /// \return Whether the vector length param can be ignored. 
-   bool canIgnoreVectorLengthParam() const; 
-   
-   /// \return The static element count (vector number of elements) the vector 
-   /// length parameter applies to. 
-   ElementCount getStaticVectorLength() const; 
-   
-   /// \return The alignment of the pointer used by this load/store/gather or 
-   /// scatter. 
-   MaybeAlign getPointerAlignment() const; 
-   // MaybeAlign setPointerAlignment(Align NewAlign); // TODO 
-   
-   /// \return The pointer operand of this load,store, gather or scatter. 
-   Value *getMemoryPointerParam() const; 
-   static std::optional<unsigned> getMemoryPointerParamPos(Intrinsic::ID); 
-   
-   /// \return The data (payload) operand of this store or scatter. 
-   Value *getMemoryDataParam() const; 
-   static std::optional<unsigned> getMemoryDataParamPos(Intrinsic::ID); 
-   
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     return isVPIntrinsic(I->getIntrinsicID()); 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   // Equivalent non-predicated opcode 
-   std::optional<unsigned> getFunctionalOpcode() const { 
-     return getFunctionalOpcodeForVP(getIntrinsicID()); 
-   } 
-   
-   // Equivalent non-predicated opcode 
-   static std::optional<unsigned> getFunctionalOpcodeForVP(Intrinsic::ID ID); 
- }; 
-   
- /// This represents vector predication reduction intrinsics. 
- class VPReductionIntrinsic : public VPIntrinsic { 
- public: 
-   static bool isVPReduction(Intrinsic::ID ID); 
-   
-   unsigned getStartParamPos() const; 
-   unsigned getVectorParamPos() const; 
-   
-   static std::optional<unsigned> getStartParamPos(Intrinsic::ID ID); 
-   static std::optional<unsigned> getVectorParamPos(Intrinsic::ID ID); 
-   
-   /// Methods for support type inquiry through isa, cast, and dyn_cast: 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return VPReductionIntrinsic::isVPReduction(I->getIntrinsicID()); 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- class VPCastIntrinsic : public VPIntrinsic { 
- public: 
-   static bool isVPCast(Intrinsic::ID ID); 
-   
-   /// Methods for support type inquiry through isa, cast, and dyn_cast: 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return VPCastIntrinsic::isVPCast(I->getIntrinsicID()); 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- class VPCmpIntrinsic : public VPIntrinsic { 
- public: 
-   static bool isVPCmp(Intrinsic::ID ID); 
-   
-   CmpInst::Predicate getPredicate() const; 
-   
-   /// Methods for support type inquiry through isa, cast, and dyn_cast: 
-   /// @{ 
-   static bool classof(const IntrinsicInst *I) { 
-     return VPCmpIntrinsic::isVPCmp(I->getIntrinsicID()); 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   /// @} 
- }; 
-   
- /// This is the common base class for constrained floating point intrinsics. 
- class ConstrainedFPIntrinsic : public IntrinsicInst { 
- public: 
-   bool isUnaryOp() const; 
-   bool isTernaryOp() const; 
-   std::optional<RoundingMode> getRoundingMode() const; 
-   std::optional<fp::ExceptionBehavior> getExceptionBehavior() const; 
-   bool isDefaultFPEnvironment() const; 
-   
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I); 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// Constrained floating point compare intrinsics. 
- class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic { 
- public: 
-   FCmpInst::Predicate getPredicate() const; 
-   bool isSignaling() const { 
-     return getIntrinsicID() == Intrinsic::experimental_constrained_fcmps; 
-   } 
-   
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::experimental_constrained_fcmp: 
-     case Intrinsic::experimental_constrained_fcmps: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class represents min/max intrinsics. 
- class MinMaxIntrinsic : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::umin: 
-     case Intrinsic::umax: 
-     case Intrinsic::smin: 
-     case Intrinsic::smax: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); } 
-   Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); } 
-   
-   /// Returns the comparison predicate underlying the intrinsic. 
-   static ICmpInst::Predicate getPredicate(Intrinsic::ID ID) { 
-     switch (ID) { 
-     case Intrinsic::umin: 
-       return ICmpInst::Predicate::ICMP_ULT; 
-     case Intrinsic::umax: 
-       return ICmpInst::Predicate::ICMP_UGT; 
-     case Intrinsic::smin: 
-       return ICmpInst::Predicate::ICMP_SLT; 
-     case Intrinsic::smax: 
-       return ICmpInst::Predicate::ICMP_SGT; 
-     default: 
-       llvm_unreachable("Invalid intrinsic"); 
-     } 
-   } 
-   
-   /// Returns the comparison predicate underlying the intrinsic. 
-   ICmpInst::Predicate getPredicate() const { 
-     return getPredicate(getIntrinsicID()); 
-   } 
-   
-   /// Whether the intrinsic is signed or unsigned. 
-   static bool isSigned(Intrinsic::ID ID) { 
-     return ICmpInst::isSigned(getPredicate(ID)); 
-   }; 
-   
-   /// Whether the intrinsic is signed or unsigned. 
-   bool isSigned() const { return isSigned(getIntrinsicID()); }; 
-   
-   /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values, 
-   /// so there is a certain threshold value, upon reaching which, 
-   /// their value can no longer change. Return said threshold. 
-   static APInt getSaturationPoint(Intrinsic::ID ID, unsigned numBits) { 
-     switch (ID) { 
-     case Intrinsic::umin: 
-       return APInt::getMinValue(numBits); 
-     case Intrinsic::umax: 
-       return APInt::getMaxValue(numBits); 
-     case Intrinsic::smin: 
-       return APInt::getSignedMinValue(numBits); 
-     case Intrinsic::smax: 
-       return APInt::getSignedMaxValue(numBits); 
-     default: 
-       llvm_unreachable("Invalid intrinsic"); 
-     } 
-   } 
-   
-   /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values, 
-   /// so there is a certain threshold value, upon reaching which, 
-   /// their value can no longer change. Return said threshold. 
-   APInt getSaturationPoint(unsigned numBits) const { 
-     return getSaturationPoint(getIntrinsicID(), numBits); 
-   } 
-   
-   /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values, 
-   /// so there is a certain threshold value, upon reaching which, 
-   /// their value can no longer change. Return said threshold. 
-   static Constant *getSaturationPoint(Intrinsic::ID ID, Type *Ty) { 
-     return Constant::getIntegerValue( 
-         Ty, getSaturationPoint(ID, Ty->getScalarSizeInBits())); 
-   } 
-   
-   /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values, 
-   /// so there is a certain threshold value, upon reaching which, 
-   /// their value can no longer change. Return said threshold. 
-   Constant *getSaturationPoint(Type *Ty) const { 
-     return getSaturationPoint(getIntrinsicID(), Ty); 
-   } 
- }; 
-   
- /// This class represents an intrinsic that is based on a binary operation. 
- /// This includes op.with.overflow and saturating add/sub intrinsics. 
- class BinaryOpIntrinsic : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::uadd_with_overflow: 
-     case Intrinsic::sadd_with_overflow: 
-     case Intrinsic::usub_with_overflow: 
-     case Intrinsic::ssub_with_overflow: 
-     case Intrinsic::umul_with_overflow: 
-     case Intrinsic::smul_with_overflow: 
-     case Intrinsic::uadd_sat: 
-     case Intrinsic::sadd_sat: 
-     case Intrinsic::usub_sat: 
-     case Intrinsic::ssub_sat: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); } 
-   Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); } 
-   
-   /// Returns the binary operation underlying the intrinsic. 
-   Instruction::BinaryOps getBinaryOp() const; 
-   
-   /// Whether the intrinsic is signed or unsigned. 
-   bool isSigned() const; 
-   
-   /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap. 
-   unsigned getNoWrapKind() const; 
- }; 
-   
- /// Represents an op.with.overflow intrinsic. 
- class WithOverflowInst : public BinaryOpIntrinsic { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::uadd_with_overflow: 
-     case Intrinsic::sadd_with_overflow: 
-     case Intrinsic::usub_with_overflow: 
-     case Intrinsic::ssub_with_overflow: 
-     case Intrinsic::umul_with_overflow: 
-     case Intrinsic::smul_with_overflow: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// Represents a saturating add/sub intrinsic. 
- class SaturatingInst : public BinaryOpIntrinsic { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::uadd_sat: 
-     case Intrinsic::sadd_sat: 
-     case Intrinsic::usub_sat: 
-     case Intrinsic::ssub_sat: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// Common base class for all memory intrinsics. Simply provides 
- /// common methods. 
- /// Written as CRTP to avoid a common base class amongst the 
- /// three atomicity hierarchies. 
- template <typename Derived> class MemIntrinsicBase : public IntrinsicInst { 
- private: 
-   enum { ARG_DEST = 0, ARG_LENGTH = 2 }; 
-   
- public: 
-   Value *getRawDest() const { 
-     return const_cast<Value *>(getArgOperand(ARG_DEST)); 
-   } 
-   const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); } 
-   Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); } 
-   
-   Value *getLength() const { 
-     return const_cast<Value *>(getArgOperand(ARG_LENGTH)); 
-   } 
-   const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); } 
-   Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); } 
-   
-   /// This is just like getRawDest, but it strips off any cast 
-   /// instructions (including addrspacecast) that feed it, giving the 
-   /// original input.  The returned value is guaranteed to be a pointer. 
-   Value *getDest() const { return getRawDest()->stripPointerCasts(); } 
-   
-   unsigned getDestAddressSpace() const { 
-     return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 
-   } 
-   
-   /// FIXME: Remove this function once transition to Align is over. 
-   /// Use getDestAlign() instead. 
-   LLVM_DEPRECATED("Use getDestAlign() instead", "getDestAlign") 
-   unsigned getDestAlignment() const { 
-     if (auto MA = getParamAlign(ARG_DEST)) 
-       return MA->value(); 
-     return 0; 
-   } 
-   MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); } 
-   
-   /// Set the specified arguments of the instruction. 
-   void setDest(Value *Ptr) { 
-     assert(getRawDest()->getType() == Ptr->getType() && 
-            "setDest called with pointer of wrong type!"); 
-     setArgOperand(ARG_DEST, Ptr); 
-   } 
-   
-   void setDestAlignment(MaybeAlign Alignment) { 
-     removeParamAttr(ARG_DEST, Attribute::Alignment); 
-     if (Alignment) 
-       addParamAttr(ARG_DEST, 
-                    Attribute::getWithAlignment(getContext(), *Alignment)); 
-   } 
-   void setDestAlignment(Align Alignment) { 
-     removeParamAttr(ARG_DEST, Attribute::Alignment); 
-     addParamAttr(ARG_DEST, 
-                  Attribute::getWithAlignment(getContext(), Alignment)); 
-   } 
-   
-   void setLength(Value *L) { 
-     assert(getLength()->getType() == L->getType() && 
-            "setLength called with value of wrong type!"); 
-     setArgOperand(ARG_LENGTH, L); 
-   } 
- }; 
-   
- /// Common base class for all memory transfer intrinsics. Simply provides 
- /// common methods. 
- template <class BaseCL> class MemTransferBase : public BaseCL { 
- private: 
-   enum { ARG_SOURCE = 1 }; 
-   
- public: 
-   /// Return the arguments to the instruction. 
-   Value *getRawSource() const { 
-     return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE)); 
-   } 
-   const Use &getRawSourceUse() const { 
-     return BaseCL::getArgOperandUse(ARG_SOURCE); 
-   } 
-   Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); } 
-   
-   /// This is just like getRawSource, but it strips off any cast 
-   /// instructions that feed it, giving the original input.  The returned 
-   /// value is guaranteed to be a pointer. 
-   Value *getSource() const { return getRawSource()->stripPointerCasts(); } 
-   
-   unsigned getSourceAddressSpace() const { 
-     return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 
-   } 
-   
-   /// FIXME: Remove this function once transition to Align is over. 
-   /// Use getSourceAlign() instead. 
-   LLVM_DEPRECATED("Use getSourceAlign() instead", "getSourceAlign") 
-   unsigned getSourceAlignment() const { 
-     if (auto MA = BaseCL::getParamAlign(ARG_SOURCE)) 
-       return MA->value(); 
-     return 0; 
-   } 
-   
-   MaybeAlign getSourceAlign() const { 
-     return BaseCL::getParamAlign(ARG_SOURCE); 
-   } 
-   
-   void setSource(Value *Ptr) { 
-     assert(getRawSource()->getType() == Ptr->getType() && 
-            "setSource called with pointer of wrong type!"); 
-     BaseCL::setArgOperand(ARG_SOURCE, Ptr); 
-   } 
-   
-   void setSourceAlignment(MaybeAlign Alignment) { 
-     BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 
-     if (Alignment) 
-       BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 
-                                            BaseCL::getContext(), *Alignment)); 
-   } 
-   
-   void setSourceAlignment(Align Alignment) { 
-     BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 
-     BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 
-                                          BaseCL::getContext(), Alignment)); 
-   } 
- }; 
-   
- /// Common base class for all memset intrinsics. Simply provides 
- /// common methods. 
- template <class BaseCL> class MemSetBase : public BaseCL { 
- private: 
-   enum { ARG_VALUE = 1 }; 
-   
- public: 
-   Value *getValue() const { 
-     return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE)); 
-   } 
-   const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); } 
-   Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); } 
-   
-   void setValue(Value *Val) { 
-     assert(getValue()->getType() == Val->getType() && 
-            "setValue called with value of wrong type!"); 
-     BaseCL::setArgOperand(ARG_VALUE, Val); 
-   } 
- }; 
-   
- // The common base class for the atomic memset/memmove/memcpy intrinsics 
- // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 
- class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> { 
- private: 
-   enum { ARG_ELEMENTSIZE = 3 }; 
-   
- public: 
-   Value *getRawElementSizeInBytes() const { 
-     return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE)); 
-   } 
-   
-   ConstantInt *getElementSizeInBytesCst() const { 
-     return cast<ConstantInt>(getRawElementSizeInBytes()); 
-   } 
-   
-   uint32_t getElementSizeInBytes() const { 
-     return getElementSizeInBytesCst()->getZExtValue(); 
-   } 
-   
-   void setElementSizeInBytes(Constant *V) { 
-     assert(V->getType() == Type::getInt8Ty(getContext()) && 
-            "setElementSizeInBytes called with value of wrong type!"); 
-     setArgOperand(ARG_ELEMENTSIZE, V); 
-   } 
-   
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memcpy_element_unordered_atomic: 
-     case Intrinsic::memmove_element_unordered_atomic: 
-     case Intrinsic::memset_element_unordered_atomic: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class represents atomic memset intrinsic 
- // i.e. llvm.element.unordered.atomic.memset 
- class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- // This class wraps the atomic memcpy/memmove intrinsics 
- // i.e. llvm.element.unordered.atomic.memcpy/memmove 
- class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memcpy_element_unordered_atomic: 
-     case Intrinsic::memmove_element_unordered_atomic: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class represents the atomic memcpy intrinsic 
- /// i.e. llvm.element.unordered.atomic.memcpy 
- class AtomicMemCpyInst : public AtomicMemTransferInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class represents the atomic memmove intrinsic 
- /// i.e. llvm.element.unordered.atomic.memmove 
- class AtomicMemMoveInst : public AtomicMemTransferInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This is the common base class for memset/memcpy/memmove. 
- class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> { 
- private: 
-   enum { ARG_VOLATILE = 3 }; 
-   
- public: 
-   ConstantInt *getVolatileCst() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE))); 
-   } 
-   
-   bool isVolatile() const { return !getVolatileCst()->isZero(); } 
-   
-   void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); } 
-   
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memcpy: 
-     case Intrinsic::memmove: 
-     case Intrinsic::memset: 
-     case Intrinsic::memset_inline: 
-     case Intrinsic::memcpy_inline: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class wraps the llvm.memset and llvm.memset.inline intrinsics. 
- class MemSetInst : public MemSetBase<MemIntrinsic> { 
- public: 
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memset: 
-     case Intrinsic::memset_inline: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class wraps the llvm.memset.inline intrinsic. 
- class MemSetInlineInst : public MemSetInst { 
- public: 
-   ConstantInt *getLength() const { 
-     return cast<ConstantInt>(MemSetInst::getLength()); 
-   } 
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::memset_inline; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class wraps the llvm.memcpy/memmove intrinsics. 
- class MemTransferInst : public MemTransferBase<MemIntrinsic> { 
- public: 
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memcpy: 
-     case Intrinsic::memmove: 
-     case Intrinsic::memcpy_inline: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class wraps the llvm.memcpy intrinsic. 
- class MemCpyInst : public MemTransferInst { 
- public: 
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::memcpy || 
-            I->getIntrinsicID() == Intrinsic::memcpy_inline; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class wraps the llvm.memmove intrinsic. 
- class MemMoveInst : public MemTransferInst { 
- public: 
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::memmove; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class wraps the llvm.memcpy.inline intrinsic. 
- class MemCpyInlineInst : public MemCpyInst { 
- public: 
-   ConstantInt *getLength() const { 
-     return cast<ConstantInt>(MemCpyInst::getLength()); 
-   } 
-   // Methods for support type inquiry through isa, cast, and dyn_cast: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::memcpy_inline; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- // The common base class for any memset/memmove/memcpy intrinsics; 
- // whether they be atomic or non-atomic. 
- // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 
- //  and llvm.memset/memcpy/memmove 
- class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> { 
- public: 
-   bool isVolatile() const { 
-     // Only the non-atomic intrinsics can be volatile 
-     if (auto *MI = dyn_cast<MemIntrinsic>(this)) 
-       return MI->isVolatile(); 
-     return false; 
-   } 
-   
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memcpy: 
-     case Intrinsic::memcpy_inline: 
-     case Intrinsic::memmove: 
-     case Intrinsic::memset: 
-     case Intrinsic::memset_inline: 
-     case Intrinsic::memcpy_element_unordered_atomic: 
-     case Intrinsic::memmove_element_unordered_atomic: 
-     case Intrinsic::memset_element_unordered_atomic: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class represents any memset intrinsic 
- // i.e. llvm.element.unordered.atomic.memset 
- // and  llvm.memset 
- class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memset: 
-     case Intrinsic::memset_inline: 
-     case Intrinsic::memset_element_unordered_atomic: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- // This class wraps any memcpy/memmove intrinsics 
- // i.e. llvm.element.unordered.atomic.memcpy/memmove 
- // and  llvm.memcpy/memmove 
- class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memcpy: 
-     case Intrinsic::memcpy_inline: 
-     case Intrinsic::memmove: 
-     case Intrinsic::memcpy_element_unordered_atomic: 
-     case Intrinsic::memmove_element_unordered_atomic: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class represents any memcpy intrinsic 
- /// i.e. llvm.element.unordered.atomic.memcpy 
- ///  and llvm.memcpy 
- class AnyMemCpyInst : public AnyMemTransferInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memcpy: 
-     case Intrinsic::memcpy_inline: 
-     case Intrinsic::memcpy_element_unordered_atomic: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This class represents any memmove intrinsic 
- /// i.e. llvm.element.unordered.atomic.memmove 
- ///  and llvm.memmove 
- class AnyMemMoveInst : public AnyMemTransferInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     switch (I->getIntrinsicID()) { 
-     case Intrinsic::memmove: 
-     case Intrinsic::memmove_element_unordered_atomic: 
-       return true; 
-     default: 
-       return false; 
-     } 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This represents the llvm.va_start intrinsic. 
- class VAStartInst : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::vastart; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); } 
- }; 
-   
- /// This represents the llvm.va_end intrinsic. 
- class VAEndInst : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::vaend; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); } 
- }; 
-   
- /// This represents the llvm.va_copy intrinsic. 
- class VACopyInst : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::vacopy; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); } 
-   Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); } 
- }; 
-   
- /// A base class for all instrprof intrinsics. 
- class InstrProfInstBase : public IntrinsicInst { 
- public: 
-   // The name of the instrumented function. 
-   GlobalVariable *getName() const { 
-     return cast<GlobalVariable>( 
-         const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 
-   } 
-   // The hash of the CFG for the instrumented function. 
-   ConstantInt *getHash() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 
-   } 
-   // The number of counters for the instrumented function. 
-   ConstantInt *getNumCounters() const; 
-   // The index of the counter that this instruction acts on. 
-   ConstantInt *getIndex() const; 
- }; 
-   
- /// This represents the llvm.instrprof.cover intrinsic. 
- class InstrProfCoverInst : public InstrProfInstBase { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::instrprof_cover; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This represents the llvm.instrprof.increment intrinsic. 
- class InstrProfIncrementInst : public InstrProfInstBase { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::instrprof_increment || 
-            I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   Value *getStep() const; 
- }; 
-   
- /// This represents the llvm.instrprof.increment.step intrinsic. 
- class InstrProfIncrementInstStep : public InstrProfIncrementInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This represents the llvm.instrprof.value.profile intrinsic. 
- class InstrProfValueProfileInst : public InstrProfInstBase { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   Value *getTargetValue() const { 
-     return cast<Value>(const_cast<Value *>(getArgOperand(2))); 
-   } 
-   
-   ConstantInt *getValueKind() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 
-   } 
-   
-   // Returns the value site index. 
-   ConstantInt *getIndex() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); 
-   } 
- }; 
-   
- class PseudoProbeInst : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::pseudoprobe; 
-   } 
-   
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   ConstantInt *getFuncGuid() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0))); 
-   } 
-   
-   ConstantInt *getIndex() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 
-   } 
-   
-   ConstantInt *getAttributes() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 
-   } 
-   
-   ConstantInt *getFactor() const { 
-     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 
-   } 
- }; 
-   
- class NoAliasScopeDeclInst : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl; 
-   } 
-   
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   MDNode *getScopeList() const { 
-     auto *MV = 
-         cast<MetadataAsValue>(getOperand(Intrinsic::NoAliasScopeDeclScopeArg)); 
-     return cast<MDNode>(MV->getMetadata()); 
-   } 
-   
-   void setScopeList(MDNode *ScopeList) { 
-     setOperand(Intrinsic::NoAliasScopeDeclScopeArg, 
-                MetadataAsValue::get(getContext(), ScopeList)); 
-   } 
- }; 
-   
- /// Common base class for representing values projected from a statepoint. 
- /// Currently, the only projections available are gc.result and gc.relocate. 
- class GCProjectionInst : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate || 
-       I->getIntrinsicID() == Intrinsic::experimental_gc_result; 
-   } 
-   
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   /// Return true if this relocate is tied to the invoke statepoint. 
-   /// This includes relocates which are on the unwinding path. 
-   bool isTiedToInvoke() const { 
-     const Value *Token = getArgOperand(0); 
-   
-     return isa<LandingPadInst>(Token) || isa<InvokeInst>(Token); 
-   } 
-   
-   /// The statepoint with which this gc.relocate is associated. 
-   const Value *getStatepoint() const; 
- }; 
-   
- /// Represents calls to the gc.relocate intrinsic. 
- class GCRelocateInst : public GCProjectionInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate; 
-   } 
-   
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
-   
-   /// The index into the associate statepoint's argument list 
-   /// which contains the base pointer of the pointer whose 
-   /// relocation this gc.relocate describes. 
-   unsigned getBasePtrIndex() const { 
-     return cast<ConstantInt>(getArgOperand(1))->getZExtValue(); 
-   } 
-   
-   /// The index into the associate statepoint's argument list which 
-   /// contains the pointer whose relocation this gc.relocate describes. 
-   unsigned getDerivedPtrIndex() const { 
-     return cast<ConstantInt>(getArgOperand(2))->getZExtValue(); 
-   } 
-   
-   Value *getBasePtr() const; 
-   Value *getDerivedPtr() const; 
- }; 
-   
- /// Represents calls to the gc.result intrinsic. 
- class GCResultInst : public GCProjectionInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::experimental_gc_result; 
-   } 
-   
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This represents intrinsics that guard a condition 
- class CondGuardInst : public IntrinsicInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::assume || 
-            I->getIntrinsicID() == Intrinsic::experimental_guard; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- /// This represents the llvm.assume intrinsic. 
- class AssumeInst : public CondGuardInst { 
- public: 
-   static bool classof(const IntrinsicInst *I) { 
-     return I->getIntrinsicID() == Intrinsic::assume; 
-   } 
-   static bool classof(const Value *V) { 
-     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 
-   } 
- }; 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_IR_INTRINSICINST_H 
-