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