[InstCombine] Signed saturation patterns
[llvm-core.git] / include / llvm / IR / IntrinsicInst.h
blobc989b4a2e72ae6a44bc13db0698beeadce9687e0
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:
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
19 // hack working.
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"
35 #include <cassert>
36 #include <cstdint>
38 namespace llvm {
40 /// A wrapper class for inspecting calls to intrinsic functions.
41 /// This allows the standard isa/dyncast/cast functionality to work with calls
42 /// to intrinsic functions.
43 class IntrinsicInst : public CallInst {
44 public:
45 IntrinsicInst() = delete;
46 IntrinsicInst(const IntrinsicInst &) = delete;
47 IntrinsicInst &operator=(const IntrinsicInst &) = delete;
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();
58 return false;
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 {
67 public:
68 /// \name Casting methods
69 /// @{
70 static bool classof(const IntrinsicInst *I) {
71 switch (I->getIntrinsicID()) {
72 case Intrinsic::dbg_declare:
73 case Intrinsic::dbg_value:
74 case Intrinsic::dbg_addr:
75 case Intrinsic::dbg_label:
76 return true;
77 default: return false;
80 static bool classof(const Value *V) {
81 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
83 /// @}
86 /// This is the common base class for debug info intrinsics for variables.
87 class DbgVariableIntrinsic : public DbgInfoIntrinsic {
88 public:
89 /// Get the location corresponding to the variable referenced by the debug
90 /// info intrinsic. Depending on the intrinsic, this could be the
91 /// variable's value or its address.
92 Value *getVariableLocation(bool AllowNullOp = true) const;
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
117 /// is described.
118 Optional<uint64_t> getFragmentSizeInBits() const;
120 /// \name Casting methods
121 /// @{
122 static bool classof(const IntrinsicInst *I) {
123 switch (I->getIntrinsicID()) {
124 case Intrinsic::dbg_declare:
125 case Intrinsic::dbg_value:
126 case Intrinsic::dbg_addr:
127 return true;
128 default: return false;
131 static bool classof(const Value *V) {
132 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
134 /// @}
137 /// This represents the llvm.dbg.declare instruction.
138 class DbgDeclareInst : public DbgVariableIntrinsic {
139 public:
140 Value *getAddress() const { return getVariableLocation(); }
142 /// \name Casting methods
143 /// @{
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));
150 /// @}
153 /// This represents the llvm.dbg.addr instruction.
154 class DbgAddrIntrinsic : public DbgVariableIntrinsic {
155 public:
156 Value *getAddress() const { return getVariableLocation(); }
158 /// \name Casting methods
159 /// @{
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 {
170 public:
171 Value *getValue() const {
172 return getVariableLocation(/* AllowNullOp = */ false);
175 /// \name Casting methods
176 /// @{
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));
183 /// @}
186 /// This represents the llvm.dbg.label instruction.
187 class DbgLabelInst : public DbgInfoIntrinsic {
188 public:
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:
198 /// @{
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));
205 /// @}
208 /// This is the common base class for constrained floating point intrinsics.
209 class ConstrainedFPIntrinsic : public IntrinsicInst {
210 public:
211 /// Specifies the rounding mode to be assumed. This is only used when
212 /// when constrained floating point is enabled. See the LLVM Language
213 /// Reference Manual for details.
214 enum RoundingMode : uint8_t {
215 rmDynamic, ///< This corresponds to "fpround.dynamic".
216 rmToNearest, ///< This corresponds to "fpround.tonearest".
217 rmDownward, ///< This corresponds to "fpround.downward".
218 rmUpward, ///< This corresponds to "fpround.upward".
219 rmTowardZero ///< This corresponds to "fpround.tozero".
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
238 /// metadata.
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:
288 return true;
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 {
300 public:
301 static bool classof(const IntrinsicInst *I) {
302 switch (I->getIntrinsicID()) {
303 case Intrinsic::uadd_with_overflow:
304 case Intrinsic::sadd_with_overflow:
305 case Intrinsic::usub_with_overflow:
306 case Intrinsic::ssub_with_overflow:
307 case Intrinsic::umul_with_overflow:
308 case Intrinsic::smul_with_overflow:
309 case Intrinsic::uadd_sat:
310 case Intrinsic::sadd_sat:
311 case Intrinsic::usub_sat:
312 case Intrinsic::ssub_sat:
313 return true;
314 default:
315 return false;
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 {
337 public:
338 static bool classof(const IntrinsicInst *I) {
339 switch (I->getIntrinsicID()) {
340 case Intrinsic::uadd_with_overflow:
341 case Intrinsic::sadd_with_overflow:
342 case Intrinsic::usub_with_overflow:
343 case Intrinsic::ssub_with_overflow:
344 case Intrinsic::umul_with_overflow:
345 case Intrinsic::smul_with_overflow:
346 return true;
347 default:
348 return false;
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 {
358 public:
359 static bool classof(const IntrinsicInst *I) {
360 switch (I->getIntrinsicID()) {
361 case Intrinsic::uadd_sat:
362 case Intrinsic::sadd_sat:
363 case Intrinsic::usub_sat:
364 case Intrinsic::ssub_sat:
365 return true;
366 default:
367 return false;
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
376 /// common methods.
377 /// Written as CRTP to avoid a common base class amongst the
378 /// three atomicity hierarchies.
379 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
380 private:
381 enum { ARG_DEST = 0, ARG_LENGTH = 2 };
383 public:
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);
416 if (Alignment > 0)
417 addParamAttr(ARG_DEST, Attribute::getWithAlignment(getContext(),
418 Align(Alignment)));
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
429 /// common methods.
430 template <class BaseCL> class MemTransferBase : public BaseCL {
431 private:
432 enum { ARG_SOURCE = 1 };
434 public:
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);
465 if (Alignment > 0)
466 BaseCL::addParamAttr(ARG_SOURCE,
467 Attribute::getWithAlignment(BaseCL::getContext(),
468 Align(Alignment)));
472 /// Common base class for all memset intrinsics. Simply provides
473 /// common methods.
474 template <class BaseCL> class MemSetBase : public BaseCL {
475 private:
476 enum { ARG_VALUE = 1 };
478 public:
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> {
497 private:
498 enum { ARG_ELEMENTSIZE = 3 };
500 public:
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:
524 return true;
525 default:
526 return false;
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> {
537 public:
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> {
549 public:
550 static bool classof(const IntrinsicInst *I) {
551 switch (I->getIntrinsicID()) {
552 case Intrinsic::memcpy_element_unordered_atomic:
553 case Intrinsic::memmove_element_unordered_atomic:
554 return true;
555 default:
556 return false;
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 {
567 public:
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 {
579 public:
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> {
590 private:
591 enum { ARG_VOLATILE = 3 };
593 public:
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:
611 return true;
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> {
622 public:
623 // Methods for support type inquiry through isa, cast, and dyn_cast:
624 static bool classof(const IntrinsicInst *I) {
625 return I->getIntrinsicID() == Intrinsic::memset;
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> {
634 public:
635 // Methods for support type inquiry through isa, cast, and dyn_cast:
636 static bool classof(const IntrinsicInst *I) {
637 return I->getIntrinsicID() == Intrinsic::memcpy ||
638 I->getIntrinsicID() == Intrinsic::memmove;
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 {
647 public:
648 // Methods for support type inquiry through isa, cast, and dyn_cast:
649 static bool classof(const IntrinsicInst *I) {
650 return I->getIntrinsicID() == Intrinsic::memcpy;
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 {
659 public:
660 // Methods for support type inquiry through isa, cast, and dyn_cast:
661 static bool classof(const IntrinsicInst *I) {
662 return I->getIntrinsicID() == Intrinsic::memmove;
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> {
674 public:
675 bool isVolatile() const {
676 // Only the non-atomic intrinsics can be volatile
677 if (auto *MI = dyn_cast<MemIntrinsic>(this))
678 return MI->isVolatile();
679 return false;
682 static bool classof(const IntrinsicInst *I) {
683 switch (I->getIntrinsicID()) {
684 case Intrinsic::memcpy:
685 case Intrinsic::memmove:
686 case Intrinsic::memset:
687 case Intrinsic::memcpy_element_unordered_atomic:
688 case Intrinsic::memmove_element_unordered_atomic:
689 case Intrinsic::memset_element_unordered_atomic:
690 return true;
691 default:
692 return false;
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
702 // and llvm.memset
703 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
704 public:
705 static bool classof(const IntrinsicInst *I) {
706 switch (I->getIntrinsicID()) {
707 case Intrinsic::memset:
708 case Intrinsic::memset_element_unordered_atomic:
709 return true;
710 default:
711 return false;
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> {
723 public:
724 static bool classof(const IntrinsicInst *I) {
725 switch (I->getIntrinsicID()) {
726 case Intrinsic::memcpy:
727 case Intrinsic::memmove:
728 case Intrinsic::memcpy_element_unordered_atomic:
729 case Intrinsic::memmove_element_unordered_atomic:
730 return true;
731 default:
732 return false;
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
742 /// and llvm.memcpy
743 class AnyMemCpyInst : public AnyMemTransferInst {
744 public:
745 static bool classof(const IntrinsicInst *I) {
746 switch (I->getIntrinsicID()) {
747 case Intrinsic::memcpy:
748 case Intrinsic::memcpy_element_unordered_atomic:
749 return true;
750 default:
751 return false;
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
761 /// and llvm.memmove
762 class AnyMemMoveInst : public AnyMemTransferInst {
763 public:
764 static bool classof(const IntrinsicInst *I) {
765 switch (I->getIntrinsicID()) {
766 case Intrinsic::memmove:
767 case Intrinsic::memmove_element_unordered_atomic:
768 return true;
769 default:
770 return false;
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 {
780 public:
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 {
793 public:
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 {
806 public:
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 {
820 public:
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 {
849 public:
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 {
860 public:
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