LLVM 22.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.
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
49 }
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.
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 return true;
96 default:
97 return false;
98 }
99 }
100};
101
102/// Represents indexed loads. These are different enough from regular loads
103/// that they get their own class. Including them in GAnyLoad would probably
104/// make a footgun for someone.
106public:
107 /// Get the definition register of the loaded value.
108 Register getDstReg() const { return getOperand(0).getReg(); }
109 /// Get the def register of the writeback value.
110 Register getWritebackReg() const { return getOperand(1).getReg(); }
111 /// Get the base register of the pointer value.
112 Register getBaseReg() const { return getOperand(2).getReg(); }
113 /// Get the offset register of the pointer value.
114 Register getOffsetReg() const { return getOperand(3).getReg(); }
115
116 bool isPre() const { return getOperand(4).getImm() == 1; }
117 bool isPost() const { return !isPre(); }
118
119 static bool classof(const MachineInstr *MI) {
120 return MI->getOpcode() == TargetOpcode::G_INDEXED_LOAD;
121 }
122};
123
124/// Represents a G_INDEX_ZEXTLOAD/G_INDEXED_SEXTLOAD.
126public:
127 static bool classof(const MachineInstr *MI) {
128 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD ||
129 MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
130 }
131};
132
133/// Represents either G_INDEXED_LOAD, G_INDEXED_ZEXTLOAD or G_INDEXED_SEXTLOAD.
135public:
136 static bool classof(const MachineInstr *MI) {
137 switch (MI->getOpcode()) {
138 case TargetOpcode::G_INDEXED_LOAD:
139 case TargetOpcode::G_INDEXED_ZEXTLOAD:
140 case TargetOpcode::G_INDEXED_SEXTLOAD:
141 return true;
142 default:
143 return false;
144 }
145 }
146};
147
148/// Represents a G_ZEXTLOAD.
150public:
151 static bool classof(const MachineInstr *MI) {
152 return MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
153 }
154};
155
156/// Represents a G_SEXTLOAD.
158public:
159 static bool classof(const MachineInstr *MI) {
160 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD;
161 }
162};
163
164/// Represents indexed stores.
166public:
167 /// Get the def register of the writeback value.
168 Register getWritebackReg() const { return getOperand(0).getReg(); }
169 /// Get the stored value register.
170 Register getValueReg() const { return getOperand(1).getReg(); }
171 /// Get the base register of the pointer value.
172 Register getBaseReg() const { return getOperand(2).getReg(); }
173 /// Get the offset register of the pointer value.
174 Register getOffsetReg() const { return getOperand(3).getReg(); }
175
176 bool isPre() const { return getOperand(4).getImm() == 1; }
177 bool isPost() const { return !isPre(); }
178
179 static bool classof(const MachineInstr *MI) {
180 return MI->getOpcode() == TargetOpcode::G_INDEXED_STORE;
181 }
182};
183
184/// Represents any generic load, including sign/zero extending variants.
185class GAnyLoad : public GLoadStore {
186public:
187 /// Get the definition register of the loaded value.
188 Register getDstReg() const { return getOperand(0).getReg(); }
189
190 /// Returns the Ranges that describes the dereference.
191 const MDNode *getRanges() const {
192 return getMMO().getRanges();
193 }
194
195 static bool classof(const MachineInstr *MI) {
196 switch (MI->getOpcode()) {
197 case TargetOpcode::G_LOAD:
198 case TargetOpcode::G_ZEXTLOAD:
199 case TargetOpcode::G_SEXTLOAD:
200 return true;
201 default:
202 return false;
203 }
204 }
205};
206
207/// Represents a G_LOAD.
208class GLoad : public GAnyLoad {
209public:
210 static bool classof(const MachineInstr *MI) {
211 return MI->getOpcode() == TargetOpcode::G_LOAD;
212 }
213};
214
215/// Represents either a G_SEXTLOAD or G_ZEXTLOAD.
216class GExtLoad : public GAnyLoad {
217public:
218 static bool classof(const MachineInstr *MI) {
219 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD ||
220 MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
221 }
222};
223
224/// Represents a G_SEXTLOAD.
225class GSExtLoad : public GExtLoad {
226public:
227 static bool classof(const MachineInstr *MI) {
228 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD;
229 }
230};
231
232/// Represents a G_ZEXTLOAD.
233class GZExtLoad : public GExtLoad {
234public:
235 static bool classof(const MachineInstr *MI) {
236 return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
237 }
238};
239
240/// Represents a G_STORE.
241class GStore : public GLoadStore {
242public:
243 /// Get the stored value register.
244 Register getValueReg() const { return getOperand(0).getReg(); }
245
246 static bool classof(const MachineInstr *MI) {
247 return MI->getOpcode() == TargetOpcode::G_STORE;
248 }
249};
250
251/// Represents a G_UNMERGE_VALUES.
253public:
254 /// Returns the number of def registers.
255 unsigned getNumDefs() const { return getNumOperands() - 1; }
256 /// Get the unmerge source register.
258
259 static bool classof(const MachineInstr *MI) {
260 return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES;
261 }
262};
263
264/// Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
265/// All these have the common property of generating a single value from
266/// multiple sources.
268public:
269 /// Returns the number of source registers.
270 unsigned getNumSources() const { return getNumOperands() - 1; }
271 /// Returns the I'th source register.
272 Register getSourceReg(unsigned I) const { return getReg(I + 1); }
273
274 static bool classof(const MachineInstr *MI) {
275 switch (MI->getOpcode()) {
276 case TargetOpcode::G_MERGE_VALUES:
277 case TargetOpcode::G_CONCAT_VECTORS:
278 case TargetOpcode::G_BUILD_VECTOR:
279 return true;
280 default:
281 return false;
282 }
283 }
284};
285
286/// Represents a G_MERGE_VALUES.
287class GMerge : public GMergeLikeInstr {
288public:
289 static bool classof(const MachineInstr *MI) {
290 return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES;
291 }
292};
293
294/// Represents a G_CONCAT_VECTORS.
296public:
297 static bool classof(const MachineInstr *MI) {
298 return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
299 }
300};
301
302/// Represents a G_BUILD_VECTOR.
304public:
305 static bool classof(const MachineInstr *MI) {
306 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR;
307 }
308};
309
310/// Represents a G_BUILD_VECTOR_TRUNC.
312public:
313 static bool classof(const MachineInstr *MI) {
314 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC;
315 }
316};
317
318/// Represents a G_SHUFFLE_VECTOR.
320public:
321 Register getSrc1Reg() const { return getOperand(1).getReg(); }
322 Register getSrc2Reg() const { return getOperand(2).getReg(); }
324
325 static bool classof(const MachineInstr *MI) {
326 return MI->getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR;
327 }
328};
329
330/// Represents a G_PTR_ADD.
332public:
333 Register getBaseReg() const { return getReg(1); }
334 Register getOffsetReg() const { return getReg(2); }
335
336 static bool classof(const MachineInstr *MI) {
337 return MI->getOpcode() == TargetOpcode::G_PTR_ADD;
338 }
339};
340
341/// Represents a G_IMPLICIT_DEF.
343public:
344 static bool classof(const MachineInstr *MI) {
345 return MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
346 }
347};
348
349/// Represents a G_SELECT.
351public:
352 Register getCondReg() const { return getReg(1); }
353 Register getTrueReg() const { return getReg(2); }
354 Register getFalseReg() const { return getReg(3); }
355
356 static bool classof(const MachineInstr *MI) {
357 return MI->getOpcode() == TargetOpcode::G_SELECT;
358 }
359};
360
361/// Represent a G_ICMP or G_FCMP.
363public:
365 return static_cast<CmpInst::Predicate>(getOperand(1).getPredicate());
366 }
367 Register getLHSReg() const { return getReg(2); }
368 Register getRHSReg() const { return getReg(3); }
369
370 static bool classof(const MachineInstr *MI) {
371 return MI->getOpcode() == TargetOpcode::G_ICMP ||
372 MI->getOpcode() == TargetOpcode::G_FCMP;
373 }
374};
375
376/// Represent a G_ICMP.
377class GICmp : public GAnyCmp {
378public:
379 static bool classof(const MachineInstr *MI) {
380 return MI->getOpcode() == TargetOpcode::G_ICMP;
381 }
382};
383
384/// Represent a G_FCMP.
385class GFCmp : public GAnyCmp {
386public:
387 static bool classof(const MachineInstr *MI) {
388 return MI->getOpcode() == TargetOpcode::G_FCMP;
389 }
390};
391
392/// Represents overflowing binary operations.
393/// Only carry-out:
394/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_UMULO, G_SMULO
395/// Carry-in and carry-out:
396/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
398public:
399 Register getDstReg() const { return getReg(0); }
400 Register getCarryOutReg() const { return getReg(1); }
403 Register getLHSReg() const { return getOperand(2).getReg(); }
404 Register getRHSReg() const { return getOperand(3).getReg(); }
405
406 static bool classof(const MachineInstr *MI) {
407 switch (MI->getOpcode()) {
408 case TargetOpcode::G_UADDO:
409 case TargetOpcode::G_SADDO:
410 case TargetOpcode::G_USUBO:
411 case TargetOpcode::G_SSUBO:
412 case TargetOpcode::G_UADDE:
413 case TargetOpcode::G_SADDE:
414 case TargetOpcode::G_USUBE:
415 case TargetOpcode::G_SSUBE:
416 case TargetOpcode::G_UMULO:
417 case TargetOpcode::G_SMULO:
418 return true;
419 default:
420 return false;
421 }
422 }
423};
424
425/// Represents overflowing add/sub operations.
426/// Only carry-out:
427/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO
428/// Carry-in and carry-out:
429/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
431public:
432 bool isAdd() const {
433 switch (getOpcode()) {
434 case TargetOpcode::G_UADDO:
435 case TargetOpcode::G_SADDO:
436 case TargetOpcode::G_UADDE:
437 case TargetOpcode::G_SADDE:
438 return true;
439 default:
440 return false;
441 }
442 }
443 bool isSub() const { return !isAdd(); }
444
445 bool isSigned() const {
446 switch (getOpcode()) {
447 case TargetOpcode::G_SADDO:
448 case TargetOpcode::G_SSUBO:
449 case TargetOpcode::G_SADDE:
450 case TargetOpcode::G_SSUBE:
451 return true;
452 default:
453 return false;
454 }
455 }
456 bool isUnsigned() const { return !isSigned(); }
457
458 static bool classof(const MachineInstr *MI) {
459 switch (MI->getOpcode()) {
460 case TargetOpcode::G_UADDO:
461 case TargetOpcode::G_SADDO:
462 case TargetOpcode::G_USUBO:
463 case TargetOpcode::G_SSUBO:
464 case TargetOpcode::G_UADDE:
465 case TargetOpcode::G_SADDE:
466 case TargetOpcode::G_USUBE:
467 case TargetOpcode::G_SSUBE:
468 return true;
469 default:
470 return false;
471 }
472 }
473};
474
475/// Represents overflowing add operations.
476/// G_UADDO, G_SADDO
478public:
479 bool isSigned() const { return getOpcode() == TargetOpcode::G_SADDO; }
480
481 static bool classof(const MachineInstr *MI) {
482 switch (MI->getOpcode()) {
483 case TargetOpcode::G_UADDO:
484 case TargetOpcode::G_SADDO:
485 return true;
486 default:
487 return false;
488 }
489 }
490};
491
492/// Represents overflowing sub operations.
493/// G_USUBO, G_SSUBO
495public:
496 bool isSigned() const { return getOpcode() == TargetOpcode::G_SSUBO; }
497
498 static bool classof(const MachineInstr *MI) {
499 switch (MI->getOpcode()) {
500 case TargetOpcode::G_USUBO:
501 case TargetOpcode::G_SSUBO:
502 return true;
503 default:
504 return false;
505 }
506 }
507};
508
509/// Represents overflowing add/sub operations that also consume a carry-in.
510/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
512public:
513 Register getCarryInReg() const { return getReg(4); }
514
515 static bool classof(const MachineInstr *MI) {
516 switch (MI->getOpcode()) {
517 case TargetOpcode::G_UADDE:
518 case TargetOpcode::G_SADDE:
519 case TargetOpcode::G_USUBE:
520 case TargetOpcode::G_SSUBE:
521 return true;
522 default:
523 return false;
524 }
525 }
526};
527
528/// Represents a call to an intrinsic.
529class GIntrinsic final : public GenericMachineInstr {
530public:
533 }
534
535 bool is(Intrinsic::ID ID) const { return getIntrinsicID() == ID; }
536
537 bool hasSideEffects() const {
538 switch (getOpcode()) {
539 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
540 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
541 return true;
542 default:
543 return false;
544 }
545 }
546
547 bool isConvergent() const {
548 switch (getOpcode()) {
549 case TargetOpcode::G_INTRINSIC_CONVERGENT:
550 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
551 return true;
552 default:
553 return false;
554 }
555 }
556
557 static bool classof(const MachineInstr *MI) {
558 switch (MI->getOpcode()) {
559 case TargetOpcode::G_INTRINSIC:
560 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
561 case TargetOpcode::G_INTRINSIC_CONVERGENT:
562 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
563 return true;
564 default:
565 return false;
566 }
567 }
568};
569
570// Represents a (non-sequential) vector reduction operation.
572public:
573 static bool classof(const MachineInstr *MI) {
574 switch (MI->getOpcode()) {
575 case TargetOpcode::G_VECREDUCE_FADD:
576 case TargetOpcode::G_VECREDUCE_FMUL:
577 case TargetOpcode::G_VECREDUCE_FMAX:
578 case TargetOpcode::G_VECREDUCE_FMIN:
579 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
580 case TargetOpcode::G_VECREDUCE_FMINIMUM:
581 case TargetOpcode::G_VECREDUCE_ADD:
582 case TargetOpcode::G_VECREDUCE_MUL:
583 case TargetOpcode::G_VECREDUCE_AND:
584 case TargetOpcode::G_VECREDUCE_OR:
585 case TargetOpcode::G_VECREDUCE_XOR:
586 case TargetOpcode::G_VECREDUCE_SMAX:
587 case TargetOpcode::G_VECREDUCE_SMIN:
588 case TargetOpcode::G_VECREDUCE_UMAX:
589 case TargetOpcode::G_VECREDUCE_UMIN:
590 return true;
591 default:
592 return false;
593 }
594 }
595
596 /// Get the opcode for the equivalent scalar operation for this reduction.
597 /// E.g. for G_VECREDUCE_FADD, this returns G_FADD.
599 unsigned ScalarOpc;
600 switch (getOpcode()) {
601 case TargetOpcode::G_VECREDUCE_FADD:
602 ScalarOpc = TargetOpcode::G_FADD;
603 break;
604 case TargetOpcode::G_VECREDUCE_FMUL:
605 ScalarOpc = TargetOpcode::G_FMUL;
606 break;
607 case TargetOpcode::G_VECREDUCE_FMAX:
608 ScalarOpc = TargetOpcode::G_FMAXNUM;
609 break;
610 case TargetOpcode::G_VECREDUCE_FMIN:
611 ScalarOpc = TargetOpcode::G_FMINNUM;
612 break;
613 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
614 ScalarOpc = TargetOpcode::G_FMAXIMUM;
615 break;
616 case TargetOpcode::G_VECREDUCE_FMINIMUM:
617 ScalarOpc = TargetOpcode::G_FMINIMUM;
618 break;
619 case TargetOpcode::G_VECREDUCE_ADD:
620 ScalarOpc = TargetOpcode::G_ADD;
621 break;
622 case TargetOpcode::G_VECREDUCE_MUL:
623 ScalarOpc = TargetOpcode::G_MUL;
624 break;
625 case TargetOpcode::G_VECREDUCE_AND:
626 ScalarOpc = TargetOpcode::G_AND;
627 break;
628 case TargetOpcode::G_VECREDUCE_OR:
629 ScalarOpc = TargetOpcode::G_OR;
630 break;
631 case TargetOpcode::G_VECREDUCE_XOR:
632 ScalarOpc = TargetOpcode::G_XOR;
633 break;
634 case TargetOpcode::G_VECREDUCE_SMAX:
635 ScalarOpc = TargetOpcode::G_SMAX;
636 break;
637 case TargetOpcode::G_VECREDUCE_SMIN:
638 ScalarOpc = TargetOpcode::G_SMIN;
639 break;
640 case TargetOpcode::G_VECREDUCE_UMAX:
641 ScalarOpc = TargetOpcode::G_UMAX;
642 break;
643 case TargetOpcode::G_VECREDUCE_UMIN:
644 ScalarOpc = TargetOpcode::G_UMIN;
645 break;
646 default:
647 llvm_unreachable("Unhandled reduction");
648 }
649 return ScalarOpc;
650 }
651};
652
653/// Represents a G_PHI.
654class GPhi : public GenericMachineInstr {
655public:
656 /// Returns the number of incoming values.
657 unsigned getNumIncomingValues() const { return (getNumOperands() - 1) / 2; }
658 /// Returns the I'th incoming vreg.
659 Register getIncomingValue(unsigned I) const {
660 return getOperand(I * 2 + 1).getReg();
661 }
662 /// Returns the I'th incoming basic block.
664 return getOperand(I * 2 + 2).getMBB();
665 }
666
667 static bool classof(const MachineInstr *MI) {
668 return MI->getOpcode() == TargetOpcode::G_PHI;
669 }
670};
671
672/// Represents a binary operation, i.e, x = y op z.
674public:
675 Register getLHSReg() const { return getReg(1); }
676 Register getRHSReg() const { return getReg(2); }
677
678 static bool classof(const MachineInstr *MI) {
679 switch (MI->getOpcode()) {
680 // Integer.
681 case TargetOpcode::G_ADD:
682 case TargetOpcode::G_SUB:
683 case TargetOpcode::G_MUL:
684 case TargetOpcode::G_SDIV:
685 case TargetOpcode::G_UDIV:
686 case TargetOpcode::G_SREM:
687 case TargetOpcode::G_UREM:
688 case TargetOpcode::G_SMIN:
689 case TargetOpcode::G_SMAX:
690 case TargetOpcode::G_UMIN:
691 case TargetOpcode::G_UMAX:
692 // Floating point.
693 case TargetOpcode::G_FMINNUM:
694 case TargetOpcode::G_FMAXNUM:
695 case TargetOpcode::G_FMINNUM_IEEE:
696 case TargetOpcode::G_FMAXNUM_IEEE:
697 case TargetOpcode::G_FMINIMUM:
698 case TargetOpcode::G_FMAXIMUM:
699 case TargetOpcode::G_FADD:
700 case TargetOpcode::G_FSUB:
701 case TargetOpcode::G_FMUL:
702 case TargetOpcode::G_FDIV:
703 case TargetOpcode::G_FPOW:
704 // Logical.
705 case TargetOpcode::G_AND:
706 case TargetOpcode::G_OR:
707 case TargetOpcode::G_XOR:
708 return true;
709 default:
710 return false;
711 }
712 };
713};
714
715/// Represents an integer binary operation.
716class GIntBinOp : public GBinOp {
717public:
718 static bool classof(const MachineInstr *MI) {
719 switch (MI->getOpcode()) {
720 case TargetOpcode::G_ADD:
721 case TargetOpcode::G_SUB:
722 case TargetOpcode::G_MUL:
723 case TargetOpcode::G_SDIV:
724 case TargetOpcode::G_UDIV:
725 case TargetOpcode::G_SREM:
726 case TargetOpcode::G_UREM:
727 case TargetOpcode::G_SMIN:
728 case TargetOpcode::G_SMAX:
729 case TargetOpcode::G_UMIN:
730 case TargetOpcode::G_UMAX:
731 return true;
732 default:
733 return false;
734 }
735 };
736};
737
738/// Represents a floating point binary operation.
739class GFBinOp : public GBinOp {
740public:
741 static bool classof(const MachineInstr *MI) {
742 switch (MI->getOpcode()) {
743 case TargetOpcode::G_FMINNUM:
744 case TargetOpcode::G_FMAXNUM:
745 case TargetOpcode::G_FMINNUM_IEEE:
746 case TargetOpcode::G_FMAXNUM_IEEE:
747 case TargetOpcode::G_FMINIMUM:
748 case TargetOpcode::G_FMAXIMUM:
749 case TargetOpcode::G_FADD:
750 case TargetOpcode::G_FSUB:
751 case TargetOpcode::G_FMUL:
752 case TargetOpcode::G_FDIV:
753 case TargetOpcode::G_FPOW:
754 return true;
755 default:
756 return false;
757 }
758 };
759};
760
761/// Represents a logical binary operation.
762class GLogicalBinOp : public GBinOp {
763public:
764 static bool classof(const MachineInstr *MI) {
765 switch (MI->getOpcode()) {
766 case TargetOpcode::G_AND:
767 case TargetOpcode::G_OR:
768 case TargetOpcode::G_XOR:
769 return true;
770 default:
771 return false;
772 }
773 };
774};
775
776/// Represents an integer addition.
777class GAdd : public GIntBinOp {
778public:
779 static bool classof(const MachineInstr *MI) {
780 return MI->getOpcode() == TargetOpcode::G_ADD;
781 };
782};
783
784/// Represents a logical and.
785class GAnd : public GLogicalBinOp {
786public:
787 static bool classof(const MachineInstr *MI) {
788 return MI->getOpcode() == TargetOpcode::G_AND;
789 };
790};
791
792/// Represents a logical or.
793class GOr : public GLogicalBinOp {
794public:
795 static bool classof(const MachineInstr *MI) {
796 return MI->getOpcode() == TargetOpcode::G_OR;
797 };
798};
799
800/// Represents an extract vector element.
802public:
803 Register getVectorReg() const { return getOperand(1).getReg(); }
804 Register getIndexReg() const { return getOperand(2).getReg(); }
805
806 static bool classof(const MachineInstr *MI) {
807 return MI->getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT;
808 }
809};
810
811/// Represents an insert vector element.
813public:
814 Register getVectorReg() const { return getOperand(1).getReg(); }
815 Register getElementReg() const { return getOperand(2).getReg(); }
816 Register getIndexReg() const { return getOperand(3).getReg(); }
817
818 static bool classof(const MachineInstr *MI) {
819 return MI->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
820 }
821};
822
823/// Represents an extract subvector.
825public:
826 Register getSrcVec() const { return getOperand(1).getReg(); }
827 uint64_t getIndexImm() const { return getOperand(2).getImm(); }
828
829 static bool classof(const MachineInstr *MI) {
830 return MI->getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR;
831 }
832};
833
834/// Represents a insert subvector.
836public:
837 Register getBigVec() const { return getOperand(1).getReg(); }
838 Register getSubVec() const { return getOperand(2).getReg(); }
839 uint64_t getIndexImm() const { return getOperand(3).getImm(); }
840
841 static bool classof(const MachineInstr *MI) {
842 return MI->getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR;
843 }
844};
845
846/// Represents a freeze.
848public:
849 Register getSourceReg() const { return getOperand(1).getReg(); }
850
851 static bool classof(const MachineInstr *MI) {
852 return MI->getOpcode() == TargetOpcode::G_FREEZE;
853 }
854};
855
856/// Represents a cast operation.
857/// It models the llvm::CastInst concept.
858/// The exception is bitcast.
860public:
861 Register getSrcReg() const { return getOperand(1).getReg(); }
862
863 static bool classof(const MachineInstr *MI) {
864 switch (MI->getOpcode()) {
865 case TargetOpcode::G_ADDRSPACE_CAST:
866 case TargetOpcode::G_FPEXT:
867 case TargetOpcode::G_FPTOSI:
868 case TargetOpcode::G_FPTOUI:
869 case TargetOpcode::G_FPTOSI_SAT:
870 case TargetOpcode::G_FPTOUI_SAT:
871 case TargetOpcode::G_FPTRUNC:
872 case TargetOpcode::G_INTTOPTR:
873 case TargetOpcode::G_PTRTOINT:
874 case TargetOpcode::G_SEXT:
875 case TargetOpcode::G_SITOFP:
876 case TargetOpcode::G_TRUNC:
877 case TargetOpcode::G_TRUNC_SSAT_S:
878 case TargetOpcode::G_TRUNC_SSAT_U:
879 case TargetOpcode::G_TRUNC_USAT_U:
880 case TargetOpcode::G_UITOFP:
881 case TargetOpcode::G_ZEXT:
882 case TargetOpcode::G_ANYEXT:
883 return true;
884 default:
885 return false;
886 }
887 };
888};
889
890/// Represents a sext.
891class GSext : public GCastOp {
892public:
893 static bool classof(const MachineInstr *MI) {
894 return MI->getOpcode() == TargetOpcode::G_SEXT;
895 };
896};
897
898/// Represents a zext.
899class GZext : public GCastOp {
900public:
901 static bool classof(const MachineInstr *MI) {
902 return MI->getOpcode() == TargetOpcode::G_ZEXT;
903 };
904};
905
906/// Represents an any ext.
907class GAnyExt : public GCastOp {
908public:
909 static bool classof(const MachineInstr *MI) {
910 return MI->getOpcode() == TargetOpcode::G_ANYEXT;
911 };
912};
913
914/// Represents a trunc.
915class GTrunc : public GCastOp {
916public:
917 static bool classof(const MachineInstr *MI) {
918 return MI->getOpcode() == TargetOpcode::G_TRUNC;
919 };
920};
921
922/// Represents a vscale.
924public:
925 APInt getSrc() const { return getOperand(1).getCImm()->getValue(); }
926
927 static bool classof(const MachineInstr *MI) {
928 return MI->getOpcode() == TargetOpcode::G_VSCALE;
929 };
930};
931
932/// Represents a step vector.
934public:
936 return getOperand(1).getCImm()->getValue().getZExtValue();
937 }
938
939 static bool classof(const MachineInstr *MI) {
940 return MI->getOpcode() == TargetOpcode::G_STEP_VECTOR;
941 };
942};
943
944/// Represents an integer subtraction.
945class GSub : public GIntBinOp {
946public:
947 static bool classof(const MachineInstr *MI) {
948 return MI->getOpcode() == TargetOpcode::G_SUB;
949 };
950};
951
952/// Represents an integer multiplication.
953class GMul : public GIntBinOp {
954public:
955 static bool classof(const MachineInstr *MI) {
956 return MI->getOpcode() == TargetOpcode::G_MUL;
957 };
958};
959
960/// Represents a shift left.
961class GShl : public GenericMachineInstr {
962public:
963 Register getSrcReg() const { return getOperand(1).getReg(); }
964 Register getShiftReg() const { return getOperand(2).getReg(); }
965
966 static bool classof(const MachineInstr *MI) {
967 return MI->getOpcode() == TargetOpcode::G_SHL;
968 };
969};
970
971/// Represents a threeway compare.
973public:
974 Register getLHSReg() const { return getOperand(1).getReg(); }
975 Register getRHSReg() const { return getOperand(2).getReg(); }
976
977 bool isSigned() const { return getOpcode() == TargetOpcode::G_SCMP; }
978
979 static bool classof(const MachineInstr *MI) {
980 switch (MI->getOpcode()) {
981 case TargetOpcode::G_SCMP:
982 case TargetOpcode::G_UCMP:
983 return true;
984 default:
985 return false;
986 }
987 };
988};
989
990/// Represents an integer-like extending operation.
991class GExtOp : public GCastOp {
992public:
993 static bool classof(const MachineInstr *MI) {
994 switch (MI->getOpcode()) {
995 case TargetOpcode::G_SEXT:
996 case TargetOpcode::G_ZEXT:
997 case TargetOpcode::G_ANYEXT:
998 return true;
999 default:
1000 return false;
1001 }
1002 };
1003};
1004
1005/// Represents an integer-like extending or truncating operation.
1006class GExtOrTruncOp : public GCastOp {
1007public:
1008 static bool classof(const MachineInstr *MI) {
1009 switch (MI->getOpcode()) {
1010 case TargetOpcode::G_SEXT:
1011 case TargetOpcode::G_ZEXT:
1012 case TargetOpcode::G_ANYEXT:
1013 case TargetOpcode::G_TRUNC:
1014 return true;
1015 default:
1016 return false;
1017 }
1018 };
1019};
1020
1021/// Represents a splat vector.
1023public:
1024 Register getScalarReg() const { return getOperand(1).getReg(); }
1025
1026 static bool classof(const MachineInstr *MI) {
1027 return MI->getOpcode() == TargetOpcode::G_SPLAT_VECTOR;
1028 };
1029};
1030
1031} // namespace llvm
1032
1033#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...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
Class for arbitrary precision integers.
Definition: APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1540
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:678
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:154
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 overflowing binary operations.
MachineOperand & getRHS()
MachineOperand & getLHS()
Register getCarryOutReg() const
Register getDstReg() const
static bool classof(const MachineInstr *MI)
Register getRHSReg() const
Register getLHSReg() const
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 or G_ZEXTLOAD.
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 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)
bool hasSideEffects() const
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
bool isSigned() 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)
Register getSrc2Reg() const
Register getSrc1Reg() const
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)
Register getValueReg() const
Get the stored value register.
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)
APInt getSrc() const
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)
A base class for all GenericMachineInstrs.
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:1077
Representation of each machine instruction.
Definition: MachineInstr.h:72
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:587
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:590
void clearFlags(unsigned flags)
Definition: MachineInstr.h:437
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:798
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:595
uint32_t getFlags() const
Return the MI flags bitvector.
Definition: MachineInstr.h:404
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:19
#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.
Definition: AddressRanges.h:18
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
Definition: TargetOpcodes.h:30
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39