xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h (revision 8bcb0991864975618c09697b1aca10683346d9f0)
1 //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines classes that make it really easy to deal with intrinsic
10 // functions with the isa/dyncast family of functions.  In particular, this
11 // allows you to do things like:
12 //
13 //     if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst))
14 //        ... MCI->getDest() ... MCI->getSource() ...
15 //
16 // All intrinsic function calls are instances of the call instruction, so these
17 // are all subclasses of the CallInst class.  Note that none of these classes
18 // has state or virtual methods, which is an important part of this gross/neat
19 // hack working.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 #ifndef LLVM_IR_INTRINSICINST_H
24 #define LLVM_IR_INTRINSICINST_H
25 
26 #include "llvm/IR/Constants.h"
27 #include "llvm/IR/DerivedTypes.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/GlobalVariable.h"
30 #include "llvm/IR/Instructions.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/IR/Metadata.h"
33 #include "llvm/IR/Value.h"
34 #include "llvm/Support/Casting.h"
35 #include <cassert>
36 #include <cstdint>
37 
38 namespace llvm {
39 
40   /// A wrapper class for inspecting calls to intrinsic functions.
41   /// This allows the standard isa/dyncast/cast functionality to work with calls
42   /// to intrinsic functions.
43   class IntrinsicInst : public CallInst {
44   public:
45     IntrinsicInst() = delete;
46     IntrinsicInst(const IntrinsicInst &) = delete;
47     IntrinsicInst &operator=(const IntrinsicInst &) = delete;
48 
49     /// Return the intrinsic ID of this intrinsic.
50     Intrinsic::ID getIntrinsicID() const {
51       return getCalledFunction()->getIntrinsicID();
52     }
53 
54     // Methods for support type inquiry through isa, cast, and dyn_cast:
55     static bool classof(const CallInst *I) {
56       if (const Function *CF = I->getCalledFunction())
57         return CF->isIntrinsic();
58       return false;
59     }
60     static bool classof(const Value *V) {
61       return isa<CallInst>(V) && classof(cast<CallInst>(V));
62     }
63   };
64 
65   /// This is the common base class for debug info intrinsics.
66   class DbgInfoIntrinsic : public IntrinsicInst {
67   public:
68     /// \name Casting methods
69     /// @{
70     static bool classof(const IntrinsicInst *I) {
71       switch (I->getIntrinsicID()) {
72       case Intrinsic::dbg_declare:
73       case Intrinsic::dbg_value:
74       case Intrinsic::dbg_addr:
75       case Intrinsic::dbg_label:
76         return true;
77       default: return false;
78       }
79     }
80     static bool classof(const Value *V) {
81       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
82     }
83     /// @}
84   };
85 
86   /// This is the common base class for debug info intrinsics for variables.
87   class DbgVariableIntrinsic : public DbgInfoIntrinsic {
88   public:
89     /// Get the location corresponding to the variable referenced by the debug
90     /// info intrinsic.  Depending on the intrinsic, this could be the
91     /// variable's value or its address.
92     Value *getVariableLocation(bool AllowNullOp = true) const;
93 
94     /// Does this describe the address of a local variable. True for dbg.addr
95     /// and dbg.declare, but not dbg.value, which describes its value.
96     bool isAddressOfVariable() const {
97       return getIntrinsicID() != Intrinsic::dbg_value;
98     }
99 
100     DILocalVariable *getVariable() const {
101       return cast<DILocalVariable>(getRawVariable());
102     }
103 
104     DIExpression *getExpression() const {
105       return cast<DIExpression>(getRawExpression());
106     }
107 
108     Metadata *getRawVariable() const {
109       return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
110     }
111 
112     Metadata *getRawExpression() const {
113       return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
114     }
115 
116     /// Get the size (in bits) of the variable, or fragment of the variable that
117     /// is described.
118     Optional<uint64_t> getFragmentSizeInBits() const;
119 
120     /// \name Casting methods
121     /// @{
122     static bool classof(const IntrinsicInst *I) {
123       switch (I->getIntrinsicID()) {
124       case Intrinsic::dbg_declare:
125       case Intrinsic::dbg_value:
126       case Intrinsic::dbg_addr:
127         return true;
128       default: return false;
129       }
130     }
131     static bool classof(const Value *V) {
132       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
133     }
134     /// @}
135   };
136 
137   /// This represents the llvm.dbg.declare instruction.
138   class DbgDeclareInst : public DbgVariableIntrinsic {
139   public:
140     Value *getAddress() const { return getVariableLocation(); }
141 
142     /// \name Casting methods
143     /// @{
144     static bool classof(const IntrinsicInst *I) {
145       return I->getIntrinsicID() == Intrinsic::dbg_declare;
146     }
147     static bool classof(const Value *V) {
148       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
149     }
150     /// @}
151   };
152 
153   /// This represents the llvm.dbg.addr instruction.
154   class DbgAddrIntrinsic : public DbgVariableIntrinsic {
155   public:
156     Value *getAddress() const { return getVariableLocation(); }
157 
158     /// \name Casting methods
159     /// @{
160     static bool classof(const IntrinsicInst *I) {
161       return I->getIntrinsicID() == Intrinsic::dbg_addr;
162     }
163     static bool classof(const Value *V) {
164       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
165     }
166   };
167 
168   /// This represents the llvm.dbg.value instruction.
169   class DbgValueInst : public DbgVariableIntrinsic {
170   public:
171     Value *getValue() const {
172       return getVariableLocation(/* AllowNullOp = */ false);
173     }
174 
175     /// \name Casting methods
176     /// @{
177     static bool classof(const IntrinsicInst *I) {
178       return I->getIntrinsicID() == Intrinsic::dbg_value;
179     }
180     static bool classof(const Value *V) {
181       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
182     }
183     /// @}
184   };
185 
186   /// This represents the llvm.dbg.label instruction.
187   class DbgLabelInst : public DbgInfoIntrinsic {
188   public:
189     DILabel *getLabel() const {
190       return cast<DILabel>(getRawLabel());
191     }
192 
193     Metadata *getRawLabel() const {
194       return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
195     }
196 
197     /// Methods for support type inquiry through isa, cast, and dyn_cast:
198     /// @{
199     static bool classof(const IntrinsicInst *I) {
200       return I->getIntrinsicID() == Intrinsic::dbg_label;
201     }
202     static bool classof(const Value *V) {
203       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
204     }
205     /// @}
206   };
207 
208   /// This is the common base class for constrained floating point intrinsics.
209   class ConstrainedFPIntrinsic : public IntrinsicInst {
210   public:
211     /// Specifies the rounding mode to be assumed. This is only used when
212     /// when constrained floating point is enabled. See the LLVM Language
213     /// Reference Manual for details.
214     enum RoundingMode : uint8_t {
215       rmDynamic,         ///< This corresponds to "fpround.dynamic".
216       rmToNearest,       ///< This corresponds to "fpround.tonearest".
217       rmDownward,        ///< This corresponds to "fpround.downward".
218       rmUpward,          ///< This corresponds to "fpround.upward".
219       rmTowardZero       ///< This corresponds to "fpround.tozero".
220     };
221 
222     /// Specifies the required exception behavior. This is only used when
223     /// when constrained floating point is used. See the LLVM Language
224     /// Reference Manual for details.
225     enum ExceptionBehavior : uint8_t {
226       ebIgnore,          ///< This corresponds to "fpexcept.ignore".
227       ebMayTrap,         ///< This corresponds to "fpexcept.maytrap".
228       ebStrict           ///< This corresponds to "fpexcept.strict".
229     };
230 
231     bool isUnaryOp() const;
232     bool isTernaryOp() const;
233     Optional<RoundingMode> getRoundingMode() const;
234     Optional<ExceptionBehavior> getExceptionBehavior() const;
235 
236     /// Returns a valid RoundingMode enumerator when given a string
237     /// that is valid as input in constrained intrinsic rounding mode
238     /// metadata.
239     static Optional<RoundingMode> StrToRoundingMode(StringRef);
240 
241     /// For any RoundingMode enumerator, returns a string valid as input in
242     /// constrained intrinsic rounding mode metadata.
243     static Optional<StringRef> RoundingModeToStr(RoundingMode);
244 
245     /// Returns a valid ExceptionBehavior enumerator when given a string
246     /// valid as input in constrained intrinsic exception behavior metadata.
247     static Optional<ExceptionBehavior> StrToExceptionBehavior(StringRef);
248 
249     /// For any ExceptionBehavior enumerator, returns a string valid as
250     /// input in constrained intrinsic exception behavior metadata.
251     static Optional<StringRef> ExceptionBehaviorToStr(ExceptionBehavior);
252 
253     // Methods for support type inquiry through isa, cast, and dyn_cast:
254     static bool classof(const IntrinsicInst *I) {
255       switch (I->getIntrinsicID()) {
256       case Intrinsic::experimental_constrained_fadd:
257       case Intrinsic::experimental_constrained_fsub:
258       case Intrinsic::experimental_constrained_fmul:
259       case Intrinsic::experimental_constrained_fdiv:
260       case Intrinsic::experimental_constrained_frem:
261       case Intrinsic::experimental_constrained_fma:
262       case Intrinsic::experimental_constrained_fptosi:
263       case Intrinsic::experimental_constrained_fptoui:
264       case Intrinsic::experimental_constrained_fptrunc:
265       case Intrinsic::experimental_constrained_fpext:
266       case Intrinsic::experimental_constrained_sqrt:
267       case Intrinsic::experimental_constrained_pow:
268       case Intrinsic::experimental_constrained_powi:
269       case Intrinsic::experimental_constrained_sin:
270       case Intrinsic::experimental_constrained_cos:
271       case Intrinsic::experimental_constrained_exp:
272       case Intrinsic::experimental_constrained_exp2:
273       case Intrinsic::experimental_constrained_log:
274       case Intrinsic::experimental_constrained_log10:
275       case Intrinsic::experimental_constrained_log2:
276       case Intrinsic::experimental_constrained_lrint:
277       case Intrinsic::experimental_constrained_llrint:
278       case Intrinsic::experimental_constrained_rint:
279       case Intrinsic::experimental_constrained_nearbyint:
280       case Intrinsic::experimental_constrained_maxnum:
281       case Intrinsic::experimental_constrained_minnum:
282       case Intrinsic::experimental_constrained_ceil:
283       case Intrinsic::experimental_constrained_floor:
284       case Intrinsic::experimental_constrained_lround:
285       case Intrinsic::experimental_constrained_llround:
286       case Intrinsic::experimental_constrained_round:
287       case Intrinsic::experimental_constrained_trunc:
288         return true;
289       default: return false;
290       }
291     }
292     static bool classof(const Value *V) {
293       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
294     }
295   };
296 
297   /// This class represents an intrinsic that is based on a binary operation.
298   /// This includes op.with.overflow and saturating add/sub intrinsics.
299   class BinaryOpIntrinsic : public IntrinsicInst {
300   public:
301     static bool classof(const IntrinsicInst *I) {
302       switch (I->getIntrinsicID()) {
303       case Intrinsic::uadd_with_overflow:
304       case Intrinsic::sadd_with_overflow:
305       case Intrinsic::usub_with_overflow:
306       case Intrinsic::ssub_with_overflow:
307       case Intrinsic::umul_with_overflow:
308       case Intrinsic::smul_with_overflow:
309       case Intrinsic::uadd_sat:
310       case Intrinsic::sadd_sat:
311       case Intrinsic::usub_sat:
312       case Intrinsic::ssub_sat:
313         return true;
314       default:
315         return false;
316       }
317     }
318     static bool classof(const Value *V) {
319       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
320     }
321 
322     Value *getLHS() const { return const_cast<Value*>(getArgOperand(0)); }
323     Value *getRHS() const { return const_cast<Value*>(getArgOperand(1)); }
324 
325     /// Returns the binary operation underlying the intrinsic.
326     Instruction::BinaryOps getBinaryOp() const;
327 
328     /// Whether the intrinsic is signed or unsigned.
329     bool isSigned() const;
330 
331     /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
332     unsigned getNoWrapKind() const;
333   };
334 
335   /// Represents an op.with.overflow intrinsic.
336   class WithOverflowInst : public BinaryOpIntrinsic {
337   public:
338     static bool classof(const IntrinsicInst *I) {
339       switch (I->getIntrinsicID()) {
340       case Intrinsic::uadd_with_overflow:
341       case Intrinsic::sadd_with_overflow:
342       case Intrinsic::usub_with_overflow:
343       case Intrinsic::ssub_with_overflow:
344       case Intrinsic::umul_with_overflow:
345       case Intrinsic::smul_with_overflow:
346         return true;
347       default:
348         return false;
349       }
350     }
351     static bool classof(const Value *V) {
352       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
353     }
354   };
355 
356   /// Represents a saturating add/sub intrinsic.
357   class SaturatingInst : public BinaryOpIntrinsic {
358   public:
359     static bool classof(const IntrinsicInst *I) {
360       switch (I->getIntrinsicID()) {
361       case Intrinsic::uadd_sat:
362       case Intrinsic::sadd_sat:
363       case Intrinsic::usub_sat:
364       case Intrinsic::ssub_sat:
365         return true;
366       default:
367         return false;
368       }
369     }
370     static bool classof(const Value *V) {
371       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
372     }
373   };
374 
375   /// Common base class for all memory intrinsics. Simply provides
376   /// common methods.
377   /// Written as CRTP to avoid a common base class amongst the
378   /// three atomicity hierarchies.
379   template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
380   private:
381     enum { ARG_DEST = 0, ARG_LENGTH = 2 };
382 
383   public:
384     Value *getRawDest() const {
385       return const_cast<Value *>(getArgOperand(ARG_DEST));
386     }
387     const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
388     Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
389 
390     Value *getLength() const {
391       return const_cast<Value *>(getArgOperand(ARG_LENGTH));
392     }
393     const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
394     Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
395 
396     /// This is just like getRawDest, but it strips off any cast
397     /// instructions (including addrspacecast) that feed it, giving the
398     /// original input.  The returned value is guaranteed to be a pointer.
399     Value *getDest() const { return getRawDest()->stripPointerCasts(); }
400 
401     unsigned getDestAddressSpace() const {
402       return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
403     }
404 
405     unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST); }
406 
407     /// Set the specified arguments of the instruction.
408     void setDest(Value *Ptr) {
409       assert(getRawDest()->getType() == Ptr->getType() &&
410              "setDest called with pointer of wrong type!");
411       setArgOperand(ARG_DEST, Ptr);
412     }
413 
414     void setDestAlignment(unsigned Alignment) {
415       removeParamAttr(ARG_DEST, Attribute::Alignment);
416       if (Alignment > 0)
417         addParamAttr(ARG_DEST, Attribute::getWithAlignment(getContext(),
418                                                            Align(Alignment)));
419     }
420 
421     void setLength(Value *L) {
422       assert(getLength()->getType() == L->getType() &&
423              "setLength called with value of wrong type!");
424       setArgOperand(ARG_LENGTH, L);
425     }
426   };
427 
428   /// Common base class for all memory transfer intrinsics. Simply provides
429   /// common methods.
430   template <class BaseCL> class MemTransferBase : public BaseCL {
431   private:
432     enum { ARG_SOURCE = 1 };
433 
434   public:
435     /// Return the arguments to the instruction.
436     Value *getRawSource() const {
437       return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
438     }
439     const Use &getRawSourceUse() const {
440       return BaseCL::getArgOperandUse(ARG_SOURCE);
441     }
442     Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
443 
444     /// This is just like getRawSource, but it strips off any cast
445     /// instructions that feed it, giving the original input.  The returned
446     /// value is guaranteed to be a pointer.
447     Value *getSource() const { return getRawSource()->stripPointerCasts(); }
448 
449     unsigned getSourceAddressSpace() const {
450       return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
451     }
452 
453     unsigned getSourceAlignment() const {
454       return BaseCL::getParamAlignment(ARG_SOURCE);
455     }
456 
457     void setSource(Value *Ptr) {
458       assert(getRawSource()->getType() == Ptr->getType() &&
459              "setSource called with pointer of wrong type!");
460       BaseCL::setArgOperand(ARG_SOURCE, Ptr);
461     }
462 
463     void setSourceAlignment(unsigned Alignment) {
464       BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
465       if (Alignment > 0)
466         BaseCL::addParamAttr(ARG_SOURCE,
467                              Attribute::getWithAlignment(BaseCL::getContext(),
468                                                          Align(Alignment)));
469     }
470   };
471 
472   /// Common base class for all memset intrinsics. Simply provides
473   /// common methods.
474   template <class BaseCL> class MemSetBase : public BaseCL {
475   private:
476     enum { ARG_VALUE = 1 };
477 
478   public:
479     Value *getValue() const {
480       return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
481     }
482     const Use &getValueUse() const {
483       return BaseCL::getArgOperandUse(ARG_VALUE);
484     }
485     Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
486 
487     void setValue(Value *Val) {
488       assert(getValue()->getType() == Val->getType() &&
489              "setValue called with value of wrong type!");
490       BaseCL::setArgOperand(ARG_VALUE, Val);
491     }
492   };
493 
494   // The common base class for the atomic memset/memmove/memcpy intrinsics
495   // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
496   class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
497   private:
498     enum { ARG_ELEMENTSIZE = 3 };
499 
500   public:
501     Value *getRawElementSizeInBytes() const {
502       return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
503     }
504 
505     ConstantInt *getElementSizeInBytesCst() const {
506       return cast<ConstantInt>(getRawElementSizeInBytes());
507     }
508 
509     uint32_t getElementSizeInBytes() const {
510       return getElementSizeInBytesCst()->getZExtValue();
511     }
512 
513     void setElementSizeInBytes(Constant *V) {
514       assert(V->getType() == Type::getInt8Ty(getContext()) &&
515              "setElementSizeInBytes called with value of wrong type!");
516       setArgOperand(ARG_ELEMENTSIZE, V);
517     }
518 
519     static bool classof(const IntrinsicInst *I) {
520       switch (I->getIntrinsicID()) {
521       case Intrinsic::memcpy_element_unordered_atomic:
522       case Intrinsic::memmove_element_unordered_atomic:
523       case Intrinsic::memset_element_unordered_atomic:
524         return true;
525       default:
526         return false;
527       }
528     }
529     static bool classof(const Value *V) {
530       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
531     }
532   };
533 
534   /// This class represents atomic memset intrinsic
535   // i.e. llvm.element.unordered.atomic.memset
536   class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
537   public:
538     static bool classof(const IntrinsicInst *I) {
539       return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
540     }
541     static bool classof(const Value *V) {
542       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
543     }
544   };
545 
546   // This class wraps the atomic memcpy/memmove intrinsics
547   // i.e. llvm.element.unordered.atomic.memcpy/memmove
548   class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
549   public:
550     static bool classof(const IntrinsicInst *I) {
551       switch (I->getIntrinsicID()) {
552       case Intrinsic::memcpy_element_unordered_atomic:
553       case Intrinsic::memmove_element_unordered_atomic:
554         return true;
555       default:
556         return false;
557       }
558     }
559     static bool classof(const Value *V) {
560       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
561     }
562   };
563 
564   /// This class represents the atomic memcpy intrinsic
565   /// i.e. llvm.element.unordered.atomic.memcpy
566   class AtomicMemCpyInst : public AtomicMemTransferInst {
567   public:
568     static bool classof(const IntrinsicInst *I) {
569       return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
570     }
571     static bool classof(const Value *V) {
572       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
573     }
574   };
575 
576   /// This class represents the atomic memmove intrinsic
577   /// i.e. llvm.element.unordered.atomic.memmove
578   class AtomicMemMoveInst : public AtomicMemTransferInst {
579   public:
580     static bool classof(const IntrinsicInst *I) {
581       return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
582     }
583     static bool classof(const Value *V) {
584       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
585     }
586   };
587 
588   /// This is the common base class for memset/memcpy/memmove.
589   class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
590   private:
591     enum { ARG_VOLATILE = 3 };
592 
593   public:
594     ConstantInt *getVolatileCst() const {
595       return cast<ConstantInt>(
596           const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
597     }
598 
599     bool isVolatile() const {
600       return !getVolatileCst()->isZero();
601     }
602 
603     void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
604 
605     // Methods for support type inquiry through isa, cast, and dyn_cast:
606     static bool classof(const IntrinsicInst *I) {
607       switch (I->getIntrinsicID()) {
608       case Intrinsic::memcpy:
609       case Intrinsic::memmove:
610       case Intrinsic::memset:
611         return true;
612       default: return false;
613       }
614     }
615     static bool classof(const Value *V) {
616       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
617     }
618   };
619 
620   /// This class wraps the llvm.memset intrinsic.
621   class MemSetInst : public MemSetBase<MemIntrinsic> {
622   public:
623     // Methods for support type inquiry through isa, cast, and dyn_cast:
624     static bool classof(const IntrinsicInst *I) {
625       return I->getIntrinsicID() == Intrinsic::memset;
626     }
627     static bool classof(const Value *V) {
628       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
629     }
630   };
631 
632   /// This class wraps the llvm.memcpy/memmove intrinsics.
633   class MemTransferInst : public MemTransferBase<MemIntrinsic> {
634   public:
635     // Methods for support type inquiry through isa, cast, and dyn_cast:
636     static bool classof(const IntrinsicInst *I) {
637       return I->getIntrinsicID() == Intrinsic::memcpy ||
638              I->getIntrinsicID() == Intrinsic::memmove;
639     }
640     static bool classof(const Value *V) {
641       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
642     }
643   };
644 
645   /// This class wraps the llvm.memcpy intrinsic.
646   class MemCpyInst : public MemTransferInst {
647   public:
648     // Methods for support type inquiry through isa, cast, and dyn_cast:
649     static bool classof(const IntrinsicInst *I) {
650       return I->getIntrinsicID() == Intrinsic::memcpy;
651     }
652     static bool classof(const Value *V) {
653       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
654     }
655   };
656 
657   /// This class wraps the llvm.memmove intrinsic.
658   class MemMoveInst : public MemTransferInst {
659   public:
660     // Methods for support type inquiry through isa, cast, and dyn_cast:
661     static bool classof(const IntrinsicInst *I) {
662       return I->getIntrinsicID() == Intrinsic::memmove;
663     }
664     static bool classof(const Value *V) {
665       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
666     }
667   };
668 
669   // The common base class for any memset/memmove/memcpy intrinsics;
670   // whether they be atomic or non-atomic.
671   // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
672   //  and llvm.memset/memcpy/memmove
673   class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
674   public:
675     bool isVolatile() const {
676       // Only the non-atomic intrinsics can be volatile
677       if (auto *MI = dyn_cast<MemIntrinsic>(this))
678         return MI->isVolatile();
679       return false;
680     }
681 
682     static bool classof(const IntrinsicInst *I) {
683       switch (I->getIntrinsicID()) {
684       case Intrinsic::memcpy:
685       case Intrinsic::memmove:
686       case Intrinsic::memset:
687       case Intrinsic::memcpy_element_unordered_atomic:
688       case Intrinsic::memmove_element_unordered_atomic:
689       case Intrinsic::memset_element_unordered_atomic:
690         return true;
691       default:
692         return false;
693       }
694     }
695     static bool classof(const Value *V) {
696       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
697     }
698   };
699 
700   /// This class represents any memset intrinsic
701   // i.e. llvm.element.unordered.atomic.memset
702   // and  llvm.memset
703   class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
704   public:
705     static bool classof(const IntrinsicInst *I) {
706       switch (I->getIntrinsicID()) {
707       case Intrinsic::memset:
708       case Intrinsic::memset_element_unordered_atomic:
709         return true;
710       default:
711         return false;
712       }
713     }
714     static bool classof(const Value *V) {
715       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
716     }
717   };
718 
719   // This class wraps any memcpy/memmove intrinsics
720   // i.e. llvm.element.unordered.atomic.memcpy/memmove
721   // and  llvm.memcpy/memmove
722   class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
723   public:
724     static bool classof(const IntrinsicInst *I) {
725       switch (I->getIntrinsicID()) {
726       case Intrinsic::memcpy:
727       case Intrinsic::memmove:
728       case Intrinsic::memcpy_element_unordered_atomic:
729       case Intrinsic::memmove_element_unordered_atomic:
730         return true;
731       default:
732         return false;
733       }
734     }
735     static bool classof(const Value *V) {
736       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
737     }
738   };
739 
740   /// This class represents any memcpy intrinsic
741   /// i.e. llvm.element.unordered.atomic.memcpy
742   ///  and llvm.memcpy
743   class AnyMemCpyInst : public AnyMemTransferInst {
744   public:
745     static bool classof(const IntrinsicInst *I) {
746       switch (I->getIntrinsicID()) {
747       case Intrinsic::memcpy:
748       case Intrinsic::memcpy_element_unordered_atomic:
749         return true;
750       default:
751         return false;
752       }
753     }
754     static bool classof(const Value *V) {
755       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
756     }
757   };
758 
759   /// This class represents any memmove intrinsic
760   /// i.e. llvm.element.unordered.atomic.memmove
761   ///  and llvm.memmove
762   class AnyMemMoveInst : public AnyMemTransferInst {
763   public:
764     static bool classof(const IntrinsicInst *I) {
765       switch (I->getIntrinsicID()) {
766       case Intrinsic::memmove:
767       case Intrinsic::memmove_element_unordered_atomic:
768         return true;
769       default:
770         return false;
771       }
772     }
773     static bool classof(const Value *V) {
774       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
775     }
776   };
777 
778   /// This represents the llvm.va_start intrinsic.
779   class VAStartInst : public IntrinsicInst {
780   public:
781     static bool classof(const IntrinsicInst *I) {
782       return I->getIntrinsicID() == Intrinsic::vastart;
783     }
784     static bool classof(const Value *V) {
785       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
786     }
787 
788     Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
789   };
790 
791   /// This represents the llvm.va_end intrinsic.
792   class VAEndInst : public IntrinsicInst {
793   public:
794     static bool classof(const IntrinsicInst *I) {
795       return I->getIntrinsicID() == Intrinsic::vaend;
796     }
797     static bool classof(const Value *V) {
798       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
799     }
800 
801     Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
802   };
803 
804   /// This represents the llvm.va_copy intrinsic.
805   class VACopyInst : public IntrinsicInst {
806   public:
807     static bool classof(const IntrinsicInst *I) {
808       return I->getIntrinsicID() == Intrinsic::vacopy;
809     }
810     static bool classof(const Value *V) {
811       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
812     }
813 
814     Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); }
815     Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); }
816   };
817 
818   /// This represents the llvm.instrprof_increment intrinsic.
819   class InstrProfIncrementInst : public IntrinsicInst {
820   public:
821     static bool classof(const IntrinsicInst *I) {
822       return I->getIntrinsicID() == Intrinsic::instrprof_increment;
823     }
824     static bool classof(const Value *V) {
825       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
826     }
827 
828     GlobalVariable *getName() const {
829       return cast<GlobalVariable>(
830           const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
831     }
832 
833     ConstantInt *getHash() const {
834       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
835     }
836 
837     ConstantInt *getNumCounters() const {
838       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
839     }
840 
841     ConstantInt *getIndex() const {
842       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
843     }
844 
845     Value *getStep() const;
846   };
847 
848   class InstrProfIncrementInstStep : public InstrProfIncrementInst {
849   public:
850     static bool classof(const IntrinsicInst *I) {
851       return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
852     }
853     static bool classof(const Value *V) {
854       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
855     }
856   };
857 
858   /// This represents the llvm.instrprof_value_profile intrinsic.
859   class InstrProfValueProfileInst : public IntrinsicInst {
860   public:
861     static bool classof(const IntrinsicInst *I) {
862       return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
863     }
864     static bool classof(const Value *V) {
865       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
866     }
867 
868     GlobalVariable *getName() const {
869       return cast<GlobalVariable>(
870           const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
871     }
872 
873     ConstantInt *getHash() const {
874       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
875     }
876 
877     Value *getTargetValue() const {
878       return cast<Value>(const_cast<Value *>(getArgOperand(2)));
879     }
880 
881     ConstantInt *getValueKind() const {
882       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
883     }
884 
885     // Returns the value site index.
886     ConstantInt *getIndex() const {
887       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
888     }
889   };
890 
891 } // end namespace llvm
892 
893 #endif // LLVM_IR_INTRINSICINST_H
894