1 //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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:
13 // if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst))
14 // ... MCI->getDest() ... MCI->getSource() ...
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
21 //===----------------------------------------------------------------------===//
23 #ifndef LLVM_IR_INTRINSICINST_H
24 #define LLVM_IR_INTRINSICINST_H
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"
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
{
45 IntrinsicInst() = delete;
46 IntrinsicInst(const IntrinsicInst
&) = delete;
47 IntrinsicInst
&operator=(const IntrinsicInst
&) = delete;
49 /// Return the intrinsic ID of this intrinsic.
50 Intrinsic::ID
getIntrinsicID() const {
51 return getCalledFunction()->getIntrinsicID();
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();
60 static bool classof(const Value
*V
) {
61 return isa
<CallInst
>(V
) && classof(cast
<CallInst
>(V
));
65 /// This is the common base class for debug info intrinsics.
66 class DbgInfoIntrinsic
: public IntrinsicInst
{
68 /// \name Casting methods
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
:
77 default: return false;
80 static bool classof(const Value
*V
) {
81 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
86 /// This is the common base class for debug info intrinsics for variables.
87 class DbgVariableIntrinsic
: public DbgInfoIntrinsic
{
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;
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
;
100 DILocalVariable
*getVariable() const {
101 return cast
<DILocalVariable
>(getRawVariable());
104 DIExpression
*getExpression() const {
105 return cast
<DIExpression
>(getRawExpression());
108 Metadata
*getRawVariable() const {
109 return cast
<MetadataAsValue
>(getArgOperand(1))->getMetadata();
112 Metadata
*getRawExpression() const {
113 return cast
<MetadataAsValue
>(getArgOperand(2))->getMetadata();
116 /// Get the size (in bits) of the variable, or fragment of the variable that
118 Optional
<uint64_t> getFragmentSizeInBits() const;
120 /// \name Casting methods
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
:
128 default: return false;
131 static bool classof(const Value
*V
) {
132 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
137 /// This represents the llvm.dbg.declare instruction.
138 class DbgDeclareInst
: public DbgVariableIntrinsic
{
140 Value
*getAddress() const { return getVariableLocation(); }
142 /// \name Casting methods
144 static bool classof(const IntrinsicInst
*I
) {
145 return I
->getIntrinsicID() == Intrinsic::dbg_declare
;
147 static bool classof(const Value
*V
) {
148 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
153 /// This represents the llvm.dbg.addr instruction.
154 class DbgAddrIntrinsic
: public DbgVariableIntrinsic
{
156 Value
*getAddress() const { return getVariableLocation(); }
158 /// \name Casting methods
160 static bool classof(const IntrinsicInst
*I
) {
161 return I
->getIntrinsicID() == Intrinsic::dbg_addr
;
163 static bool classof(const Value
*V
) {
164 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
168 /// This represents the llvm.dbg.value instruction.
169 class DbgValueInst
: public DbgVariableIntrinsic
{
171 Value
*getValue() const {
172 return getVariableLocation(/* AllowNullOp = */ false);
175 /// \name Casting methods
177 static bool classof(const IntrinsicInst
*I
) {
178 return I
->getIntrinsicID() == Intrinsic::dbg_value
;
180 static bool classof(const Value
*V
) {
181 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
186 /// This represents the llvm.dbg.label instruction.
187 class DbgLabelInst
: public DbgInfoIntrinsic
{
189 DILabel
*getLabel() const {
190 return cast
<DILabel
>(getRawLabel());
193 Metadata
*getRawLabel() const {
194 return cast
<MetadataAsValue
>(getArgOperand(0))->getMetadata();
197 /// Methods for support type inquiry through isa, cast, and dyn_cast:
199 static bool classof(const IntrinsicInst
*I
) {
200 return I
->getIntrinsicID() == Intrinsic::dbg_label
;
202 static bool classof(const Value
*V
) {
203 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
208 /// This is the common base class for constrained floating point intrinsics.
209 class ConstrainedFPIntrinsic
: public IntrinsicInst
{
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".
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".
231 bool isUnaryOp() const;
232 bool isTernaryOp() const;
233 Optional
<RoundingMode
> getRoundingMode() const;
234 Optional
<ExceptionBehavior
> getExceptionBehavior() const;
236 /// Returns a valid RoundingMode enumerator when given a string
237 /// that is valid as input in constrained intrinsic rounding mode
239 static Optional
<RoundingMode
> StrToRoundingMode(StringRef
);
241 /// For any RoundingMode enumerator, returns a string valid as input in
242 /// constrained intrinsic rounding mode metadata.
243 static Optional
<StringRef
> RoundingModeToStr(RoundingMode
);
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
);
249 /// For any ExceptionBehavior enumerator, returns a string valid as
250 /// input in constrained intrinsic exception behavior metadata.
251 static Optional
<StringRef
> ExceptionBehaviorToStr(ExceptionBehavior
);
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
:
289 default: return false;
292 static bool classof(const Value
*V
) {
293 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
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
{
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
:
318 static bool classof(const Value
*V
) {
319 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
322 Value
*getLHS() const { return const_cast<Value
*>(getArgOperand(0)); }
323 Value
*getRHS() const { return const_cast<Value
*>(getArgOperand(1)); }
325 /// Returns the binary operation underlying the intrinsic.
326 Instruction::BinaryOps
getBinaryOp() const;
328 /// Whether the intrinsic is signed or unsigned.
329 bool isSigned() const;
331 /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
332 unsigned getNoWrapKind() const;
335 /// Represents an op.with.overflow intrinsic.
336 class WithOverflowInst
: public BinaryOpIntrinsic
{
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
:
351 static bool classof(const Value
*V
) {
352 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
356 /// Represents a saturating add/sub intrinsic.
357 class SaturatingInst
: public BinaryOpIntrinsic
{
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
:
370 static bool classof(const Value
*V
) {
371 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
375 /// Common base class for all memory intrinsics. Simply provides
377 /// Written as CRTP to avoid a common base class amongst the
378 /// three atomicity hierarchies.
379 template <typename Derived
> class MemIntrinsicBase
: public IntrinsicInst
{
381 enum { ARG_DEST
= 0, ARG_LENGTH
= 2 };
384 Value
*getRawDest() const {
385 return const_cast<Value
*>(getArgOperand(ARG_DEST
));
387 const Use
&getRawDestUse() const { return getArgOperandUse(ARG_DEST
); }
388 Use
&getRawDestUse() { return getArgOperandUse(ARG_DEST
); }
390 Value
*getLength() const {
391 return const_cast<Value
*>(getArgOperand(ARG_LENGTH
));
393 const Use
&getLengthUse() const { return getArgOperandUse(ARG_LENGTH
); }
394 Use
&getLengthUse() { return getArgOperandUse(ARG_LENGTH
); }
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(); }
401 unsigned getDestAddressSpace() const {
402 return cast
<PointerType
>(getRawDest()->getType())->getAddressSpace();
405 unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST
); }
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
);
414 void setDestAlignment(unsigned Alignment
) {
415 removeParamAttr(ARG_DEST
, Attribute::Alignment
);
417 addParamAttr(ARG_DEST
, Attribute::getWithAlignment(getContext(),
421 void setLength(Value
*L
) {
422 assert(getLength()->getType() == L
->getType() &&
423 "setLength called with value of wrong type!");
424 setArgOperand(ARG_LENGTH
, L
);
428 /// Common base class for all memory transfer intrinsics. Simply provides
430 template <class BaseCL
> class MemTransferBase
: public BaseCL
{
432 enum { ARG_SOURCE
= 1 };
435 /// Return the arguments to the instruction.
436 Value
*getRawSource() const {
437 return const_cast<Value
*>(BaseCL::getArgOperand(ARG_SOURCE
));
439 const Use
&getRawSourceUse() const {
440 return BaseCL::getArgOperandUse(ARG_SOURCE
);
442 Use
&getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE
); }
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(); }
449 unsigned getSourceAddressSpace() const {
450 return cast
<PointerType
>(getRawSource()->getType())->getAddressSpace();
453 unsigned getSourceAlignment() const {
454 return BaseCL::getParamAlignment(ARG_SOURCE
);
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
);
463 void setSourceAlignment(unsigned Alignment
) {
464 BaseCL::removeParamAttr(ARG_SOURCE
, Attribute::Alignment
);
466 BaseCL::addParamAttr(ARG_SOURCE
,
467 Attribute::getWithAlignment(BaseCL::getContext(),
472 /// Common base class for all memset intrinsics. Simply provides
474 template <class BaseCL
> class MemSetBase
: public BaseCL
{
476 enum { ARG_VALUE
= 1 };
479 Value
*getValue() const {
480 return const_cast<Value
*>(BaseCL::getArgOperand(ARG_VALUE
));
482 const Use
&getValueUse() const {
483 return BaseCL::getArgOperandUse(ARG_VALUE
);
485 Use
&getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE
); }
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
);
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
> {
498 enum { ARG_ELEMENTSIZE
= 3 };
501 Value
*getRawElementSizeInBytes() const {
502 return const_cast<Value
*>(getArgOperand(ARG_ELEMENTSIZE
));
505 ConstantInt
*getElementSizeInBytesCst() const {
506 return cast
<ConstantInt
>(getRawElementSizeInBytes());
509 uint32_t getElementSizeInBytes() const {
510 return getElementSizeInBytesCst()->getZExtValue();
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
);
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
:
529 static bool classof(const Value
*V
) {
530 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
534 /// This class represents atomic memset intrinsic
535 // i.e. llvm.element.unordered.atomic.memset
536 class AtomicMemSetInst
: public MemSetBase
<AtomicMemIntrinsic
> {
538 static bool classof(const IntrinsicInst
*I
) {
539 return I
->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic
;
541 static bool classof(const Value
*V
) {
542 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
546 // This class wraps the atomic memcpy/memmove intrinsics
547 // i.e. llvm.element.unordered.atomic.memcpy/memmove
548 class AtomicMemTransferInst
: public MemTransferBase
<AtomicMemIntrinsic
> {
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
:
559 static bool classof(const Value
*V
) {
560 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
564 /// This class represents the atomic memcpy intrinsic
565 /// i.e. llvm.element.unordered.atomic.memcpy
566 class AtomicMemCpyInst
: public AtomicMemTransferInst
{
568 static bool classof(const IntrinsicInst
*I
) {
569 return I
->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic
;
571 static bool classof(const Value
*V
) {
572 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
576 /// This class represents the atomic memmove intrinsic
577 /// i.e. llvm.element.unordered.atomic.memmove
578 class AtomicMemMoveInst
: public AtomicMemTransferInst
{
580 static bool classof(const IntrinsicInst
*I
) {
581 return I
->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic
;
583 static bool classof(const Value
*V
) {
584 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
588 /// This is the common base class for memset/memcpy/memmove.
589 class MemIntrinsic
: public MemIntrinsicBase
<MemIntrinsic
> {
591 enum { ARG_VOLATILE
= 3 };
594 ConstantInt
*getVolatileCst() const {
595 return cast
<ConstantInt
>(
596 const_cast<Value
*>(getArgOperand(ARG_VOLATILE
)));
599 bool isVolatile() const {
600 return !getVolatileCst()->isZero();
603 void setVolatile(Constant
*V
) { setArgOperand(ARG_VOLATILE
, V
); }
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
:
612 default: return false;
615 static bool classof(const Value
*V
) {
616 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
620 /// This class wraps the llvm.memset intrinsic.
621 class MemSetInst
: public MemSetBase
<MemIntrinsic
> {
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
;
627 static bool classof(const Value
*V
) {
628 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
632 /// This class wraps the llvm.memcpy/memmove intrinsics.
633 class MemTransferInst
: public MemTransferBase
<MemIntrinsic
> {
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
;
640 static bool classof(const Value
*V
) {
641 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
645 /// This class wraps the llvm.memcpy intrinsic.
646 class MemCpyInst
: public MemTransferInst
{
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
;
652 static bool classof(const Value
*V
) {
653 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
657 /// This class wraps the llvm.memmove intrinsic.
658 class MemMoveInst
: public MemTransferInst
{
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
;
664 static bool classof(const Value
*V
) {
665 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
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
> {
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();
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
:
695 static bool classof(const Value
*V
) {
696 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
700 /// This class represents any memset intrinsic
701 // i.e. llvm.element.unordered.atomic.memset
703 class AnyMemSetInst
: public MemSetBase
<AnyMemIntrinsic
> {
705 static bool classof(const IntrinsicInst
*I
) {
706 switch (I
->getIntrinsicID()) {
707 case Intrinsic::memset
:
708 case Intrinsic::memset_element_unordered_atomic
:
714 static bool classof(const Value
*V
) {
715 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
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
> {
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
:
735 static bool classof(const Value
*V
) {
736 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
740 /// This class represents any memcpy intrinsic
741 /// i.e. llvm.element.unordered.atomic.memcpy
743 class AnyMemCpyInst
: public AnyMemTransferInst
{
745 static bool classof(const IntrinsicInst
*I
) {
746 switch (I
->getIntrinsicID()) {
747 case Intrinsic::memcpy
:
748 case Intrinsic::memcpy_element_unordered_atomic
:
754 static bool classof(const Value
*V
) {
755 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
759 /// This class represents any memmove intrinsic
760 /// i.e. llvm.element.unordered.atomic.memmove
762 class AnyMemMoveInst
: public AnyMemTransferInst
{
764 static bool classof(const IntrinsicInst
*I
) {
765 switch (I
->getIntrinsicID()) {
766 case Intrinsic::memmove
:
767 case Intrinsic::memmove_element_unordered_atomic
:
773 static bool classof(const Value
*V
) {
774 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
778 /// This represents the llvm.va_start intrinsic.
779 class VAStartInst
: public IntrinsicInst
{
781 static bool classof(const IntrinsicInst
*I
) {
782 return I
->getIntrinsicID() == Intrinsic::vastart
;
784 static bool classof(const Value
*V
) {
785 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
788 Value
*getArgList() const { return const_cast<Value
*>(getArgOperand(0)); }
791 /// This represents the llvm.va_end intrinsic.
792 class VAEndInst
: public IntrinsicInst
{
794 static bool classof(const IntrinsicInst
*I
) {
795 return I
->getIntrinsicID() == Intrinsic::vaend
;
797 static bool classof(const Value
*V
) {
798 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
801 Value
*getArgList() const { return const_cast<Value
*>(getArgOperand(0)); }
804 /// This represents the llvm.va_copy intrinsic.
805 class VACopyInst
: public IntrinsicInst
{
807 static bool classof(const IntrinsicInst
*I
) {
808 return I
->getIntrinsicID() == Intrinsic::vacopy
;
810 static bool classof(const Value
*V
) {
811 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
814 Value
*getDest() const { return const_cast<Value
*>(getArgOperand(0)); }
815 Value
*getSrc() const { return const_cast<Value
*>(getArgOperand(1)); }
818 /// This represents the llvm.instrprof_increment intrinsic.
819 class InstrProfIncrementInst
: public IntrinsicInst
{
821 static bool classof(const IntrinsicInst
*I
) {
822 return I
->getIntrinsicID() == Intrinsic::instrprof_increment
;
824 static bool classof(const Value
*V
) {
825 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
828 GlobalVariable
*getName() const {
829 return cast
<GlobalVariable
>(
830 const_cast<Value
*>(getArgOperand(0))->stripPointerCasts());
833 ConstantInt
*getHash() const {
834 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(1)));
837 ConstantInt
*getNumCounters() const {
838 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(2)));
841 ConstantInt
*getIndex() const {
842 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(3)));
845 Value
*getStep() const;
848 class InstrProfIncrementInstStep
: public InstrProfIncrementInst
{
850 static bool classof(const IntrinsicInst
*I
) {
851 return I
->getIntrinsicID() == Intrinsic::instrprof_increment_step
;
853 static bool classof(const Value
*V
) {
854 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
858 /// This represents the llvm.instrprof_value_profile intrinsic.
859 class InstrProfValueProfileInst
: public IntrinsicInst
{
861 static bool classof(const IntrinsicInst
*I
) {
862 return I
->getIntrinsicID() == Intrinsic::instrprof_value_profile
;
864 static bool classof(const Value
*V
) {
865 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
868 GlobalVariable
*getName() const {
869 return cast
<GlobalVariable
>(
870 const_cast<Value
*>(getArgOperand(0))->stripPointerCasts());
873 ConstantInt
*getHash() const {
874 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(1)));
877 Value
*getTargetValue() const {
878 return cast
<Value
>(const_cast<Value
*>(getArgOperand(2)));
881 ConstantInt
*getValueKind() const {
882 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(3)));
885 // Returns the value site index.
886 ConstantInt
*getIndex() const {
887 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(4)));
891 } // end namespace llvm
893 #endif // LLVM_IR_INTRINSICINST_H