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