xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h (revision 31ba4ce8898f9dfa5e7f054fdbc26e50a599a6e3)
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   /// Return true if swapping the first two arguments to the intrinsic produces
56   /// the same result.
57   bool isCommutative() const {
58     switch (getIntrinsicID()) {
59     case Intrinsic::maxnum:
60     case Intrinsic::minnum:
61     case Intrinsic::maximum:
62     case Intrinsic::minimum:
63     case Intrinsic::smax:
64     case Intrinsic::smin:
65     case Intrinsic::umax:
66     case Intrinsic::umin:
67     case Intrinsic::sadd_sat:
68     case Intrinsic::uadd_sat:
69     case Intrinsic::sadd_with_overflow:
70     case Intrinsic::uadd_with_overflow:
71     case Intrinsic::smul_with_overflow:
72     case Intrinsic::umul_with_overflow:
73     case Intrinsic::smul_fix:
74     case Intrinsic::umul_fix:
75     case Intrinsic::smul_fix_sat:
76     case Intrinsic::umul_fix_sat:
77     case Intrinsic::fma:
78     case Intrinsic::fmuladd:
79       return true;
80     default:
81       return false;
82     }
83   }
84 
85   // Methods for support type inquiry through isa, cast, and dyn_cast:
86   static bool classof(const CallInst *I) {
87     if (const Function *CF = I->getCalledFunction())
88       return CF->isIntrinsic();
89     return false;
90   }
91   static bool classof(const Value *V) {
92     return isa<CallInst>(V) && classof(cast<CallInst>(V));
93   }
94 };
95 
96 /// Check if \p ID corresponds to a debug info intrinsic.
97 static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) {
98   switch (ID) {
99   case Intrinsic::dbg_declare:
100   case Intrinsic::dbg_value:
101   case Intrinsic::dbg_addr:
102   case Intrinsic::dbg_label:
103     return true;
104   default:
105     return false;
106   }
107 }
108 
109 /// This is the common base class for debug info intrinsics.
110 class DbgInfoIntrinsic : public IntrinsicInst {
111 public:
112   /// \name Casting methods
113   /// @{
114   static bool classof(const IntrinsicInst *I) {
115     return isDbgInfoIntrinsic(I->getIntrinsicID());
116   }
117   static bool classof(const Value *V) {
118     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
119   }
120   /// @}
121 };
122 
123 /// This is the common base class for debug info intrinsics for variables.
124 class DbgVariableIntrinsic : public DbgInfoIntrinsic {
125 public:
126   /// Get the location corresponding to the variable referenced by the debug
127   /// info intrinsic.  Depending on the intrinsic, this could be the
128   /// variable's value or its address.
129   Value *getVariableLocation(bool AllowNullOp = true) const;
130 
131   /// Does this describe the address of a local variable. True for dbg.addr
132   /// and dbg.declare, but not dbg.value, which describes its value.
133   bool isAddressOfVariable() const {
134     return getIntrinsicID() != Intrinsic::dbg_value;
135   }
136 
137   DILocalVariable *getVariable() const {
138     return cast<DILocalVariable>(getRawVariable());
139   }
140 
141   DIExpression *getExpression() const {
142     return cast<DIExpression>(getRawExpression());
143   }
144 
145   Metadata *getRawVariable() const {
146     return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
147   }
148 
149   Metadata *getRawExpression() const {
150     return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
151   }
152 
153   /// Get the size (in bits) of the variable, or fragment of the variable that
154   /// is described.
155   Optional<uint64_t> getFragmentSizeInBits() const;
156 
157   /// \name Casting methods
158   /// @{
159   static bool classof(const IntrinsicInst *I) {
160     switch (I->getIntrinsicID()) {
161     case Intrinsic::dbg_declare:
162     case Intrinsic::dbg_value:
163     case Intrinsic::dbg_addr:
164       return true;
165     default:
166       return false;
167     }
168   }
169   static bool classof(const Value *V) {
170     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
171   }
172   /// @}
173 };
174 
175 /// This represents the llvm.dbg.declare instruction.
176 class DbgDeclareInst : public DbgVariableIntrinsic {
177 public:
178   Value *getAddress() const { return getVariableLocation(); }
179 
180   /// \name Casting methods
181   /// @{
182   static bool classof(const IntrinsicInst *I) {
183     return I->getIntrinsicID() == Intrinsic::dbg_declare;
184   }
185   static bool classof(const Value *V) {
186     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
187   }
188   /// @}
189 };
190 
191 /// This represents the llvm.dbg.addr instruction.
192 class DbgAddrIntrinsic : public DbgVariableIntrinsic {
193 public:
194   Value *getAddress() const { return getVariableLocation(); }
195 
196   /// \name Casting methods
197   /// @{
198   static bool classof(const IntrinsicInst *I) {
199     return I->getIntrinsicID() == Intrinsic::dbg_addr;
200   }
201   static bool classof(const Value *V) {
202     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
203   }
204 };
205 
206 /// This represents the llvm.dbg.value instruction.
207 class DbgValueInst : public DbgVariableIntrinsic {
208 public:
209   Value *getValue() const {
210     return getVariableLocation(/* AllowNullOp = */ false);
211   }
212 
213   /// \name Casting methods
214   /// @{
215   static bool classof(const IntrinsicInst *I) {
216     return I->getIntrinsicID() == Intrinsic::dbg_value;
217   }
218   static bool classof(const Value *V) {
219     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
220   }
221   /// @}
222 };
223 
224 /// This represents the llvm.dbg.label instruction.
225 class DbgLabelInst : public DbgInfoIntrinsic {
226 public:
227   DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); }
228 
229   Metadata *getRawLabel() const {
230     return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
231   }
232 
233   /// Methods for support type inquiry through isa, cast, and dyn_cast:
234   /// @{
235   static bool classof(const IntrinsicInst *I) {
236     return I->getIntrinsicID() == Intrinsic::dbg_label;
237   }
238   static bool classof(const Value *V) {
239     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
240   }
241   /// @}
242 };
243 
244 /// This is the common base class for vector predication intrinsics.
245 class VPIntrinsic : public IntrinsicInst {
246 public:
247   static Optional<int> GetMaskParamPos(Intrinsic::ID IntrinsicID);
248   static Optional<int> GetVectorLengthParamPos(Intrinsic::ID IntrinsicID);
249 
250   /// The llvm.vp.* intrinsics for this instruction Opcode
251   static Intrinsic::ID GetForOpcode(unsigned OC);
252 
253   // Whether \p ID is a VP intrinsic ID.
254   static bool IsVPIntrinsic(Intrinsic::ID);
255 
256   /// \return the mask parameter or nullptr.
257   Value *getMaskParam() const;
258 
259   /// \return the vector length parameter or nullptr.
260   Value *getVectorLengthParam() const;
261 
262   /// \return whether the vector length param can be ignored.
263   bool canIgnoreVectorLengthParam() const;
264 
265   /// \return the static element count (vector number of elements) the vector
266   /// length parameter applies to.
267   ElementCount getStaticVectorLength() const;
268 
269   // Methods for support type inquiry through isa, cast, and dyn_cast:
270   static bool classof(const IntrinsicInst *I) {
271     return IsVPIntrinsic(I->getIntrinsicID());
272   }
273   static bool classof(const Value *V) {
274     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
275   }
276 
277   // Equivalent non-predicated opcode
278   unsigned getFunctionalOpcode() const {
279     return GetFunctionalOpcodeForVP(getIntrinsicID());
280   }
281 
282   // Equivalent non-predicated opcode
283   static unsigned GetFunctionalOpcodeForVP(Intrinsic::ID ID);
284 };
285 
286 /// This is the common base class for constrained floating point intrinsics.
287 class ConstrainedFPIntrinsic : public IntrinsicInst {
288 public:
289   bool isUnaryOp() const;
290   bool isTernaryOp() const;
291   Optional<RoundingMode> getRoundingMode() const;
292   Optional<fp::ExceptionBehavior> getExceptionBehavior() const;
293 
294   // Methods for support type inquiry through isa, cast, and dyn_cast:
295   static bool classof(const IntrinsicInst *I);
296   static bool classof(const Value *V) {
297     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
298   }
299 };
300 
301 /// Constrained floating point compare intrinsics.
302 class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
303 public:
304   FCmpInst::Predicate getPredicate() const;
305 
306   // Methods for support type inquiry through isa, cast, and dyn_cast:
307   static bool classof(const IntrinsicInst *I) {
308     switch (I->getIntrinsicID()) {
309     case Intrinsic::experimental_constrained_fcmp:
310     case Intrinsic::experimental_constrained_fcmps:
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 /// This class represents an intrinsic that is based on a binary operation.
322 /// This includes op.with.overflow and saturating add/sub intrinsics.
323 class BinaryOpIntrinsic : public IntrinsicInst {
324 public:
325   static bool classof(const IntrinsicInst *I) {
326     switch (I->getIntrinsicID()) {
327     case Intrinsic::uadd_with_overflow:
328     case Intrinsic::sadd_with_overflow:
329     case Intrinsic::usub_with_overflow:
330     case Intrinsic::ssub_with_overflow:
331     case Intrinsic::umul_with_overflow:
332     case Intrinsic::smul_with_overflow:
333     case Intrinsic::uadd_sat:
334     case Intrinsic::sadd_sat:
335     case Intrinsic::usub_sat:
336     case Intrinsic::ssub_sat:
337       return true;
338     default:
339       return false;
340     }
341   }
342   static bool classof(const Value *V) {
343     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
344   }
345 
346   Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
347   Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); }
348 
349   /// Returns the binary operation underlying the intrinsic.
350   Instruction::BinaryOps getBinaryOp() const;
351 
352   /// Whether the intrinsic is signed or unsigned.
353   bool isSigned() const;
354 
355   /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
356   unsigned getNoWrapKind() const;
357 };
358 
359 /// Represents an op.with.overflow intrinsic.
360 class WithOverflowInst : public BinaryOpIntrinsic {
361 public:
362   static bool classof(const IntrinsicInst *I) {
363     switch (I->getIntrinsicID()) {
364     case Intrinsic::uadd_with_overflow:
365     case Intrinsic::sadd_with_overflow:
366     case Intrinsic::usub_with_overflow:
367     case Intrinsic::ssub_with_overflow:
368     case Intrinsic::umul_with_overflow:
369     case Intrinsic::smul_with_overflow:
370       return true;
371     default:
372       return false;
373     }
374   }
375   static bool classof(const Value *V) {
376     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
377   }
378 };
379 
380 /// Represents a saturating add/sub intrinsic.
381 class SaturatingInst : public BinaryOpIntrinsic {
382 public:
383   static bool classof(const IntrinsicInst *I) {
384     switch (I->getIntrinsicID()) {
385     case Intrinsic::uadd_sat:
386     case Intrinsic::sadd_sat:
387     case Intrinsic::usub_sat:
388     case Intrinsic::ssub_sat:
389       return true;
390     default:
391       return false;
392     }
393   }
394   static bool classof(const Value *V) {
395     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
396   }
397 };
398 
399 /// Common base class for all memory intrinsics. Simply provides
400 /// common methods.
401 /// Written as CRTP to avoid a common base class amongst the
402 /// three atomicity hierarchies.
403 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
404 private:
405   enum { ARG_DEST = 0, ARG_LENGTH = 2 };
406 
407 public:
408   Value *getRawDest() const {
409     return const_cast<Value *>(getArgOperand(ARG_DEST));
410   }
411   const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
412   Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
413 
414   Value *getLength() const {
415     return const_cast<Value *>(getArgOperand(ARG_LENGTH));
416   }
417   const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
418   Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
419 
420   /// This is just like getRawDest, but it strips off any cast
421   /// instructions (including addrspacecast) that feed it, giving the
422   /// original input.  The returned value is guaranteed to be a pointer.
423   Value *getDest() const { return getRawDest()->stripPointerCasts(); }
424 
425   unsigned getDestAddressSpace() const {
426     return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
427   }
428 
429   /// FIXME: Remove this function once transition to Align is over.
430   /// Use getDestAlign() instead.
431   unsigned getDestAlignment() const {
432     if (auto MA = getParamAlign(ARG_DEST))
433       return MA->value();
434     return 0;
435   }
436   MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); }
437 
438   /// Set the specified arguments of the instruction.
439   void setDest(Value *Ptr) {
440     assert(getRawDest()->getType() == Ptr->getType() &&
441            "setDest called with pointer of wrong type!");
442     setArgOperand(ARG_DEST, Ptr);
443   }
444 
445   /// FIXME: Remove this function once transition to Align is over.
446   /// Use the version that takes MaybeAlign instead of this one.
447   void setDestAlignment(unsigned Alignment) {
448     setDestAlignment(MaybeAlign(Alignment));
449   }
450   void setDestAlignment(MaybeAlign Alignment) {
451     removeParamAttr(ARG_DEST, Attribute::Alignment);
452     if (Alignment)
453       addParamAttr(ARG_DEST,
454                    Attribute::getWithAlignment(getContext(), *Alignment));
455   }
456   void setDestAlignment(Align Alignment) {
457     removeParamAttr(ARG_DEST, Attribute::Alignment);
458     addParamAttr(ARG_DEST,
459                  Attribute::getWithAlignment(getContext(), Alignment));
460   }
461 
462   void setLength(Value *L) {
463     assert(getLength()->getType() == L->getType() &&
464            "setLength called with value of wrong type!");
465     setArgOperand(ARG_LENGTH, L);
466   }
467 };
468 
469 /// Common base class for all memory transfer intrinsics. Simply provides
470 /// common methods.
471 template <class BaseCL> class MemTransferBase : public BaseCL {
472 private:
473   enum { ARG_SOURCE = 1 };
474 
475 public:
476   /// Return the arguments to the instruction.
477   Value *getRawSource() const {
478     return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
479   }
480   const Use &getRawSourceUse() const {
481     return BaseCL::getArgOperandUse(ARG_SOURCE);
482   }
483   Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
484 
485   /// This is just like getRawSource, but it strips off any cast
486   /// instructions that feed it, giving the original input.  The returned
487   /// value is guaranteed to be a pointer.
488   Value *getSource() const { return getRawSource()->stripPointerCasts(); }
489 
490   unsigned getSourceAddressSpace() const {
491     return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
492   }
493 
494   /// FIXME: Remove this function once transition to Align is over.
495   /// Use getSourceAlign() instead.
496   unsigned getSourceAlignment() const {
497     if (auto MA = BaseCL::getParamAlign(ARG_SOURCE))
498       return MA->value();
499     return 0;
500   }
501 
502   MaybeAlign getSourceAlign() const {
503     return BaseCL::getParamAlign(ARG_SOURCE);
504   }
505 
506   void setSource(Value *Ptr) {
507     assert(getRawSource()->getType() == Ptr->getType() &&
508            "setSource called with pointer of wrong type!");
509     BaseCL::setArgOperand(ARG_SOURCE, Ptr);
510   }
511 
512   /// FIXME: Remove this function once transition to Align is over.
513   /// Use the version that takes MaybeAlign instead of this one.
514   void setSourceAlignment(unsigned Alignment) {
515     setSourceAlignment(MaybeAlign(Alignment));
516   }
517   void setSourceAlignment(MaybeAlign Alignment) {
518     BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
519     if (Alignment)
520       BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
521                                            BaseCL::getContext(), *Alignment));
522   }
523   void setSourceAlignment(Align Alignment) {
524     BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
525     BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
526                                          BaseCL::getContext(), Alignment));
527   }
528 };
529 
530 /// Common base class for all memset intrinsics. Simply provides
531 /// common methods.
532 template <class BaseCL> class MemSetBase : public BaseCL {
533 private:
534   enum { ARG_VALUE = 1 };
535 
536 public:
537   Value *getValue() const {
538     return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
539   }
540   const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); }
541   Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
542 
543   void setValue(Value *Val) {
544     assert(getValue()->getType() == Val->getType() &&
545            "setValue called with value of wrong type!");
546     BaseCL::setArgOperand(ARG_VALUE, Val);
547   }
548 };
549 
550 // The common base class for the atomic memset/memmove/memcpy intrinsics
551 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
552 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
553 private:
554   enum { ARG_ELEMENTSIZE = 3 };
555 
556 public:
557   Value *getRawElementSizeInBytes() const {
558     return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
559   }
560 
561   ConstantInt *getElementSizeInBytesCst() const {
562     return cast<ConstantInt>(getRawElementSizeInBytes());
563   }
564 
565   uint32_t getElementSizeInBytes() const {
566     return getElementSizeInBytesCst()->getZExtValue();
567   }
568 
569   void setElementSizeInBytes(Constant *V) {
570     assert(V->getType() == Type::getInt8Ty(getContext()) &&
571            "setElementSizeInBytes called with value of wrong type!");
572     setArgOperand(ARG_ELEMENTSIZE, V);
573   }
574 
575   static bool classof(const IntrinsicInst *I) {
576     switch (I->getIntrinsicID()) {
577     case Intrinsic::memcpy_element_unordered_atomic:
578     case Intrinsic::memmove_element_unordered_atomic:
579     case Intrinsic::memset_element_unordered_atomic:
580       return true;
581     default:
582       return false;
583     }
584   }
585   static bool classof(const Value *V) {
586     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
587   }
588 };
589 
590 /// This class represents atomic memset intrinsic
591 // i.e. llvm.element.unordered.atomic.memset
592 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
593 public:
594   static bool classof(const IntrinsicInst *I) {
595     return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
596   }
597   static bool classof(const Value *V) {
598     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
599   }
600 };
601 
602 // This class wraps the atomic memcpy/memmove intrinsics
603 // i.e. llvm.element.unordered.atomic.memcpy/memmove
604 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
605 public:
606   static bool classof(const IntrinsicInst *I) {
607     switch (I->getIntrinsicID()) {
608     case Intrinsic::memcpy_element_unordered_atomic:
609     case Intrinsic::memmove_element_unordered_atomic:
610       return true;
611     default:
612       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 represents the atomic memcpy intrinsic
621 /// i.e. llvm.element.unordered.atomic.memcpy
622 class AtomicMemCpyInst : public AtomicMemTransferInst {
623 public:
624   static bool classof(const IntrinsicInst *I) {
625     return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
626   }
627   static bool classof(const Value *V) {
628     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
629   }
630 };
631 
632 /// This class represents the atomic memmove intrinsic
633 /// i.e. llvm.element.unordered.atomic.memmove
634 class AtomicMemMoveInst : public AtomicMemTransferInst {
635 public:
636   static bool classof(const IntrinsicInst *I) {
637     return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
638   }
639   static bool classof(const Value *V) {
640     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
641   }
642 };
643 
644 /// This is the common base class for memset/memcpy/memmove.
645 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
646 private:
647   enum { ARG_VOLATILE = 3 };
648 
649 public:
650   ConstantInt *getVolatileCst() const {
651     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
652   }
653 
654   bool isVolatile() const { return !getVolatileCst()->isZero(); }
655 
656   void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
657 
658   // Methods for support type inquiry through isa, cast, and dyn_cast:
659   static bool classof(const IntrinsicInst *I) {
660     switch (I->getIntrinsicID()) {
661     case Intrinsic::memcpy:
662     case Intrinsic::memmove:
663     case Intrinsic::memset:
664     case Intrinsic::memcpy_inline:
665       return true;
666     default:
667       return false;
668     }
669   }
670   static bool classof(const Value *V) {
671     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
672   }
673 };
674 
675 /// This class wraps the llvm.memset intrinsic.
676 class MemSetInst : public MemSetBase<MemIntrinsic> {
677 public:
678   // Methods for support type inquiry through isa, cast, and dyn_cast:
679   static bool classof(const IntrinsicInst *I) {
680     return I->getIntrinsicID() == Intrinsic::memset;
681   }
682   static bool classof(const Value *V) {
683     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
684   }
685 };
686 
687 /// This class wraps the llvm.memcpy/memmove intrinsics.
688 class MemTransferInst : public MemTransferBase<MemIntrinsic> {
689 public:
690   // Methods for support type inquiry through isa, cast, and dyn_cast:
691   static bool classof(const IntrinsicInst *I) {
692     switch (I->getIntrinsicID()) {
693     case Intrinsic::memcpy:
694     case Intrinsic::memmove:
695     case Intrinsic::memcpy_inline:
696       return true;
697     default:
698       return false;
699     }
700   }
701   static bool classof(const Value *V) {
702     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
703   }
704 };
705 
706 /// This class wraps the llvm.memcpy intrinsic.
707 class MemCpyInst : public MemTransferInst {
708 public:
709   // Methods for support type inquiry through isa, cast, and dyn_cast:
710   static bool classof(const IntrinsicInst *I) {
711     return I->getIntrinsicID() == Intrinsic::memcpy;
712   }
713   static bool classof(const Value *V) {
714     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
715   }
716 };
717 
718 /// This class wraps the llvm.memmove intrinsic.
719 class MemMoveInst : public MemTransferInst {
720 public:
721   // Methods for support type inquiry through isa, cast, and dyn_cast:
722   static bool classof(const IntrinsicInst *I) {
723     return I->getIntrinsicID() == Intrinsic::memmove;
724   }
725   static bool classof(const Value *V) {
726     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
727   }
728 };
729 
730 /// This class wraps the llvm.memcpy.inline intrinsic.
731 class MemCpyInlineInst : public MemTransferInst {
732 public:
733   ConstantInt *getLength() const {
734     return cast<ConstantInt>(MemTransferInst::getLength());
735   }
736   // Methods for support type inquiry through isa, cast, and dyn_cast:
737   static bool classof(const IntrinsicInst *I) {
738     return I->getIntrinsicID() == Intrinsic::memcpy_inline;
739   }
740   static bool classof(const Value *V) {
741     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
742   }
743 };
744 
745 // The common base class for any memset/memmove/memcpy intrinsics;
746 // whether they be atomic or non-atomic.
747 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
748 //  and llvm.memset/memcpy/memmove
749 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
750 public:
751   bool isVolatile() const {
752     // Only the non-atomic intrinsics can be volatile
753     if (auto *MI = dyn_cast<MemIntrinsic>(this))
754       return MI->isVolatile();
755     return false;
756   }
757 
758   static bool classof(const IntrinsicInst *I) {
759     switch (I->getIntrinsicID()) {
760     case Intrinsic::memcpy:
761     case Intrinsic::memcpy_inline:
762     case Intrinsic::memmove:
763     case Intrinsic::memset:
764     case Intrinsic::memcpy_element_unordered_atomic:
765     case Intrinsic::memmove_element_unordered_atomic:
766     case Intrinsic::memset_element_unordered_atomic:
767       return true;
768     default:
769       return false;
770     }
771   }
772   static bool classof(const Value *V) {
773     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
774   }
775 };
776 
777 /// This class represents any memset intrinsic
778 // i.e. llvm.element.unordered.atomic.memset
779 // and  llvm.memset
780 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
781 public:
782   static bool classof(const IntrinsicInst *I) {
783     switch (I->getIntrinsicID()) {
784     case Intrinsic::memset:
785     case Intrinsic::memset_element_unordered_atomic:
786       return true;
787     default:
788       return false;
789     }
790   }
791   static bool classof(const Value *V) {
792     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
793   }
794 };
795 
796 // This class wraps any memcpy/memmove intrinsics
797 // i.e. llvm.element.unordered.atomic.memcpy/memmove
798 // and  llvm.memcpy/memmove
799 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
800 public:
801   static bool classof(const IntrinsicInst *I) {
802     switch (I->getIntrinsicID()) {
803     case Intrinsic::memcpy:
804     case Intrinsic::memcpy_inline:
805     case Intrinsic::memmove:
806     case Intrinsic::memcpy_element_unordered_atomic:
807     case Intrinsic::memmove_element_unordered_atomic:
808       return true;
809     default:
810       return false;
811     }
812   }
813   static bool classof(const Value *V) {
814     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
815   }
816 };
817 
818 /// This class represents any memcpy intrinsic
819 /// i.e. llvm.element.unordered.atomic.memcpy
820 ///  and llvm.memcpy
821 class AnyMemCpyInst : public AnyMemTransferInst {
822 public:
823   static bool classof(const IntrinsicInst *I) {
824     switch (I->getIntrinsicID()) {
825     case Intrinsic::memcpy:
826     case Intrinsic::memcpy_inline:
827     case Intrinsic::memcpy_element_unordered_atomic:
828       return true;
829     default:
830       return false;
831     }
832   }
833   static bool classof(const Value *V) {
834     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
835   }
836 };
837 
838 /// This class represents any memmove intrinsic
839 /// i.e. llvm.element.unordered.atomic.memmove
840 ///  and llvm.memmove
841 class AnyMemMoveInst : public AnyMemTransferInst {
842 public:
843   static bool classof(const IntrinsicInst *I) {
844     switch (I->getIntrinsicID()) {
845     case Intrinsic::memmove:
846     case Intrinsic::memmove_element_unordered_atomic:
847       return true;
848     default:
849       return false;
850     }
851   }
852   static bool classof(const Value *V) {
853     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
854   }
855 };
856 
857 /// This represents the llvm.va_start intrinsic.
858 class VAStartInst : public IntrinsicInst {
859 public:
860   static bool classof(const IntrinsicInst *I) {
861     return I->getIntrinsicID() == Intrinsic::vastart;
862   }
863   static bool classof(const Value *V) {
864     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
865   }
866 
867   Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
868 };
869 
870 /// This represents the llvm.va_end intrinsic.
871 class VAEndInst : public IntrinsicInst {
872 public:
873   static bool classof(const IntrinsicInst *I) {
874     return I->getIntrinsicID() == Intrinsic::vaend;
875   }
876   static bool classof(const Value *V) {
877     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
878   }
879 
880   Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
881 };
882 
883 /// This represents the llvm.va_copy intrinsic.
884 class VACopyInst : public IntrinsicInst {
885 public:
886   static bool classof(const IntrinsicInst *I) {
887     return I->getIntrinsicID() == Intrinsic::vacopy;
888   }
889   static bool classof(const Value *V) {
890     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
891   }
892 
893   Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); }
894   Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); }
895 };
896 
897 /// This represents the llvm.instrprof_increment intrinsic.
898 class InstrProfIncrementInst : public IntrinsicInst {
899 public:
900   static bool classof(const IntrinsicInst *I) {
901     return I->getIntrinsicID() == Intrinsic::instrprof_increment;
902   }
903   static bool classof(const Value *V) {
904     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
905   }
906 
907   GlobalVariable *getName() const {
908     return cast<GlobalVariable>(
909         const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
910   }
911 
912   ConstantInt *getHash() const {
913     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
914   }
915 
916   ConstantInt *getNumCounters() const {
917     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
918   }
919 
920   ConstantInt *getIndex() const {
921     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
922   }
923 
924   Value *getStep() const;
925 };
926 
927 class InstrProfIncrementInstStep : public InstrProfIncrementInst {
928 public:
929   static bool classof(const IntrinsicInst *I) {
930     return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
931   }
932   static bool classof(const Value *V) {
933     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
934   }
935 };
936 
937 /// This represents the llvm.instrprof_value_profile intrinsic.
938 class InstrProfValueProfileInst : public IntrinsicInst {
939 public:
940   static bool classof(const IntrinsicInst *I) {
941     return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
942   }
943   static bool classof(const Value *V) {
944     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
945   }
946 
947   GlobalVariable *getName() const {
948     return cast<GlobalVariable>(
949         const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
950   }
951 
952   ConstantInt *getHash() const {
953     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
954   }
955 
956   Value *getTargetValue() const {
957     return cast<Value>(const_cast<Value *>(getArgOperand(2)));
958   }
959 
960   ConstantInt *getValueKind() const {
961     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
962   }
963 
964   // Returns the value site index.
965   ConstantInt *getIndex() const {
966     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
967   }
968 };
969 
970 class PseudoProbeInst : public IntrinsicInst {
971 public:
972   static bool classof(const IntrinsicInst *I) {
973     return I->getIntrinsicID() == Intrinsic::pseudoprobe;
974   }
975 
976   static bool classof(const Value *V) {
977     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
978   }
979 
980   ConstantInt *getFuncGuid() const {
981     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0)));
982   }
983 
984   ConstantInt *getIndex() const {
985     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
986   }
987 
988   ConstantInt *getAttributes() const {
989     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
990   }
991 
992   ConstantInt *getFactor() const {
993     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
994   }
995 };
996 
997 class NoAliasScopeDeclInst : public IntrinsicInst {
998 public:
999   static bool classof(const IntrinsicInst *I) {
1000     return I->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl;
1001   }
1002 
1003   static bool classof(const Value *V) {
1004     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
1005   }
1006 
1007   MDNode *getScopeList() const {
1008     auto *MV =
1009         cast<MetadataAsValue>(getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
1010     return cast<MDNode>(MV->getMetadata());
1011   }
1012 
1013   void setScopeList(MDNode *ScopeList) {
1014     setOperand(Intrinsic::NoAliasScopeDeclScopeArg,
1015                MetadataAsValue::get(getContext(), ScopeList));
1016   }
1017 };
1018 
1019 } // end namespace llvm
1020 
1021 #endif // LLVM_IR_INTRINSICINST_H
1022