LLVM 24.0.0git
GenericMachineInstrs.h
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/GenericMachineInstrs.h -----------*- 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/// \file
9/// Declares convenience wrapper classes for interpreting MachineInstr instances
10/// as specific generic operations.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
15#define LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
16
17#include "llvm/ADT/APInt.h"
21#include "llvm/IR/Constants.h"
24
25namespace llvm {
26
27/// A base class for all GenericMachineInstrs.
28class GenericMachineInstr : public MachineInstr {
29 constexpr static unsigned PoisonFlags =
32
33public:
35
36 /// Access the Idx'th operand as a register and return it.
37 /// This assumes that the Idx'th operand is a Register type.
38 Register getReg(unsigned Idx) const { return getOperand(Idx).getReg(); }
39
40 static bool classof(const MachineInstr *MI) {
41 return isPreISelGenericOpcode(MI->getOpcode());
42 }
43
44 bool hasPoisonGeneratingFlags() const { return getFlags() & PoisonFlags; }
45
50};
51
52/// Provides common memory operand functionality.
54public:
55 /// Get the MachineMemOperand on this instruction.
57
58 /// Returns true if the attached MachineMemOperand has the atomic flag set.
59 bool isAtomic() const { return getMMO().isAtomic(); }
60 /// Returns true if the attached MachineMemOpeand as the volatile flag set.
61 bool isVolatile() const { return getMMO().isVolatile(); }
62 /// Returns true if the memory operation is neither atomic or volatile.
63 bool isSimple() const { return !isAtomic() && !isVolatile(); }
64 /// Returns true if this memory operation doesn't have any ordering
65 /// constraints other than normal aliasing. Volatile and (ordered) atomic
66 /// memory operations can't be reordered.
67 bool isUnordered() const { return getMMO().isUnordered(); }
68
69 /// Return the minimum known alignment in bytes of the actual memory
70 /// reference.
71 Align getAlign() const { return getMMO().getAlign(); }
72 /// Returns the size in bytes of the memory access.
73 LocationSize getMemSize() const { return getMMO().getSize(); }
74 /// Returns the size in bits of the memory access.
76
77 static bool classof(const MachineInstr *MI) {
78 return GenericMachineInstr::classof(MI) && MI->hasOneMemOperand();
79 }
80};
81
82/// Represents any type of generic load or store.
83/// G_LOAD, G_STORE, G_ZEXTLOAD, G_SEXTLOAD, G_FPEXTLOAD, G_FPTRUNCSTORE.
84class GLoadStore : public GMemOperation {
85public:
86 /// Get the source register of the pointer value.
87 Register getPointerReg() const { return getOperand(1).getReg(); }
88
89 static bool classof(const MachineInstr *MI) {
90 switch (MI->getOpcode()) {
91 case TargetOpcode::G_LOAD:
92 case TargetOpcode::G_STORE:
93 case TargetOpcode::G_ZEXTLOAD:
94 case TargetOpcode::G_SEXTLOAD:
95 case TargetOpcode::G_FPEXTLOAD:
96 case TargetOpcode::G_FPTRUNCSTORE:
97 return true;
98 default:
99 return false;
100 }
101 }
102};
103
104/// Represents indexed loads. These are different enough from regular loads
105/// that they get their own class. Including them in GAnyLoad would probably
106/// make a footgun for someone.
108public:
109 /// Get the definition register of the loaded value.
110 Register getDstReg() const { return getOperand(0).getReg(); }
111 /// Get the def register of the writeback value.
112 Register getWritebackReg() const { return getOperand(1).getReg(); }
113 /// Get the base register of the pointer value.
114 Register getBaseReg() const { return getOperand(2).getReg(); }
115 /// Get the offset register of the pointer value.
116 Register getOffsetReg() const { return getOperand(3).getReg(); }
117
118 bool isPre() const { return getOperand(4).getImm() == 1; }
119 bool isPost() const { return !isPre(); }
120
121 static bool classof(const MachineInstr *MI) {
122 return MI->getOpcode() == TargetOpcode::G_INDEXED_LOAD;
123 }
124};
125
126/// Represents a G_INDEX_ZEXTLOAD/G_INDEXED_SEXTLOAD.
128public:
129 static bool classof(const MachineInstr *MI) {
130 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD ||
131 MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
132 }
133};
134
135/// Represents either G_INDEXED_LOAD, G_INDEXED_ZEXTLOAD or G_INDEXED_SEXTLOAD.
137public:
138 static bool classof(const MachineInstr *MI) {
139 switch (MI->getOpcode()) {
140 case TargetOpcode::G_INDEXED_LOAD:
141 case TargetOpcode::G_INDEXED_ZEXTLOAD:
142 case TargetOpcode::G_INDEXED_SEXTLOAD:
143 return true;
144 default:
145 return false;
146 }
147 }
148};
149
150/// Represents a G_ZEXTLOAD.
152public:
153 static bool classof(const MachineInstr *MI) {
154 return MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
155 }
156};
157
158/// Represents a G_SEXTLOAD.
160public:
161 static bool classof(const MachineInstr *MI) {
162 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD;
163 }
164};
165
166/// Represents indexed stores.
168public:
169 /// Get the def register of the writeback value.
170 Register getWritebackReg() const { return getOperand(0).getReg(); }
171 /// Get the stored value register.
172 Register getValueReg() const { return getOperand(1).getReg(); }
173 /// Get the base register of the pointer value.
174 Register getBaseReg() const { return getOperand(2).getReg(); }
175 /// Get the offset register of the pointer value.
176 Register getOffsetReg() const { return getOperand(3).getReg(); }
177
178 bool isPre() const { return getOperand(4).getImm() == 1; }
179 bool isPost() const { return !isPre(); }
180
181 static bool classof(const MachineInstr *MI) {
182 return MI->getOpcode() == TargetOpcode::G_INDEXED_STORE;
183 }
184};
185
186/// Represents any generic load, including sign/zero extending variants.
187class GAnyLoad : public GLoadStore {
188public:
189 /// Get the definition register of the loaded value.
190 Register getDstReg() const { return getOperand(0).getReg(); }
191
192 /// Returns the Ranges that describes the dereference.
193 const MDNode *getRanges() const {
194 return getMMO().getRanges();
195 }
196
197 /// Returns the cache hint metadata for this load.
198 const MDNode *getMemCacheHint() const { return getMMO().getMemCacheHint(); }
199
200 static bool classof(const MachineInstr *MI) {
201 switch (MI->getOpcode()) {
202 case TargetOpcode::G_LOAD:
203 case TargetOpcode::G_ZEXTLOAD:
204 case TargetOpcode::G_SEXTLOAD:
205 case TargetOpcode::G_FPEXTLOAD:
206 return true;
207 default:
208 return false;
209 }
210 }
211};
212
213/// Represents a G_LOAD.
214class GLoad : public GAnyLoad {
215public:
216 static bool classof(const MachineInstr *MI) {
217 return MI->getOpcode() == TargetOpcode::G_LOAD;
218 }
219};
220
221/// Represents either a G_SEXTLOAD, G_ZEXTLOAD, or G_FPEXTLOAD.
222class GExtLoad : public GAnyLoad {
223public:
224 static bool classof(const MachineInstr *MI) {
225 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD ||
226 MI->getOpcode() == TargetOpcode::G_ZEXTLOAD ||
227 MI->getOpcode() == TargetOpcode::G_FPEXTLOAD;
228 }
229};
230
231/// Represents a G_SEXTLOAD.
232class GSExtLoad : public GExtLoad {
233public:
234 static bool classof(const MachineInstr *MI) {
235 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD;
236 }
237};
238
239/// Represents a G_ZEXTLOAD.
240class GZExtLoad : public GExtLoad {
241public:
242 static bool classof(const MachineInstr *MI) {
243 return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
244 }
245};
246
247/// Represents a G_FPEXTLOAD.
248class GFPExtLoad : public GAnyLoad {
249public:
250 static bool classof(const MachineInstr *MI) {
251 return MI->getOpcode() == TargetOpcode::G_FPEXTLOAD;
252 }
253};
254
255/// Represents any generic store, including truncating variants.
256class GAnyStore : public GLoadStore {
257public:
258 /// Get the stored value register.
259 Register getValueReg() const { return getOperand(0).getReg(); }
260
261 static bool classof(const MachineInstr *MI) {
262 switch (MI->getOpcode()) {
263 case TargetOpcode::G_STORE:
264 case TargetOpcode::G_FPTRUNCSTORE:
265 return true;
266 default:
267 return false;
268 }
269 }
270};
271
272/// Represents a G_STORE.
273class GStore : public GAnyStore {
274public:
275 static bool classof(const MachineInstr *MI) {
276 return MI->getOpcode() == TargetOpcode::G_STORE;
277 }
278};
279
280/// Represents a G_FPTRUNCSTORE.
281class GFPTruncStore : public GAnyStore {
282public:
283 static bool classof(const MachineInstr *MI) {
284 return MI->getOpcode() == TargetOpcode::G_FPTRUNCSTORE;
285 }
286};
287
288/// Represents a G_UNMERGE_VALUES.
290public:
291 /// Returns the number of def registers.
292 unsigned getNumDefs() const { return getNumOperands() - 1; }
293 /// Get the unmerge source register.
295
296 static bool classof(const MachineInstr *MI) {
297 return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES;
298 }
299};
300
301/// Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
302/// All these have the common property of generating a single value from
303/// multiple sources.
305public:
306 /// Returns the number of source registers.
307 unsigned getNumSources() const { return getNumOperands() - 1; }
308 /// Returns the I'th source register.
309 Register getSourceReg(unsigned I) const { return getReg(I + 1); }
310
311 static bool classof(const MachineInstr *MI) {
312 switch (MI->getOpcode()) {
313 case TargetOpcode::G_MERGE_VALUES:
314 case TargetOpcode::G_CONCAT_VECTORS:
315 case TargetOpcode::G_BUILD_VECTOR:
316 return true;
317 default:
318 return false;
319 }
320 }
321};
322
323/// Represents a G_MERGE_VALUES.
324class GMerge : public GMergeLikeInstr {
325public:
326 static bool classof(const MachineInstr *MI) {
327 return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES;
328 }
329};
330
331/// Represents a G_CONCAT_VECTORS.
333public:
334 static bool classof(const MachineInstr *MI) {
335 return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
336 }
337};
338
339/// Represents a G_BUILD_VECTOR.
341public:
342 static bool classof(const MachineInstr *MI) {
343 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR;
344 }
345};
346
347/// Represents a G_BUILD_VECTOR_TRUNC.
349public:
350 static bool classof(const MachineInstr *MI) {
351 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC;
352 }
353};
354
355/// Represents a G_SHUFFLE_VECTOR.
357public:
358 Register getSrc1Reg() const { return getOperand(1).getReg(); }
359 Register getSrc2Reg() const { return getOperand(2).getReg(); }
361
362 static bool classof(const MachineInstr *MI) {
363 return MI->getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR;
364 }
365};
366
367/// Represents a G_PTR_ADD.
369public:
370 Register getBaseReg() const { return getReg(1); }
371 Register getOffsetReg() const { return getReg(2); }
372
373 static bool classof(const MachineInstr *MI) {
374 return MI->getOpcode() == TargetOpcode::G_PTR_ADD;
375 }
376};
377
378/// Represents a G_IMPLICIT_DEF.
380public:
381 static bool classof(const MachineInstr *MI) {
382 return MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
383 }
384};
385
386/// Represents a G_SELECT.
388public:
389 Register getCondReg() const { return getReg(1); }
390 Register getTrueReg() const { return getReg(2); }
391 Register getFalseReg() const { return getReg(3); }
392
393 static bool classof(const MachineInstr *MI) {
394 return MI->getOpcode() == TargetOpcode::G_SELECT;
395 }
396};
397
398/// Represent a G_ICMP or G_FCMP.
400public:
402 return static_cast<CmpInst::Predicate>(getOperand(1).getPredicate());
403 }
404 Register getLHSReg() const { return getReg(2); }
405 Register getRHSReg() const { return getReg(3); }
406
407 static bool classof(const MachineInstr *MI) {
408 return MI->getOpcode() == TargetOpcode::G_ICMP ||
409 MI->getOpcode() == TargetOpcode::G_FCMP;
410 }
411};
412
413/// Represent a G_ICMP.
414class GICmp : public GAnyCmp {
415public:
416 static bool classof(const MachineInstr *MI) {
417 return MI->getOpcode() == TargetOpcode::G_ICMP;
418 }
419};
420
421/// Represent a G_FCMP.
422class GFCmp : public GAnyCmp {
423public:
424 static bool classof(const MachineInstr *MI) {
425 return MI->getOpcode() == TargetOpcode::G_FCMP;
426 }
427};
428
429/// Represents overflowing binary operations.
430/// Only carry-out:
431/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_UMULO, G_SMULO
432/// Carry-in and carry-out:
433/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
435public:
436 Register getDstReg() const { return getReg(0); }
437 Register getCarryOutReg() const { return getReg(1); }
440 Register getLHSReg() const { return getOperand(2).getReg(); }
441 Register getRHSReg() const { return getOperand(3).getReg(); }
442
443 static bool classof(const MachineInstr *MI) {
444 switch (MI->getOpcode()) {
445 case TargetOpcode::G_UADDO:
446 case TargetOpcode::G_SADDO:
447 case TargetOpcode::G_USUBO:
448 case TargetOpcode::G_SSUBO:
449 case TargetOpcode::G_UADDE:
450 case TargetOpcode::G_SADDE:
451 case TargetOpcode::G_USUBE:
452 case TargetOpcode::G_SSUBE:
453 case TargetOpcode::G_UMULO:
454 case TargetOpcode::G_SMULO:
455 return true;
456 default:
457 return false;
458 }
459 }
460};
461
462/// Represents overflowing add/sub operations.
463/// Only carry-out:
464/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO
465/// Carry-in and carry-out:
466/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
468public:
469 bool isAdd() const {
470 switch (getOpcode()) {
471 case TargetOpcode::G_UADDO:
472 case TargetOpcode::G_SADDO:
473 case TargetOpcode::G_UADDE:
474 case TargetOpcode::G_SADDE:
475 return true;
476 default:
477 return false;
478 }
479 }
480 bool isSub() const { return !isAdd(); }
481
482 bool isSigned() const {
483 switch (getOpcode()) {
484 case TargetOpcode::G_SADDO:
485 case TargetOpcode::G_SSUBO:
486 case TargetOpcode::G_SADDE:
487 case TargetOpcode::G_SSUBE:
488 return true;
489 default:
490 return false;
491 }
492 }
493 bool isUnsigned() const { return !isSigned(); }
494
495 static bool classof(const MachineInstr *MI) {
496 switch (MI->getOpcode()) {
497 case TargetOpcode::G_UADDO:
498 case TargetOpcode::G_SADDO:
499 case TargetOpcode::G_USUBO:
500 case TargetOpcode::G_SSUBO:
501 case TargetOpcode::G_UADDE:
502 case TargetOpcode::G_SADDE:
503 case TargetOpcode::G_USUBE:
504 case TargetOpcode::G_SSUBE:
505 return true;
506 default:
507 return false;
508 }
509 }
510};
511
512/// Represents overflowing add operations.
513/// G_UADDO, G_SADDO
515public:
516 bool isSigned() const { return getOpcode() == TargetOpcode::G_SADDO; }
517
518 static bool classof(const MachineInstr *MI) {
519 switch (MI->getOpcode()) {
520 case TargetOpcode::G_UADDO:
521 case TargetOpcode::G_SADDO:
522 return true;
523 default:
524 return false;
525 }
526 }
527};
528
529/// Represents overflowing sub operations.
530/// G_USUBO, G_SSUBO
532public:
533 bool isSigned() const { return getOpcode() == TargetOpcode::G_SSUBO; }
534
535 static bool classof(const MachineInstr *MI) {
536 switch (MI->getOpcode()) {
537 case TargetOpcode::G_USUBO:
538 case TargetOpcode::G_SSUBO:
539 return true;
540 default:
541 return false;
542 }
543 }
544};
545
546/// Represents overflowing add/sub operations that also consume a carry-in.
547/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
549public:
550 Register getCarryInReg() const { return getReg(4); }
551
552 static bool classof(const MachineInstr *MI) {
553 switch (MI->getOpcode()) {
554 case TargetOpcode::G_UADDE:
555 case TargetOpcode::G_SADDE:
556 case TargetOpcode::G_USUBE:
557 case TargetOpcode::G_SSUBE:
558 return true;
559 default:
560 return false;
561 }
562 }
563};
564
565/// Represents a call to an intrinsic.
566class GIntrinsic final : public GenericMachineInstr {
567public:
571
572 bool is(Intrinsic::ID ID) const { return getIntrinsicID() == ID; }
573
574 bool hasSideEffects() const {
575 switch (getOpcode()) {
576 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
577 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
578 return true;
579 default:
580 return false;
581 }
582 }
583
584 bool isConvergent() const {
585 switch (getOpcode()) {
586 case TargetOpcode::G_INTRINSIC_CONVERGENT:
587 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
588 return true;
589 default:
590 return false;
591 }
592 }
593
594 static bool classof(const MachineInstr *MI) {
595 switch (MI->getOpcode()) {
596 case TargetOpcode::G_INTRINSIC:
597 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
598 case TargetOpcode::G_INTRINSIC_CONVERGENT:
599 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
600 return true;
601 default:
602 return false;
603 }
604 }
605};
606
607// Represents a (non-sequential) vector reduction operation.
609public:
610 static bool classof(const MachineInstr *MI) {
611 switch (MI->getOpcode()) {
612 case TargetOpcode::G_VECREDUCE_FADD:
613 case TargetOpcode::G_VECREDUCE_FMUL:
614 case TargetOpcode::G_VECREDUCE_FMAX:
615 case TargetOpcode::G_VECREDUCE_FMIN:
616 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
617 case TargetOpcode::G_VECREDUCE_FMINIMUM:
618 case TargetOpcode::G_VECREDUCE_FMAXIMUMNUM:
619 case TargetOpcode::G_VECREDUCE_FMINIMUMNUM:
620 case TargetOpcode::G_VECREDUCE_ADD:
621 case TargetOpcode::G_VECREDUCE_MUL:
622 case TargetOpcode::G_VECREDUCE_AND:
623 case TargetOpcode::G_VECREDUCE_OR:
624 case TargetOpcode::G_VECREDUCE_XOR:
625 case TargetOpcode::G_VECREDUCE_SMAX:
626 case TargetOpcode::G_VECREDUCE_SMIN:
627 case TargetOpcode::G_VECREDUCE_UMAX:
628 case TargetOpcode::G_VECREDUCE_UMIN:
629 return true;
630 default:
631 return false;
632 }
633 }
634
635 /// Get the opcode for the equivalent scalar operation for this reduction.
636 /// E.g. for G_VECREDUCE_FADD, this returns G_FADD.
638 unsigned ScalarOpc;
639 switch (getOpcode()) {
640 case TargetOpcode::G_VECREDUCE_FADD:
641 ScalarOpc = TargetOpcode::G_FADD;
642 break;
643 case TargetOpcode::G_VECREDUCE_FMUL:
644 ScalarOpc = TargetOpcode::G_FMUL;
645 break;
646 case TargetOpcode::G_VECREDUCE_FMAX:
647 ScalarOpc = TargetOpcode::G_FMAXNUM;
648 break;
649 case TargetOpcode::G_VECREDUCE_FMIN:
650 ScalarOpc = TargetOpcode::G_FMINNUM;
651 break;
652 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
653 ScalarOpc = TargetOpcode::G_FMAXIMUM;
654 break;
655 case TargetOpcode::G_VECREDUCE_FMINIMUM:
656 ScalarOpc = TargetOpcode::G_FMINIMUM;
657 break;
658 case TargetOpcode::G_VECREDUCE_FMAXIMUMNUM:
659 ScalarOpc = TargetOpcode::G_FMAXIMUMNUM;
660 break;
661 case TargetOpcode::G_VECREDUCE_FMINIMUMNUM:
662 ScalarOpc = TargetOpcode::G_FMINIMUMNUM;
663 break;
664 case TargetOpcode::G_VECREDUCE_ADD:
665 ScalarOpc = TargetOpcode::G_ADD;
666 break;
667 case TargetOpcode::G_VECREDUCE_MUL:
668 ScalarOpc = TargetOpcode::G_MUL;
669 break;
670 case TargetOpcode::G_VECREDUCE_AND:
671 ScalarOpc = TargetOpcode::G_AND;
672 break;
673 case TargetOpcode::G_VECREDUCE_OR:
674 ScalarOpc = TargetOpcode::G_OR;
675 break;
676 case TargetOpcode::G_VECREDUCE_XOR:
677 ScalarOpc = TargetOpcode::G_XOR;
678 break;
679 case TargetOpcode::G_VECREDUCE_SMAX:
680 ScalarOpc = TargetOpcode::G_SMAX;
681 break;
682 case TargetOpcode::G_VECREDUCE_SMIN:
683 ScalarOpc = TargetOpcode::G_SMIN;
684 break;
685 case TargetOpcode::G_VECREDUCE_UMAX:
686 ScalarOpc = TargetOpcode::G_UMAX;
687 break;
688 case TargetOpcode::G_VECREDUCE_UMIN:
689 ScalarOpc = TargetOpcode::G_UMIN;
690 break;
691 default:
692 llvm_unreachable("Unhandled reduction");
693 }
694 return ScalarOpc;
695 }
696};
697
698/// Represents a G_PHI.
699class GPhi : public GenericMachineInstr {
700public:
701 /// Returns the number of incoming values.
702 unsigned getNumIncomingValues() const { return (getNumOperands() - 1) / 2; }
703 /// Returns the I'th incoming vreg.
704 Register getIncomingValue(unsigned I) const {
705 return getOperand(I * 2 + 1).getReg();
706 }
707 /// Returns the I'th incoming basic block.
709 return getOperand(I * 2 + 2).getMBB();
710 }
711
712 static bool classof(const MachineInstr *MI) {
713 return MI->getOpcode() == TargetOpcode::G_PHI;
714 }
715};
716
717/// Represents a binary operation, i.e, x = y op z.
719public:
720 Register getLHSReg() const { return getReg(1); }
721 Register getRHSReg() const { return getReg(2); }
722
723 static bool classof(const MachineInstr *MI) {
724 switch (MI->getOpcode()) {
725 // Integer.
726 case TargetOpcode::G_ADD:
727 case TargetOpcode::G_SUB:
728 case TargetOpcode::G_MUL:
729 case TargetOpcode::G_SDIV:
730 case TargetOpcode::G_UDIV:
731 case TargetOpcode::G_SREM:
732 case TargetOpcode::G_UREM:
733 case TargetOpcode::G_SMIN:
734 case TargetOpcode::G_SMAX:
735 case TargetOpcode::G_UMIN:
736 case TargetOpcode::G_UMAX:
737 // Floating point.
738 case TargetOpcode::G_FMINNUM:
739 case TargetOpcode::G_FMAXNUM:
740 case TargetOpcode::G_FMINNUM_IEEE:
741 case TargetOpcode::G_FMAXNUM_IEEE:
742 case TargetOpcode::G_FMINIMUM:
743 case TargetOpcode::G_FMAXIMUM:
744 case TargetOpcode::G_FADD:
745 case TargetOpcode::G_FSUB:
746 case TargetOpcode::G_FMUL:
747 case TargetOpcode::G_FDIV:
748 case TargetOpcode::G_FPOW:
749 // Logical.
750 case TargetOpcode::G_AND:
751 case TargetOpcode::G_OR:
752 case TargetOpcode::G_XOR:
753 return true;
754 default:
755 return false;
756 }
757 };
758};
759
760/// Represents an integer binary operation.
761class GIntBinOp : public GBinOp {
762public:
763 static bool classof(const MachineInstr *MI) {
764 switch (MI->getOpcode()) {
765 case TargetOpcode::G_ADD:
766 case TargetOpcode::G_SUB:
767 case TargetOpcode::G_MUL:
768 case TargetOpcode::G_SDIV:
769 case TargetOpcode::G_UDIV:
770 case TargetOpcode::G_SREM:
771 case TargetOpcode::G_UREM:
772 case TargetOpcode::G_SMIN:
773 case TargetOpcode::G_SMAX:
774 case TargetOpcode::G_UMIN:
775 case TargetOpcode::G_UMAX:
776 return true;
777 default:
778 return false;
779 }
780 };
781};
782
783/// Represents a floating point binary operation.
784class GFBinOp : public GBinOp {
785public:
786 static bool classof(const MachineInstr *MI) {
787 switch (MI->getOpcode()) {
788 case TargetOpcode::G_FMINNUM:
789 case TargetOpcode::G_FMAXNUM:
790 case TargetOpcode::G_FMINNUM_IEEE:
791 case TargetOpcode::G_FMAXNUM_IEEE:
792 case TargetOpcode::G_FMINIMUM:
793 case TargetOpcode::G_FMAXIMUM:
794 case TargetOpcode::G_FADD:
795 case TargetOpcode::G_FSUB:
796 case TargetOpcode::G_FMUL:
797 case TargetOpcode::G_FDIV:
798 case TargetOpcode::G_FPOW:
799 return true;
800 default:
801 return false;
802 }
803 };
804};
805
806/// Represents a logical binary operation.
807class GLogicalBinOp : public GBinOp {
808public:
809 static bool classof(const MachineInstr *MI) {
810 switch (MI->getOpcode()) {
811 case TargetOpcode::G_AND:
812 case TargetOpcode::G_OR:
813 case TargetOpcode::G_XOR:
814 return true;
815 default:
816 return false;
817 }
818 };
819};
820
821/// Represents an integer addition.
822class GAdd : public GIntBinOp {
823public:
824 static bool classof(const MachineInstr *MI) {
825 return MI->getOpcode() == TargetOpcode::G_ADD;
826 };
827};
828
829/// Represents a logical and.
830class GAnd : public GLogicalBinOp {
831public:
832 static bool classof(const MachineInstr *MI) {
833 return MI->getOpcode() == TargetOpcode::G_AND;
834 };
835};
836
837/// Represents a logical or.
838class GOr : public GLogicalBinOp {
839public:
840 static bool classof(const MachineInstr *MI) {
841 return MI->getOpcode() == TargetOpcode::G_OR;
842 };
843};
844
845/// Represents an extract vector element.
847public:
848 Register getVectorReg() const { return getOperand(1).getReg(); }
849 Register getIndexReg() const { return getOperand(2).getReg(); }
850
851 static bool classof(const MachineInstr *MI) {
852 return MI->getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT;
853 }
854};
855
856/// Represents an insert vector element.
858public:
859 Register getVectorReg() const { return getOperand(1).getReg(); }
860 Register getElementReg() const { return getOperand(2).getReg(); }
861 Register getIndexReg() const { return getOperand(3).getReg(); }
862
863 static bool classof(const MachineInstr *MI) {
864 return MI->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
865 }
866};
867
868/// Represents an extract subvector.
870public:
871 Register getSrcVec() const { return getOperand(1).getReg(); }
872 uint64_t getIndexImm() const { return getOperand(2).getImm(); }
873
874 static bool classof(const MachineInstr *MI) {
875 return MI->getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR;
876 }
877};
878
879/// Represents a insert subvector.
881public:
882 Register getBigVec() const { return getOperand(1).getReg(); }
883 Register getSubVec() const { return getOperand(2).getReg(); }
884 uint64_t getIndexImm() const { return getOperand(3).getImm(); }
885
886 static bool classof(const MachineInstr *MI) {
887 return MI->getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR;
888 }
889};
890
891/// Represents a freeze.
893public:
894 Register getSourceReg() const { return getOperand(1).getReg(); }
895
896 static bool classof(const MachineInstr *MI) {
897 return MI->getOpcode() == TargetOpcode::G_FREEZE;
898 }
899};
900
901/// Represents a cast operation.
902/// It models the llvm::CastInst concept.
903/// The exception is bitcast.
905public:
906 Register getSrcReg() const { return getOperand(1).getReg(); }
907
908 static bool classof(const MachineInstr *MI) {
909 switch (MI->getOpcode()) {
910 case TargetOpcode::G_ADDRSPACE_CAST:
911 case TargetOpcode::G_FPEXT:
912 case TargetOpcode::G_FPTOSI:
913 case TargetOpcode::G_FPTOUI:
914 case TargetOpcode::G_FPTOSI_SAT:
915 case TargetOpcode::G_FPTOUI_SAT:
916 case TargetOpcode::G_FPTRUNC:
917 case TargetOpcode::G_INTTOPTR:
918 case TargetOpcode::G_PTRTOINT:
919 case TargetOpcode::G_SEXT:
920 case TargetOpcode::G_SITOFP:
921 case TargetOpcode::G_TRUNC:
922 case TargetOpcode::G_TRUNC_SSAT_S:
923 case TargetOpcode::G_TRUNC_SSAT_U:
924 case TargetOpcode::G_TRUNC_USAT_U:
925 case TargetOpcode::G_UITOFP:
926 case TargetOpcode::G_ZEXT:
927 case TargetOpcode::G_ANYEXT:
928 return true;
929 default:
930 return false;
931 }
932 };
933};
934
935/// Represents a sext.
936class GSext : public GCastOp {
937public:
938 static bool classof(const MachineInstr *MI) {
939 return MI->getOpcode() == TargetOpcode::G_SEXT;
940 };
941};
942
943/// Represents a zext.
944class GZext : public GCastOp {
945public:
946 static bool classof(const MachineInstr *MI) {
947 return MI->getOpcode() == TargetOpcode::G_ZEXT;
948 };
949};
950
951/// Represents an any ext.
952class GAnyExt : public GCastOp {
953public:
954 static bool classof(const MachineInstr *MI) {
955 return MI->getOpcode() == TargetOpcode::G_ANYEXT;
956 };
957};
958
959/// Represents a trunc.
960class GTrunc : public GCastOp {
961public:
962 static bool classof(const MachineInstr *MI) {
963 return MI->getOpcode() == TargetOpcode::G_TRUNC;
964 };
965};
966
967/// Represents a vscale.
969public:
970 APInt getSrc() const { return getOperand(1).getCImm()->getValue(); }
971
972 static bool classof(const MachineInstr *MI) {
973 return MI->getOpcode() == TargetOpcode::G_VSCALE;
974 };
975};
976
977/// Represents a step vector.
979public:
981 return getOperand(1).getCImm()->getValue().getZExtValue();
982 }
983
984 static bool classof(const MachineInstr *MI) {
985 return MI->getOpcode() == TargetOpcode::G_STEP_VECTOR;
986 };
987};
988
989/// Represents a G_CONSTANT.
991public:
992 const ConstantInt *getConstantInt() const { return getOperand(1).getCImm(); }
993 const APInt &getValue() const { return getConstantInt()->getValue(); }
994
995 static bool classof(const MachineInstr *MI) {
996 return MI->getOpcode() == TargetOpcode::G_CONSTANT;
997 };
998};
999
1000/// Represents an integer subtraction.
1001class GSub : public GIntBinOp {
1002public:
1003 static bool classof(const MachineInstr *MI) {
1004 return MI->getOpcode() == TargetOpcode::G_SUB;
1005 };
1006};
1007
1008/// Represents an integer multiplication.
1009class GMul : public GIntBinOp {
1010public:
1011 static bool classof(const MachineInstr *MI) {
1012 return MI->getOpcode() == TargetOpcode::G_MUL;
1013 };
1014};
1015
1016/// Represents a shift left.
1018public:
1019 Register getSrcReg() const { return getOperand(1).getReg(); }
1020 Register getShiftReg() const { return getOperand(2).getReg(); }
1021
1022 static bool classof(const MachineInstr *MI) {
1023 return MI->getOpcode() == TargetOpcode::G_SHL;
1024 };
1025};
1026
1027/// Represents a threeway compare.
1029public:
1030 Register getLHSReg() const { return getOperand(1).getReg(); }
1031 Register getRHSReg() const { return getOperand(2).getReg(); }
1032
1033 bool isSigned() const { return getOpcode() == TargetOpcode::G_SCMP; }
1034
1035 static bool classof(const MachineInstr *MI) {
1036 switch (MI->getOpcode()) {
1037 case TargetOpcode::G_SCMP:
1038 case TargetOpcode::G_UCMP:
1039 return true;
1040 default:
1041 return false;
1042 }
1043 };
1044};
1045
1046/// Represents an integer-like extending operation.
1047class GExtOp : public GCastOp {
1048public:
1049 static bool classof(const MachineInstr *MI) {
1050 switch (MI->getOpcode()) {
1051 case TargetOpcode::G_SEXT:
1052 case TargetOpcode::G_ZEXT:
1053 case TargetOpcode::G_ANYEXT:
1054 return true;
1055 default:
1056 return false;
1057 }
1058 };
1059};
1060
1061/// Represents an integer-like extending or truncating operation.
1062class GExtOrTruncOp : public GCastOp {
1063public:
1064 static bool classof(const MachineInstr *MI) {
1065 switch (MI->getOpcode()) {
1066 case TargetOpcode::G_SEXT:
1067 case TargetOpcode::G_ZEXT:
1068 case TargetOpcode::G_ANYEXT:
1069 case TargetOpcode::G_TRUNC:
1070 return true;
1071 default:
1072 return false;
1073 }
1074 };
1075};
1076
1077/// Represents a splat vector.
1079public:
1080 Register getScalarReg() const { return getOperand(1).getReg(); }
1081
1082 static bool classof(const MachineInstr *MI) {
1083 return MI->getOpcode() == TargetOpcode::G_SPLAT_VECTOR;
1084 };
1085};
1086
1087} // namespace llvm
1088
1089#endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file implements a class to represent arbitrary precision integral constant values and operations...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1561
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
This is the shared class of boolean and integer constants.
Definition Constants.h:87
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
Represents overflowing add operations.
static bool classof(const MachineInstr *MI)
Represents overflowing add/sub operations that also consume a carry-in.
static bool classof(const MachineInstr *MI)
Represents overflowing add/sub operations.
static bool classof(const MachineInstr *MI)
Represents an integer addition.
static bool classof(const MachineInstr *MI)
Represents a logical and.
static bool classof(const MachineInstr *MI)
Represent a G_ICMP or G_FCMP.
static bool classof(const MachineInstr *MI)
CmpInst::Predicate getCond() const
Register getLHSReg() const
Register getRHSReg() const
Represents an any ext.
static bool classof(const MachineInstr *MI)
Represents any generic load, including sign/zero extending variants.
const MDNode * getMemCacheHint() const
Returns the cache hint metadata for this load.
Register getDstReg() const
Get the definition register of the loaded value.
static bool classof(const MachineInstr *MI)
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
Represents any generic store, including truncating variants.
static bool classof(const MachineInstr *MI)
Register getValueReg() const
Get the stored value register.
Represents overflowing binary operations.
MachineOperand & getRHS()
MachineOperand & getLHS()
Register getCarryOutReg() const
static bool classof(const MachineInstr *MI)
Represents a binary operation, i.e, x = y op z.
Register getLHSReg() const
static bool classof(const MachineInstr *MI)
Register getRHSReg() const
Represents a G_BUILD_VECTOR_TRUNC.
static bool classof(const MachineInstr *MI)
Represents a G_BUILD_VECTOR.
static bool classof(const MachineInstr *MI)
Represents a cast operation.
static bool classof(const MachineInstr *MI)
Register getSrcReg() const
Represents a G_CONCAT_VECTORS.
static bool classof(const MachineInstr *MI)
Represents a G_CONSTANT.
static bool classof(const MachineInstr *MI)
const APInt & getValue() const
const ConstantInt * getConstantInt() const
Represents either a G_SEXTLOAD, G_ZEXTLOAD, or G_FPEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents an integer-like extending operation.
static bool classof(const MachineInstr *MI)
Represents an integer-like extending or truncating operation.
static bool classof(const MachineInstr *MI)
Represents an extract subvector.
static bool classof(const MachineInstr *MI)
Represents an extract vector element.
static bool classof(const MachineInstr *MI)
Represents a floating point binary operation.
static bool classof(const MachineInstr *MI)
Represent a G_FCMP.
static bool classof(const MachineInstr *MI)
Represents a G_FPEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents a G_FPTRUNCSTORE.
static bool classof(const MachineInstr *MI)
Represents a freeze.
Register getSourceReg() const
static bool classof(const MachineInstr *MI)
Represent a G_ICMP.
static bool classof(const MachineInstr *MI)
Represents a G_IMPLICIT_DEF.
static bool classof(const MachineInstr *MI)
Represents either G_INDEXED_LOAD, G_INDEXED_ZEXTLOAD or G_INDEXED_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents a G_INDEX_ZEXTLOAD/G_INDEXED_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents indexed loads.
static bool classof(const MachineInstr *MI)
Register getOffsetReg() const
Get the offset register of the pointer value.
Register getWritebackReg() const
Get the def register of the writeback value.
Register getDstReg() const
Get the definition register of the loaded value.
Register getBaseReg() const
Get the base register of the pointer value.
Represents a G_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents indexed stores.
Register getOffsetReg() const
Get the offset register of the pointer value.
Register getValueReg() const
Get the stored value register.
Register getBaseReg() const
Get the base register of the pointer value.
static bool classof(const MachineInstr *MI)
Register getWritebackReg() const
Get the def register of the writeback value.
Represents a G_ZEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents a insert subvector.
static bool classof(const MachineInstr *MI)
Represents an insert vector element.
static bool classof(const MachineInstr *MI)
Represents an integer binary operation.
static bool classof(const MachineInstr *MI)
Represents a call to an intrinsic.
Intrinsic::ID getIntrinsicID() const
bool is(Intrinsic::ID ID) const
static bool classof(const MachineInstr *MI)
Represents any type of generic load or store.
Register getPointerReg() const
Get the source register of the pointer value.
static bool classof(const MachineInstr *MI)
Represents a G_LOAD.
static bool classof(const MachineInstr *MI)
Represents a logical binary operation.
static bool classof(const MachineInstr *MI)
Provides common memory operand functionality.
MachineMemOperand & getMMO() const
Get the MachineMemOperand on this instruction.
LocationSize getMemSize() const
Returns the size in bytes of the memory access.
bool isUnordered() const
Returns true if this memory operation doesn't have any ordering constraints other than normal aliasin...
bool isAtomic() const
Returns true if the attached MachineMemOperand has the atomic flag set.
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
bool isVolatile() const
Returns true if the attached MachineMemOpeand as the volatile flag set.
static bool classof(const MachineInstr *MI)
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
Register getSourceReg(unsigned I) const
Returns the I'th source register.
unsigned getNumSources() const
Returns the number of source registers.
static bool classof(const MachineInstr *MI)
Represents a G_MERGE_VALUES.
static bool classof(const MachineInstr *MI)
Represents an integer multiplication.
static bool classof(const MachineInstr *MI)
Represents a logical or.
static bool classof(const MachineInstr *MI)
Represents a G_PHI.
MachineBasicBlock * getIncomingBlock(unsigned I) const
Returns the I'th incoming basic block.
Register getIncomingValue(unsigned I) const
Returns the I'th incoming vreg.
static bool classof(const MachineInstr *MI)
unsigned getNumIncomingValues() const
Returns the number of incoming values.
Represents a G_PTR_ADD.
Register getOffsetReg() const
static bool classof(const MachineInstr *MI)
Register getBaseReg() const
Represents a G_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents a threeway compare.
Register getRHSReg() const
Register getLHSReg() const
static bool classof(const MachineInstr *MI)
Represents a G_SELECT.
Register getCondReg() const
static bool classof(const MachineInstr *MI)
Register getFalseReg() const
Register getTrueReg() const
Represents a sext.
static bool classof(const MachineInstr *MI)
Represents a shift left.
Register getShiftReg() const
static bool classof(const MachineInstr *MI)
Register getSrcReg() const
Represents a G_SHUFFLE_VECTOR.
static bool classof(const MachineInstr *MI)
ArrayRef< int > getMask() const
Represents a splat vector.
Register getScalarReg() const
static bool classof(const MachineInstr *MI)
Represents a step vector.
static bool classof(const MachineInstr *MI)
uint64_t getStep() const
Represents a G_STORE.
static bool classof(const MachineInstr *MI)
Represents overflowing sub operations.
static bool classof(const MachineInstr *MI)
Represents an integer subtraction.
static bool classof(const MachineInstr *MI)
Represents a trunc.
static bool classof(const MachineInstr *MI)
Represents a G_UNMERGE_VALUES.
unsigned getNumDefs() const
Returns the number of def registers.
static bool classof(const MachineInstr *MI)
Register getSourceReg() const
Get the unmerge source register.
Represents a vscale.
static bool classof(const MachineInstr *MI)
unsigned getScalarOpcForReduction()
Get the opcode for the equivalent scalar operation for this reduction.
static bool classof(const MachineInstr *MI)
Represents a G_ZEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents a zext.
static bool classof(const MachineInstr *MI)
static bool classof(const MachineInstr *MI)
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
Metadata node.
Definition Metadata.h:1069
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getNumOperands() const
Retuns the total number of operands.
void clearFlags(unsigned flags)
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
bool isUnordered() const
Returns true if this memory operation doesn't have any ordering constraints other than normal aliasin...
const MDNode * getRanges() const
Return the range tag for the memory reference.
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
LocationSize getSizeInBits() const
Return the size in bits of the memory reference.
const MDNode * getMemCacheHint() const
Return the cache hint metadata for the memory reference.
MachineOperand class - Representation of each machine instruction operand.
const ConstantInt * getCImm() const
int64_t getImm() const
MachineBasicBlock * getMBB() const
ArrayRef< int > getShuffleMask() const
Register getReg() const
getReg - Returns the register number.
Intrinsic::ID getIntrinsicID() const
unsigned getPredicate() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39