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_rint
:
277 case Intrinsic::experimental_constrained_nearbyint
:
278 case Intrinsic::experimental_constrained_maxnum
:
279 case Intrinsic::experimental_constrained_minnum
:
280 case Intrinsic::experimental_constrained_ceil
:
281 case Intrinsic::experimental_constrained_floor
:
282 case Intrinsic::experimental_constrained_round
:
283 case Intrinsic::experimental_constrained_trunc
:
285 default: return false;
288 static bool classof(const Value
*V
) {
289 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
293 /// This class represents an intrinsic that is based on a binary operation.
294 /// This includes op.with.overflow and saturating add/sub intrinsics.
295 class BinaryOpIntrinsic
: public IntrinsicInst
{
297 static bool classof(const IntrinsicInst
*I
) {
298 switch (I
->getIntrinsicID()) {
299 case Intrinsic::uadd_with_overflow
:
300 case Intrinsic::sadd_with_overflow
:
301 case Intrinsic::usub_with_overflow
:
302 case Intrinsic::ssub_with_overflow
:
303 case Intrinsic::umul_with_overflow
:
304 case Intrinsic::smul_with_overflow
:
305 case Intrinsic::uadd_sat
:
306 case Intrinsic::sadd_sat
:
307 case Intrinsic::usub_sat
:
308 case Intrinsic::ssub_sat
:
314 static bool classof(const Value
*V
) {
315 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
318 Value
*getLHS() const { return const_cast<Value
*>(getArgOperand(0)); }
319 Value
*getRHS() const { return const_cast<Value
*>(getArgOperand(1)); }
321 /// Returns the binary operation underlying the intrinsic.
322 Instruction::BinaryOps
getBinaryOp() const;
324 /// Whether the intrinsic is signed or unsigned.
325 bool isSigned() const;
327 /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
328 unsigned getNoWrapKind() const;
331 /// Represents an op.with.overflow intrinsic.
332 class WithOverflowInst
: public BinaryOpIntrinsic
{
334 static bool classof(const IntrinsicInst
*I
) {
335 switch (I
->getIntrinsicID()) {
336 case Intrinsic::uadd_with_overflow
:
337 case Intrinsic::sadd_with_overflow
:
338 case Intrinsic::usub_with_overflow
:
339 case Intrinsic::ssub_with_overflow
:
340 case Intrinsic::umul_with_overflow
:
341 case Intrinsic::smul_with_overflow
:
347 static bool classof(const Value
*V
) {
348 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
352 /// Represents a saturating add/sub intrinsic.
353 class SaturatingInst
: public BinaryOpIntrinsic
{
355 static bool classof(const IntrinsicInst
*I
) {
356 switch (I
->getIntrinsicID()) {
357 case Intrinsic::uadd_sat
:
358 case Intrinsic::sadd_sat
:
359 case Intrinsic::usub_sat
:
360 case Intrinsic::ssub_sat
:
366 static bool classof(const Value
*V
) {
367 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
371 /// Common base class for all memory intrinsics. Simply provides
373 /// Written as CRTP to avoid a common base class amongst the
374 /// three atomicity hierarchies.
375 template <typename Derived
> class MemIntrinsicBase
: public IntrinsicInst
{
377 enum { ARG_DEST
= 0, ARG_LENGTH
= 2 };
380 Value
*getRawDest() const {
381 return const_cast<Value
*>(getArgOperand(ARG_DEST
));
383 const Use
&getRawDestUse() const { return getArgOperandUse(ARG_DEST
); }
384 Use
&getRawDestUse() { return getArgOperandUse(ARG_DEST
); }
386 Value
*getLength() const {
387 return const_cast<Value
*>(getArgOperand(ARG_LENGTH
));
389 const Use
&getLengthUse() const { return getArgOperandUse(ARG_LENGTH
); }
390 Use
&getLengthUse() { return getArgOperandUse(ARG_LENGTH
); }
392 /// This is just like getRawDest, but it strips off any cast
393 /// instructions (including addrspacecast) that feed it, giving the
394 /// original input. The returned value is guaranteed to be a pointer.
395 Value
*getDest() const { return getRawDest()->stripPointerCasts(); }
397 unsigned getDestAddressSpace() const {
398 return cast
<PointerType
>(getRawDest()->getType())->getAddressSpace();
401 unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST
); }
403 /// Set the specified arguments of the instruction.
404 void setDest(Value
*Ptr
) {
405 assert(getRawDest()->getType() == Ptr
->getType() &&
406 "setDest called with pointer of wrong type!");
407 setArgOperand(ARG_DEST
, Ptr
);
410 void setDestAlignment(unsigned Align
) {
411 removeParamAttr(ARG_DEST
, Attribute::Alignment
);
413 addParamAttr(ARG_DEST
,
414 Attribute::getWithAlignment(getContext(), Align
));
417 void setLength(Value
*L
) {
418 assert(getLength()->getType() == L
->getType() &&
419 "setLength called with value of wrong type!");
420 setArgOperand(ARG_LENGTH
, L
);
424 /// Common base class for all memory transfer intrinsics. Simply provides
426 template <class BaseCL
> class MemTransferBase
: public BaseCL
{
428 enum { ARG_SOURCE
= 1 };
431 /// Return the arguments to the instruction.
432 Value
*getRawSource() const {
433 return const_cast<Value
*>(BaseCL::getArgOperand(ARG_SOURCE
));
435 const Use
&getRawSourceUse() const {
436 return BaseCL::getArgOperandUse(ARG_SOURCE
);
438 Use
&getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE
); }
440 /// This is just like getRawSource, but it strips off any cast
441 /// instructions that feed it, giving the original input. The returned
442 /// value is guaranteed to be a pointer.
443 Value
*getSource() const { return getRawSource()->stripPointerCasts(); }
445 unsigned getSourceAddressSpace() const {
446 return cast
<PointerType
>(getRawSource()->getType())->getAddressSpace();
449 unsigned getSourceAlignment() const {
450 return BaseCL::getParamAlignment(ARG_SOURCE
);
453 void setSource(Value
*Ptr
) {
454 assert(getRawSource()->getType() == Ptr
->getType() &&
455 "setSource called with pointer of wrong type!");
456 BaseCL::setArgOperand(ARG_SOURCE
, Ptr
);
459 void setSourceAlignment(unsigned Align
) {
460 BaseCL::removeParamAttr(ARG_SOURCE
, Attribute::Alignment
);
462 BaseCL::addParamAttr(ARG_SOURCE
, Attribute::getWithAlignment(
463 BaseCL::getContext(), Align
));
467 /// Common base class for all memset intrinsics. Simply provides
469 template <class BaseCL
> class MemSetBase
: public BaseCL
{
471 enum { ARG_VALUE
= 1 };
474 Value
*getValue() const {
475 return const_cast<Value
*>(BaseCL::getArgOperand(ARG_VALUE
));
477 const Use
&getValueUse() const {
478 return BaseCL::getArgOperandUse(ARG_VALUE
);
480 Use
&getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE
); }
482 void setValue(Value
*Val
) {
483 assert(getValue()->getType() == Val
->getType() &&
484 "setValue called with value of wrong type!");
485 BaseCL::setArgOperand(ARG_VALUE
, Val
);
489 // The common base class for the atomic memset/memmove/memcpy intrinsics
490 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
491 class AtomicMemIntrinsic
: public MemIntrinsicBase
<AtomicMemIntrinsic
> {
493 enum { ARG_ELEMENTSIZE
= 3 };
496 Value
*getRawElementSizeInBytes() const {
497 return const_cast<Value
*>(getArgOperand(ARG_ELEMENTSIZE
));
500 ConstantInt
*getElementSizeInBytesCst() const {
501 return cast
<ConstantInt
>(getRawElementSizeInBytes());
504 uint32_t getElementSizeInBytes() const {
505 return getElementSizeInBytesCst()->getZExtValue();
508 void setElementSizeInBytes(Constant
*V
) {
509 assert(V
->getType() == Type::getInt8Ty(getContext()) &&
510 "setElementSizeInBytes called with value of wrong type!");
511 setArgOperand(ARG_ELEMENTSIZE
, V
);
514 static bool classof(const IntrinsicInst
*I
) {
515 switch (I
->getIntrinsicID()) {
516 case Intrinsic::memcpy_element_unordered_atomic
:
517 case Intrinsic::memmove_element_unordered_atomic
:
518 case Intrinsic::memset_element_unordered_atomic
:
524 static bool classof(const Value
*V
) {
525 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
529 /// This class represents atomic memset intrinsic
530 // i.e. llvm.element.unordered.atomic.memset
531 class AtomicMemSetInst
: public MemSetBase
<AtomicMemIntrinsic
> {
533 static bool classof(const IntrinsicInst
*I
) {
534 return I
->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic
;
536 static bool classof(const Value
*V
) {
537 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
541 // This class wraps the atomic memcpy/memmove intrinsics
542 // i.e. llvm.element.unordered.atomic.memcpy/memmove
543 class AtomicMemTransferInst
: public MemTransferBase
<AtomicMemIntrinsic
> {
545 static bool classof(const IntrinsicInst
*I
) {
546 switch (I
->getIntrinsicID()) {
547 case Intrinsic::memcpy_element_unordered_atomic
:
548 case Intrinsic::memmove_element_unordered_atomic
:
554 static bool classof(const Value
*V
) {
555 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
559 /// This class represents the atomic memcpy intrinsic
560 /// i.e. llvm.element.unordered.atomic.memcpy
561 class AtomicMemCpyInst
: public AtomicMemTransferInst
{
563 static bool classof(const IntrinsicInst
*I
) {
564 return I
->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic
;
566 static bool classof(const Value
*V
) {
567 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
571 /// This class represents the atomic memmove intrinsic
572 /// i.e. llvm.element.unordered.atomic.memmove
573 class AtomicMemMoveInst
: public AtomicMemTransferInst
{
575 static bool classof(const IntrinsicInst
*I
) {
576 return I
->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic
;
578 static bool classof(const Value
*V
) {
579 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
583 /// This is the common base class for memset/memcpy/memmove.
584 class MemIntrinsic
: public MemIntrinsicBase
<MemIntrinsic
> {
586 enum { ARG_VOLATILE
= 3 };
589 ConstantInt
*getVolatileCst() const {
590 return cast
<ConstantInt
>(
591 const_cast<Value
*>(getArgOperand(ARG_VOLATILE
)));
594 bool isVolatile() const {
595 return !getVolatileCst()->isZero();
598 void setVolatile(Constant
*V
) { setArgOperand(ARG_VOLATILE
, V
); }
600 // Methods for support type inquiry through isa, cast, and dyn_cast:
601 static bool classof(const IntrinsicInst
*I
) {
602 switch (I
->getIntrinsicID()) {
603 case Intrinsic::memcpy
:
604 case Intrinsic::memmove
:
605 case Intrinsic::memset
:
607 default: return false;
610 static bool classof(const Value
*V
) {
611 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
615 /// This class wraps the llvm.memset intrinsic.
616 class MemSetInst
: public MemSetBase
<MemIntrinsic
> {
618 // Methods for support type inquiry through isa, cast, and dyn_cast:
619 static bool classof(const IntrinsicInst
*I
) {
620 return I
->getIntrinsicID() == Intrinsic::memset
;
622 static bool classof(const Value
*V
) {
623 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
627 /// This class wraps the llvm.memcpy/memmove intrinsics.
628 class MemTransferInst
: public MemTransferBase
<MemIntrinsic
> {
630 // Methods for support type inquiry through isa, cast, and dyn_cast:
631 static bool classof(const IntrinsicInst
*I
) {
632 return I
->getIntrinsicID() == Intrinsic::memcpy
||
633 I
->getIntrinsicID() == Intrinsic::memmove
;
635 static bool classof(const Value
*V
) {
636 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
640 /// This class wraps the llvm.memcpy intrinsic.
641 class MemCpyInst
: public MemTransferInst
{
643 // Methods for support type inquiry through isa, cast, and dyn_cast:
644 static bool classof(const IntrinsicInst
*I
) {
645 return I
->getIntrinsicID() == Intrinsic::memcpy
;
647 static bool classof(const Value
*V
) {
648 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
652 /// This class wraps the llvm.memmove intrinsic.
653 class MemMoveInst
: public MemTransferInst
{
655 // Methods for support type inquiry through isa, cast, and dyn_cast:
656 static bool classof(const IntrinsicInst
*I
) {
657 return I
->getIntrinsicID() == Intrinsic::memmove
;
659 static bool classof(const Value
*V
) {
660 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
664 // The common base class for any memset/memmove/memcpy intrinsics;
665 // whether they be atomic or non-atomic.
666 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
667 // and llvm.memset/memcpy/memmove
668 class AnyMemIntrinsic
: public MemIntrinsicBase
<AnyMemIntrinsic
> {
670 bool isVolatile() const {
671 // Only the non-atomic intrinsics can be volatile
672 if (auto *MI
= dyn_cast
<MemIntrinsic
>(this))
673 return MI
->isVolatile();
677 static bool classof(const IntrinsicInst
*I
) {
678 switch (I
->getIntrinsicID()) {
679 case Intrinsic::memcpy
:
680 case Intrinsic::memmove
:
681 case Intrinsic::memset
:
682 case Intrinsic::memcpy_element_unordered_atomic
:
683 case Intrinsic::memmove_element_unordered_atomic
:
684 case Intrinsic::memset_element_unordered_atomic
:
690 static bool classof(const Value
*V
) {
691 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
695 /// This class represents any memset intrinsic
696 // i.e. llvm.element.unordered.atomic.memset
698 class AnyMemSetInst
: public MemSetBase
<AnyMemIntrinsic
> {
700 static bool classof(const IntrinsicInst
*I
) {
701 switch (I
->getIntrinsicID()) {
702 case Intrinsic::memset
:
703 case Intrinsic::memset_element_unordered_atomic
:
709 static bool classof(const Value
*V
) {
710 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
714 // This class wraps any memcpy/memmove intrinsics
715 // i.e. llvm.element.unordered.atomic.memcpy/memmove
716 // and llvm.memcpy/memmove
717 class AnyMemTransferInst
: public MemTransferBase
<AnyMemIntrinsic
> {
719 static bool classof(const IntrinsicInst
*I
) {
720 switch (I
->getIntrinsicID()) {
721 case Intrinsic::memcpy
:
722 case Intrinsic::memmove
:
723 case Intrinsic::memcpy_element_unordered_atomic
:
724 case Intrinsic::memmove_element_unordered_atomic
:
730 static bool classof(const Value
*V
) {
731 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
735 /// This class represents any memcpy intrinsic
736 /// i.e. llvm.element.unordered.atomic.memcpy
738 class AnyMemCpyInst
: public AnyMemTransferInst
{
740 static bool classof(const IntrinsicInst
*I
) {
741 switch (I
->getIntrinsicID()) {
742 case Intrinsic::memcpy
:
743 case Intrinsic::memcpy_element_unordered_atomic
:
749 static bool classof(const Value
*V
) {
750 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
754 /// This class represents any memmove intrinsic
755 /// i.e. llvm.element.unordered.atomic.memmove
757 class AnyMemMoveInst
: public AnyMemTransferInst
{
759 static bool classof(const IntrinsicInst
*I
) {
760 switch (I
->getIntrinsicID()) {
761 case Intrinsic::memmove
:
762 case Intrinsic::memmove_element_unordered_atomic
:
768 static bool classof(const Value
*V
) {
769 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
773 /// This represents the llvm.va_start intrinsic.
774 class VAStartInst
: public IntrinsicInst
{
776 static bool classof(const IntrinsicInst
*I
) {
777 return I
->getIntrinsicID() == Intrinsic::vastart
;
779 static bool classof(const Value
*V
) {
780 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
783 Value
*getArgList() const { return const_cast<Value
*>(getArgOperand(0)); }
786 /// This represents the llvm.va_end intrinsic.
787 class VAEndInst
: public IntrinsicInst
{
789 static bool classof(const IntrinsicInst
*I
) {
790 return I
->getIntrinsicID() == Intrinsic::vaend
;
792 static bool classof(const Value
*V
) {
793 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
796 Value
*getArgList() const { return const_cast<Value
*>(getArgOperand(0)); }
799 /// This represents the llvm.va_copy intrinsic.
800 class VACopyInst
: public IntrinsicInst
{
802 static bool classof(const IntrinsicInst
*I
) {
803 return I
->getIntrinsicID() == Intrinsic::vacopy
;
805 static bool classof(const Value
*V
) {
806 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
809 Value
*getDest() const { return const_cast<Value
*>(getArgOperand(0)); }
810 Value
*getSrc() const { return const_cast<Value
*>(getArgOperand(1)); }
813 /// This represents the llvm.instrprof_increment intrinsic.
814 class InstrProfIncrementInst
: public IntrinsicInst
{
816 static bool classof(const IntrinsicInst
*I
) {
817 return I
->getIntrinsicID() == Intrinsic::instrprof_increment
;
819 static bool classof(const Value
*V
) {
820 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
823 GlobalVariable
*getName() const {
824 return cast
<GlobalVariable
>(
825 const_cast<Value
*>(getArgOperand(0))->stripPointerCasts());
828 ConstantInt
*getHash() const {
829 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(1)));
832 ConstantInt
*getNumCounters() const {
833 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(2)));
836 ConstantInt
*getIndex() const {
837 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(3)));
840 Value
*getStep() const;
843 class InstrProfIncrementInstStep
: public InstrProfIncrementInst
{
845 static bool classof(const IntrinsicInst
*I
) {
846 return I
->getIntrinsicID() == Intrinsic::instrprof_increment_step
;
848 static bool classof(const Value
*V
) {
849 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
853 /// This represents the llvm.instrprof_value_profile intrinsic.
854 class InstrProfValueProfileInst
: public IntrinsicInst
{
856 static bool classof(const IntrinsicInst
*I
) {
857 return I
->getIntrinsicID() == Intrinsic::instrprof_value_profile
;
859 static bool classof(const Value
*V
) {
860 return isa
<IntrinsicInst
>(V
) && classof(cast
<IntrinsicInst
>(V
));
863 GlobalVariable
*getName() const {
864 return cast
<GlobalVariable
>(
865 const_cast<Value
*>(getArgOperand(0))->stripPointerCasts());
868 ConstantInt
*getHash() const {
869 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(1)));
872 Value
*getTargetValue() const {
873 return cast
<Value
>(const_cast<Value
*>(getArgOperand(2)));
876 ConstantInt
*getValueKind() const {
877 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(3)));
880 // Returns the value site index.
881 ConstantInt
*getIndex() const {
882 return cast
<ConstantInt
>(const_cast<Value
*>(getArgOperand(4)));
886 } // end namespace llvm
888 #endif // LLVM_IR_INTRINSICINST_H