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