LLVM 23.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 static bool classof(const MachineInstr *MI) {
198 switch (MI->getOpcode()) {
199 case TargetOpcode::G_LOAD:
200 case TargetOpcode::G_ZEXTLOAD:
201 case TargetOpcode::G_SEXTLOAD:
202 case TargetOpcode::G_FPEXTLOAD:
203 return true;
204 default:
205 return false;
206 }
207 }
208};
209
210/// Represents a G_LOAD.
211class GLoad : public GAnyLoad {
212public:
213 static bool classof(const MachineInstr *MI) {
214 return MI->getOpcode() == TargetOpcode::G_LOAD;
215 }
216};
217
218/// Represents either a G_SEXTLOAD, G_ZEXTLOAD, or G_FPEXTLOAD.
219class GExtLoad : public GAnyLoad {
220public:
221 static bool classof(const MachineInstr *MI) {
222 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD ||
223 MI->getOpcode() == TargetOpcode::G_ZEXTLOAD ||
224 MI->getOpcode() == TargetOpcode::G_FPEXTLOAD;
225 }
226};
227
228/// Represents a G_SEXTLOAD.
229class GSExtLoad : public GExtLoad {
230public:
231 static bool classof(const MachineInstr *MI) {
232 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD;
233 }
234};
235
236/// Represents a G_ZEXTLOAD.
237class GZExtLoad : public GExtLoad {
238public:
239 static bool classof(const MachineInstr *MI) {
240 return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
241 }
242};
243
244/// Represents a G_FPEXTLOAD.
245class GFPExtLoad : public GAnyLoad {
246public:
247 static bool classof(const MachineInstr *MI) {
248 return MI->getOpcode() == TargetOpcode::G_FPEXTLOAD;
249 }
250};
251
252/// Represents any generic store, including truncating variants.
253class GAnyStore : public GLoadStore {
254public:
255 /// Get the stored value register.
256 Register getValueReg() const { return getOperand(0).getReg(); }
257
258 static bool classof(const MachineInstr *MI) {
259 switch (MI->getOpcode()) {
260 case TargetOpcode::G_STORE:
261 case TargetOpcode::G_FPTRUNCSTORE:
262 return true;
263 default:
264 return false;
265 }
266 }
267};
268
269/// Represents a G_STORE.
270class GStore : public GAnyStore {
271public:
272 static bool classof(const MachineInstr *MI) {
273 return MI->getOpcode() == TargetOpcode::G_STORE;
274 }
275};
276
277/// Represents a G_FPTRUNCSTORE.
278class GFPTruncStore : public GAnyStore {
279public:
280 static bool classof(const MachineInstr *MI) {
281 return MI->getOpcode() == TargetOpcode::G_FPTRUNCSTORE;
282 }
283};
284
285/// Represents a G_UNMERGE_VALUES.
287public:
288 /// Returns the number of def registers.
289 unsigned getNumDefs() const { return getNumOperands() - 1; }
290 /// Get the unmerge source register.
292
293 static bool classof(const MachineInstr *MI) {
294 return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES;
295 }
296};
297
298/// Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
299/// All these have the common property of generating a single value from
300/// multiple sources.
302public:
303 /// Returns the number of source registers.
304 unsigned getNumSources() const { return getNumOperands() - 1; }
305 /// Returns the I'th source register.
306 Register getSourceReg(unsigned I) const { return getReg(I + 1); }
307
308 static bool classof(const MachineInstr *MI) {
309 switch (MI->getOpcode()) {
310 case TargetOpcode::G_MERGE_VALUES:
311 case TargetOpcode::G_CONCAT_VECTORS:
312 case TargetOpcode::G_BUILD_VECTOR:
313 return true;
314 default:
315 return false;
316 }
317 }
318};
319
320/// Represents a G_MERGE_VALUES.
321class GMerge : public GMergeLikeInstr {
322public:
323 static bool classof(const MachineInstr *MI) {
324 return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES;
325 }
326};
327
328/// Represents a G_CONCAT_VECTORS.
330public:
331 static bool classof(const MachineInstr *MI) {
332 return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
333 }
334};
335
336/// Represents a G_BUILD_VECTOR.
338public:
339 static bool classof(const MachineInstr *MI) {
340 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR;
341 }
342};
343
344/// Represents a G_BUILD_VECTOR_TRUNC.
346public:
347 static bool classof(const MachineInstr *MI) {
348 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC;
349 }
350};
351
352/// Represents a G_SHUFFLE_VECTOR.
354public:
355 Register getSrc1Reg() const { return getOperand(1).getReg(); }
356 Register getSrc2Reg() const { return getOperand(2).getReg(); }
358
359 static bool classof(const MachineInstr *MI) {
360 return MI->getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR;
361 }
362};
363
364/// Represents a G_PTR_ADD.
366public:
367 Register getBaseReg() const { return getReg(1); }
368 Register getOffsetReg() const { return getReg(2); }
369
370 static bool classof(const MachineInstr *MI) {
371 return MI->getOpcode() == TargetOpcode::G_PTR_ADD;
372 }
373};
374
375/// Represents a G_IMPLICIT_DEF.
377public:
378 static bool classof(const MachineInstr *MI) {
379 return MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
380 }
381};
382
383/// Represents a G_SELECT.
385public:
386 Register getCondReg() const { return getReg(1); }
387 Register getTrueReg() const { return getReg(2); }
388 Register getFalseReg() const { return getReg(3); }
389
390 static bool classof(const MachineInstr *MI) {
391 return MI->getOpcode() == TargetOpcode::G_SELECT;
392 }
393};
394
395/// Represent a G_ICMP or G_FCMP.
397public:
399 return static_cast<CmpInst::Predicate>(getOperand(1).getPredicate());
400 }
401 Register getLHSReg() const { return getReg(2); }
402 Register getRHSReg() const { return getReg(3); }
403
404 static bool classof(const MachineInstr *MI) {
405 return MI->getOpcode() == TargetOpcode::G_ICMP ||
406 MI->getOpcode() == TargetOpcode::G_FCMP;
407 }
408};
409
410/// Represent a G_ICMP.
411class GICmp : public GAnyCmp {
412public:
413 static bool classof(const MachineInstr *MI) {
414 return MI->getOpcode() == TargetOpcode::G_ICMP;
415 }
416};
417
418/// Represent a G_FCMP.
419class GFCmp : public GAnyCmp {
420public:
421 static bool classof(const MachineInstr *MI) {
422 return MI->getOpcode() == TargetOpcode::G_FCMP;
423 }
424};
425
426/// Represents overflowing binary operations.
427/// Only carry-out:
428/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_UMULO, G_SMULO
429/// Carry-in and carry-out:
430/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
432public:
433 Register getDstReg() const { return getReg(0); }
434 Register getCarryOutReg() const { return getReg(1); }
437 Register getLHSReg() const { return getOperand(2).getReg(); }
438 Register getRHSReg() const { return getOperand(3).getReg(); }
439
440 static bool classof(const MachineInstr *MI) {
441 switch (MI->getOpcode()) {
442 case TargetOpcode::G_UADDO:
443 case TargetOpcode::G_SADDO:
444 case TargetOpcode::G_USUBO:
445 case TargetOpcode::G_SSUBO:
446 case TargetOpcode::G_UADDE:
447 case TargetOpcode::G_SADDE:
448 case TargetOpcode::G_USUBE:
449 case TargetOpcode::G_SSUBE:
450 case TargetOpcode::G_UMULO:
451 case TargetOpcode::G_SMULO:
452 return true;
453 default:
454 return false;
455 }
456 }
457};
458
459/// Represents overflowing add/sub operations.
460/// Only carry-out:
461/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO
462/// Carry-in and carry-out:
463/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
465public:
466 bool isAdd() const {
467 switch (getOpcode()) {
468 case TargetOpcode::G_UADDO:
469 case TargetOpcode::G_SADDO:
470 case TargetOpcode::G_UADDE:
471 case TargetOpcode::G_SADDE:
472 return true;
473 default:
474 return false;
475 }
476 }
477 bool isSub() const { return !isAdd(); }
478
479 bool isSigned() const {
480 switch (getOpcode()) {
481 case TargetOpcode::G_SADDO:
482 case TargetOpcode::G_SSUBO:
483 case TargetOpcode::G_SADDE:
484 case TargetOpcode::G_SSUBE:
485 return true;
486 default:
487 return false;
488 }
489 }
490 bool isUnsigned() const { return !isSigned(); }
491
492 static bool classof(const MachineInstr *MI) {
493 switch (MI->getOpcode()) {
494 case TargetOpcode::G_UADDO:
495 case TargetOpcode::G_SADDO:
496 case TargetOpcode::G_USUBO:
497 case TargetOpcode::G_SSUBO:
498 case TargetOpcode::G_UADDE:
499 case TargetOpcode::G_SADDE:
500 case TargetOpcode::G_USUBE:
501 case TargetOpcode::G_SSUBE:
502 return true;
503 default:
504 return false;
505 }
506 }
507};
508
509/// Represents overflowing add operations.
510/// G_UADDO, G_SADDO
512public:
513 bool isSigned() const { return getOpcode() == TargetOpcode::G_SADDO; }
514
515 static bool classof(const MachineInstr *MI) {
516 switch (MI->getOpcode()) {
517 case TargetOpcode::G_UADDO:
518 case TargetOpcode::G_SADDO:
519 return true;
520 default:
521 return false;
522 }
523 }
524};
525
526/// Represents overflowing sub operations.
527/// G_USUBO, G_SSUBO
529public:
530 bool isSigned() const { return getOpcode() == TargetOpcode::G_SSUBO; }
531
532 static bool classof(const MachineInstr *MI) {
533 switch (MI->getOpcode()) {
534 case TargetOpcode::G_USUBO:
535 case TargetOpcode::G_SSUBO:
536 return true;
537 default:
538 return false;
539 }
540 }
541};
542
543/// Represents overflowing add/sub operations that also consume a carry-in.
544/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
546public:
547 Register getCarryInReg() const { return getReg(4); }
548
549 static bool classof(const MachineInstr *MI) {
550 switch (MI->getOpcode()) {
551 case TargetOpcode::G_UADDE:
552 case TargetOpcode::G_SADDE:
553 case TargetOpcode::G_USUBE:
554 case TargetOpcode::G_SSUBE:
555 return true;
556 default:
557 return false;
558 }
559 }
560};
561
562/// Represents a call to an intrinsic.
563class GIntrinsic final : public GenericMachineInstr {
564public:
568
569 bool is(Intrinsic::ID ID) const { return getIntrinsicID() == ID; }
570
571 bool hasSideEffects() const {
572 switch (getOpcode()) {
573 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
574 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
575 return true;
576 default:
577 return false;
578 }
579 }
580
581 bool isConvergent() const {
582 switch (getOpcode()) {
583 case TargetOpcode::G_INTRINSIC_CONVERGENT:
584 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
585 return true;
586 default:
587 return false;
588 }
589 }
590
591 static bool classof(const MachineInstr *MI) {
592 switch (MI->getOpcode()) {
593 case TargetOpcode::G_INTRINSIC:
594 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
595 case TargetOpcode::G_INTRINSIC_CONVERGENT:
596 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
597 return true;
598 default:
599 return false;
600 }
601 }
602};
603
604// Represents a (non-sequential) vector reduction operation.
606public:
607 static bool classof(const MachineInstr *MI) {
608 switch (MI->getOpcode()) {
609 case TargetOpcode::G_VECREDUCE_FADD:
610 case TargetOpcode::G_VECREDUCE_FMUL:
611 case TargetOpcode::G_VECREDUCE_FMAX:
612 case TargetOpcode::G_VECREDUCE_FMIN:
613 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
614 case TargetOpcode::G_VECREDUCE_FMINIMUM:
615 case TargetOpcode::G_VECREDUCE_ADD:
616 case TargetOpcode::G_VECREDUCE_MUL:
617 case TargetOpcode::G_VECREDUCE_AND:
618 case TargetOpcode::G_VECREDUCE_OR:
619 case TargetOpcode::G_VECREDUCE_XOR:
620 case TargetOpcode::G_VECREDUCE_SMAX:
621 case TargetOpcode::G_VECREDUCE_SMIN:
622 case TargetOpcode::G_VECREDUCE_UMAX:
623 case TargetOpcode::G_VECREDUCE_UMIN:
624 return true;
625 default:
626 return false;
627 }
628 }
629
630 /// Get the opcode for the equivalent scalar operation for this reduction.
631 /// E.g. for G_VECREDUCE_FADD, this returns G_FADD.
633 unsigned ScalarOpc;
634 switch (getOpcode()) {
635 case TargetOpcode::G_VECREDUCE_FADD:
636 ScalarOpc = TargetOpcode::G_FADD;
637 break;
638 case TargetOpcode::G_VECREDUCE_FMUL:
639 ScalarOpc = TargetOpcode::G_FMUL;
640 break;
641 case TargetOpcode::G_VECREDUCE_FMAX:
642 ScalarOpc = TargetOpcode::G_FMAXNUM;
643 break;
644 case TargetOpcode::G_VECREDUCE_FMIN:
645 ScalarOpc = TargetOpcode::G_FMINNUM;
646 break;
647 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
648 ScalarOpc = TargetOpcode::G_FMAXIMUM;
649 break;
650 case TargetOpcode::G_VECREDUCE_FMINIMUM:
651 ScalarOpc = TargetOpcode::G_FMINIMUM;
652 break;
653 case TargetOpcode::G_VECREDUCE_ADD:
654 ScalarOpc = TargetOpcode::G_ADD;
655 break;
656 case TargetOpcode::G_VECREDUCE_MUL:
657 ScalarOpc = TargetOpcode::G_MUL;
658 break;
659 case TargetOpcode::G_VECREDUCE_AND:
660 ScalarOpc = TargetOpcode::G_AND;
661 break;
662 case TargetOpcode::G_VECREDUCE_OR:
663 ScalarOpc = TargetOpcode::G_OR;
664 break;
665 case TargetOpcode::G_VECREDUCE_XOR:
666 ScalarOpc = TargetOpcode::G_XOR;
667 break;
668 case TargetOpcode::G_VECREDUCE_SMAX:
669 ScalarOpc = TargetOpcode::G_SMAX;
670 break;
671 case TargetOpcode::G_VECREDUCE_SMIN:
672 ScalarOpc = TargetOpcode::G_SMIN;
673 break;
674 case TargetOpcode::G_VECREDUCE_UMAX:
675 ScalarOpc = TargetOpcode::G_UMAX;
676 break;
677 case TargetOpcode::G_VECREDUCE_UMIN:
678 ScalarOpc = TargetOpcode::G_UMIN;
679 break;
680 default:
681 llvm_unreachable("Unhandled reduction");
682 }
683 return ScalarOpc;
684 }
685};
686
687/// Represents a G_PHI.
688class GPhi : public GenericMachineInstr {
689public:
690 /// Returns the number of incoming values.
691 unsigned getNumIncomingValues() const { return (getNumOperands() - 1) / 2; }
692 /// Returns the I'th incoming vreg.
693 Register getIncomingValue(unsigned I) const {
694 return getOperand(I * 2 + 1).getReg();
695 }
696 /// Returns the I'th incoming basic block.
698 return getOperand(I * 2 + 2).getMBB();
699 }
700
701 static bool classof(const MachineInstr *MI) {
702 return MI->getOpcode() == TargetOpcode::G_PHI;
703 }
704};
705
706/// Represents a binary operation, i.e, x = y op z.
708public:
709 Register getLHSReg() const { return getReg(1); }
710 Register getRHSReg() const { return getReg(2); }
711
712 static bool classof(const MachineInstr *MI) {
713 switch (MI->getOpcode()) {
714 // Integer.
715 case TargetOpcode::G_ADD:
716 case TargetOpcode::G_SUB:
717 case TargetOpcode::G_MUL:
718 case TargetOpcode::G_SDIV:
719 case TargetOpcode::G_UDIV:
720 case TargetOpcode::G_SREM:
721 case TargetOpcode::G_UREM:
722 case TargetOpcode::G_SMIN:
723 case TargetOpcode::G_SMAX:
724 case TargetOpcode::G_UMIN:
725 case TargetOpcode::G_UMAX:
726 // Floating point.
727 case TargetOpcode::G_FMINNUM:
728 case TargetOpcode::G_FMAXNUM:
729 case TargetOpcode::G_FMINNUM_IEEE:
730 case TargetOpcode::G_FMAXNUM_IEEE:
731 case TargetOpcode::G_FMINIMUM:
732 case TargetOpcode::G_FMAXIMUM:
733 case TargetOpcode::G_FADD:
734 case TargetOpcode::G_FSUB:
735 case TargetOpcode::G_FMUL:
736 case TargetOpcode::G_FDIV:
737 case TargetOpcode::G_FPOW:
738 // Logical.
739 case TargetOpcode::G_AND:
740 case TargetOpcode::G_OR:
741 case TargetOpcode::G_XOR:
742 return true;
743 default:
744 return false;
745 }
746 };
747};
748
749/// Represents an integer binary operation.
750class GIntBinOp : public GBinOp {
751public:
752 static bool classof(const MachineInstr *MI) {
753 switch (MI->getOpcode()) {
754 case TargetOpcode::G_ADD:
755 case TargetOpcode::G_SUB:
756 case TargetOpcode::G_MUL:
757 case TargetOpcode::G_SDIV:
758 case TargetOpcode::G_UDIV:
759 case TargetOpcode::G_SREM:
760 case TargetOpcode::G_UREM:
761 case TargetOpcode::G_SMIN:
762 case TargetOpcode::G_SMAX:
763 case TargetOpcode::G_UMIN:
764 case TargetOpcode::G_UMAX:
765 return true;
766 default:
767 return false;
768 }
769 };
770};
771
772/// Represents a floating point binary operation.
773class GFBinOp : public GBinOp {
774public:
775 static bool classof(const MachineInstr *MI) {
776 switch (MI->getOpcode()) {
777 case TargetOpcode::G_FMINNUM:
778 case TargetOpcode::G_FMAXNUM:
779 case TargetOpcode::G_FMINNUM_IEEE:
780 case TargetOpcode::G_FMAXNUM_IEEE:
781 case TargetOpcode::G_FMINIMUM:
782 case TargetOpcode::G_FMAXIMUM:
783 case TargetOpcode::G_FADD:
784 case TargetOpcode::G_FSUB:
785 case TargetOpcode::G_FMUL:
786 case TargetOpcode::G_FDIV:
787 case TargetOpcode::G_FPOW:
788 return true;
789 default:
790 return false;
791 }
792 };
793};
794
795/// Represents a logical binary operation.
796class GLogicalBinOp : public GBinOp {
797public:
798 static bool classof(const MachineInstr *MI) {
799 switch (MI->getOpcode()) {
800 case TargetOpcode::G_AND:
801 case TargetOpcode::G_OR:
802 case TargetOpcode::G_XOR:
803 return true;
804 default:
805 return false;
806 }
807 };
808};
809
810/// Represents an integer addition.
811class GAdd : public GIntBinOp {
812public:
813 static bool classof(const MachineInstr *MI) {
814 return MI->getOpcode() == TargetOpcode::G_ADD;
815 };
816};
817
818/// Represents a logical and.
819class GAnd : public GLogicalBinOp {
820public:
821 static bool classof(const MachineInstr *MI) {
822 return MI->getOpcode() == TargetOpcode::G_AND;
823 };
824};
825
826/// Represents a logical or.
827class GOr : public GLogicalBinOp {
828public:
829 static bool classof(const MachineInstr *MI) {
830 return MI->getOpcode() == TargetOpcode::G_OR;
831 };
832};
833
834/// Represents an extract vector element.
836public:
837 Register getVectorReg() const { return getOperand(1).getReg(); }
838 Register getIndexReg() const { return getOperand(2).getReg(); }
839
840 static bool classof(const MachineInstr *MI) {
841 return MI->getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT;
842 }
843};
844
845/// Represents an insert vector element.
847public:
848 Register getVectorReg() const { return getOperand(1).getReg(); }
849 Register getElementReg() const { return getOperand(2).getReg(); }
850 Register getIndexReg() const { return getOperand(3).getReg(); }
851
852 static bool classof(const MachineInstr *MI) {
853 return MI->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
854 }
855};
856
857/// Represents an extract subvector.
859public:
860 Register getSrcVec() const { return getOperand(1).getReg(); }
861 uint64_t getIndexImm() const { return getOperand(2).getImm(); }
862
863 static bool classof(const MachineInstr *MI) {
864 return MI->getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR;
865 }
866};
867
868/// Represents a insert subvector.
870public:
871 Register getBigVec() const { return getOperand(1).getReg(); }
872 Register getSubVec() const { return getOperand(2).getReg(); }
873 uint64_t getIndexImm() const { return getOperand(3).getImm(); }
874
875 static bool classof(const MachineInstr *MI) {
876 return MI->getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR;
877 }
878};
879
880/// Represents a freeze.
882public:
883 Register getSourceReg() const { return getOperand(1).getReg(); }
884
885 static bool classof(const MachineInstr *MI) {
886 return MI->getOpcode() == TargetOpcode::G_FREEZE;
887 }
888};
889
890/// Represents a cast operation.
891/// It models the llvm::CastInst concept.
892/// The exception is bitcast.
894public:
895 Register getSrcReg() const { return getOperand(1).getReg(); }
896
897 static bool classof(const MachineInstr *MI) {
898 switch (MI->getOpcode()) {
899 case TargetOpcode::G_ADDRSPACE_CAST:
900 case TargetOpcode::G_FPEXT:
901 case TargetOpcode::G_FPTOSI:
902 case TargetOpcode::G_FPTOUI:
903 case TargetOpcode::G_FPTOSI_SAT:
904 case TargetOpcode::G_FPTOUI_SAT:
905 case TargetOpcode::G_FPTRUNC:
906 case TargetOpcode::G_INTTOPTR:
907 case TargetOpcode::G_PTRTOINT:
908 case TargetOpcode::G_SEXT:
909 case TargetOpcode::G_SITOFP:
910 case TargetOpcode::G_TRUNC:
911 case TargetOpcode::G_TRUNC_SSAT_S:
912 case TargetOpcode::G_TRUNC_SSAT_U:
913 case TargetOpcode::G_TRUNC_USAT_U:
914 case TargetOpcode::G_UITOFP:
915 case TargetOpcode::G_ZEXT:
916 case TargetOpcode::G_ANYEXT:
917 return true;
918 default:
919 return false;
920 }
921 };
922};
923
924/// Represents a sext.
925class GSext : public GCastOp {
926public:
927 static bool classof(const MachineInstr *MI) {
928 return MI->getOpcode() == TargetOpcode::G_SEXT;
929 };
930};
931
932/// Represents a zext.
933class GZext : public GCastOp {
934public:
935 static bool classof(const MachineInstr *MI) {
936 return MI->getOpcode() == TargetOpcode::G_ZEXT;
937 };
938};
939
940/// Represents an any ext.
941class GAnyExt : public GCastOp {
942public:
943 static bool classof(const MachineInstr *MI) {
944 return MI->getOpcode() == TargetOpcode::G_ANYEXT;
945 };
946};
947
948/// Represents a trunc.
949class GTrunc : public GCastOp {
950public:
951 static bool classof(const MachineInstr *MI) {
952 return MI->getOpcode() == TargetOpcode::G_TRUNC;
953 };
954};
955
956/// Represents a vscale.
958public:
959 APInt getSrc() const { return getOperand(1).getCImm()->getValue(); }
960
961 static bool classof(const MachineInstr *MI) {
962 return MI->getOpcode() == TargetOpcode::G_VSCALE;
963 };
964};
965
966/// Represents a step vector.
968public:
970 return getOperand(1).getCImm()->getValue().getZExtValue();
971 }
972
973 static bool classof(const MachineInstr *MI) {
974 return MI->getOpcode() == TargetOpcode::G_STEP_VECTOR;
975 };
976};
977
978/// Represents an integer subtraction.
979class GSub : public GIntBinOp {
980public:
981 static bool classof(const MachineInstr *MI) {
982 return MI->getOpcode() == TargetOpcode::G_SUB;
983 };
984};
985
986/// Represents an integer multiplication.
987class GMul : public GIntBinOp {
988public:
989 static bool classof(const MachineInstr *MI) {
990 return MI->getOpcode() == TargetOpcode::G_MUL;
991 };
992};
993
994/// Represents a shift left.
995class GShl : public GenericMachineInstr {
996public:
997 Register getSrcReg() const { return getOperand(1).getReg(); }
998 Register getShiftReg() const { return getOperand(2).getReg(); }
999
1000 static bool classof(const MachineInstr *MI) {
1001 return MI->getOpcode() == TargetOpcode::G_SHL;
1002 };
1003};
1004
1005/// Represents a threeway compare.
1007public:
1008 Register getLHSReg() const { return getOperand(1).getReg(); }
1009 Register getRHSReg() const { return getOperand(2).getReg(); }
1010
1011 bool isSigned() const { return getOpcode() == TargetOpcode::G_SCMP; }
1012
1013 static bool classof(const MachineInstr *MI) {
1014 switch (MI->getOpcode()) {
1015 case TargetOpcode::G_SCMP:
1016 case TargetOpcode::G_UCMP:
1017 return true;
1018 default:
1019 return false;
1020 }
1021 };
1022};
1023
1024/// Represents an integer-like extending operation.
1025class GExtOp : public GCastOp {
1026public:
1027 static bool classof(const MachineInstr *MI) {
1028 switch (MI->getOpcode()) {
1029 case TargetOpcode::G_SEXT:
1030 case TargetOpcode::G_ZEXT:
1031 case TargetOpcode::G_ANYEXT:
1032 return true;
1033 default:
1034 return false;
1035 }
1036 };
1037};
1038
1039/// Represents an integer-like extending or truncating operation.
1040class GExtOrTruncOp : public GCastOp {
1041public:
1042 static bool classof(const MachineInstr *MI) {
1043 switch (MI->getOpcode()) {
1044 case TargetOpcode::G_SEXT:
1045 case TargetOpcode::G_ZEXT:
1046 case TargetOpcode::G_ANYEXT:
1047 case TargetOpcode::G_TRUNC:
1048 return true;
1049 default:
1050 return false;
1051 }
1052 };
1053};
1054
1055/// Represents a splat vector.
1057public:
1058 Register getScalarReg() const { return getOperand(1).getReg(); }
1059
1060 static bool classof(const MachineInstr *MI) {
1061 return MI->getOpcode() == TargetOpcode::G_SPLAT_VECTOR;
1062 };
1063};
1064
1065} // namespace llvm
1066
1067#endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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:1563
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:676
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.
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 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:1080
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.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
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