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 add/sub operations that also consume a carry-in.
490/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
492public:
493 Register getCarryInReg() const { return getReg(4); }
494
495 static bool classof(const MachineInstr *MI) {
496 switch (MI->getOpcode()) {
497 case TargetOpcode::G_UADDE:
498 case TargetOpcode::G_SADDE:
499 case TargetOpcode::G_USUBE:
500 case TargetOpcode::G_SSUBE:
501 return true;
502 default:
503 return false;
504 }
505 }
506};
507
508/// Represents a call to an intrinsic.
509class GIntrinsic final : public GenericMachineInstr {
510public:
513 }
514
515 bool is(Intrinsic::ID ID) const { return getIntrinsicID() == ID; }
516
517 bool hasSideEffects() const {
518 switch (getOpcode()) {
519 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
520 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
521 return true;
522 default:
523 return false;
524 }
525 }
526
527 bool isConvergent() const {
528 switch (getOpcode()) {
529 case TargetOpcode::G_INTRINSIC_CONVERGENT:
530 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
531 return true;
532 default:
533 return false;
534 }
535 }
536
537 static bool classof(const MachineInstr *MI) {
538 switch (MI->getOpcode()) {
539 case TargetOpcode::G_INTRINSIC:
540 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
541 case TargetOpcode::G_INTRINSIC_CONVERGENT:
542 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
543 return true;
544 default:
545 return false;
546 }
547 }
548};
549
550// Represents a (non-sequential) vector reduction operation.
552public:
553 static bool classof(const MachineInstr *MI) {
554 switch (MI->getOpcode()) {
555 case TargetOpcode::G_VECREDUCE_FADD:
556 case TargetOpcode::G_VECREDUCE_FMUL:
557 case TargetOpcode::G_VECREDUCE_FMAX:
558 case TargetOpcode::G_VECREDUCE_FMIN:
559 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
560 case TargetOpcode::G_VECREDUCE_FMINIMUM:
561 case TargetOpcode::G_VECREDUCE_ADD:
562 case TargetOpcode::G_VECREDUCE_MUL:
563 case TargetOpcode::G_VECREDUCE_AND:
564 case TargetOpcode::G_VECREDUCE_OR:
565 case TargetOpcode::G_VECREDUCE_XOR:
566 case TargetOpcode::G_VECREDUCE_SMAX:
567 case TargetOpcode::G_VECREDUCE_SMIN:
568 case TargetOpcode::G_VECREDUCE_UMAX:
569 case TargetOpcode::G_VECREDUCE_UMIN:
570 return true;
571 default:
572 return false;
573 }
574 }
575
576 /// Get the opcode for the equivalent scalar operation for this reduction.
577 /// E.g. for G_VECREDUCE_FADD, this returns G_FADD.
579 unsigned ScalarOpc;
580 switch (getOpcode()) {
581 case TargetOpcode::G_VECREDUCE_FADD:
582 ScalarOpc = TargetOpcode::G_FADD;
583 break;
584 case TargetOpcode::G_VECREDUCE_FMUL:
585 ScalarOpc = TargetOpcode::G_FMUL;
586 break;
587 case TargetOpcode::G_VECREDUCE_FMAX:
588 ScalarOpc = TargetOpcode::G_FMAXNUM;
589 break;
590 case TargetOpcode::G_VECREDUCE_FMIN:
591 ScalarOpc = TargetOpcode::G_FMINNUM;
592 break;
593 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
594 ScalarOpc = TargetOpcode::G_FMAXIMUM;
595 break;
596 case TargetOpcode::G_VECREDUCE_FMINIMUM:
597 ScalarOpc = TargetOpcode::G_FMINIMUM;
598 break;
599 case TargetOpcode::G_VECREDUCE_ADD:
600 ScalarOpc = TargetOpcode::G_ADD;
601 break;
602 case TargetOpcode::G_VECREDUCE_MUL:
603 ScalarOpc = TargetOpcode::G_MUL;
604 break;
605 case TargetOpcode::G_VECREDUCE_AND:
606 ScalarOpc = TargetOpcode::G_AND;
607 break;
608 case TargetOpcode::G_VECREDUCE_OR:
609 ScalarOpc = TargetOpcode::G_OR;
610 break;
611 case TargetOpcode::G_VECREDUCE_XOR:
612 ScalarOpc = TargetOpcode::G_XOR;
613 break;
614 case TargetOpcode::G_VECREDUCE_SMAX:
615 ScalarOpc = TargetOpcode::G_SMAX;
616 break;
617 case TargetOpcode::G_VECREDUCE_SMIN:
618 ScalarOpc = TargetOpcode::G_SMIN;
619 break;
620 case TargetOpcode::G_VECREDUCE_UMAX:
621 ScalarOpc = TargetOpcode::G_UMAX;
622 break;
623 case TargetOpcode::G_VECREDUCE_UMIN:
624 ScalarOpc = TargetOpcode::G_UMIN;
625 break;
626 default:
627 llvm_unreachable("Unhandled reduction");
628 }
629 return ScalarOpc;
630 }
631};
632
633/// Represents a G_PHI.
634class GPhi : public GenericMachineInstr {
635public:
636 /// Returns the number of incoming values.
637 unsigned getNumIncomingValues() const { return (getNumOperands() - 1) / 2; }
638 /// Returns the I'th incoming vreg.
639 Register getIncomingValue(unsigned I) const {
640 return getOperand(I * 2 + 1).getReg();
641 }
642 /// Returns the I'th incoming basic block.
644 return getOperand(I * 2 + 2).getMBB();
645 }
646
647 static bool classof(const MachineInstr *MI) {
648 return MI->getOpcode() == TargetOpcode::G_PHI;
649 }
650};
651
652/// Represents a binary operation, i.e, x = y op z.
654public:
655 Register getLHSReg() const { return getReg(1); }
656 Register getRHSReg() const { return getReg(2); }
657
658 static bool classof(const MachineInstr *MI) {
659 switch (MI->getOpcode()) {
660 // Integer.
661 case TargetOpcode::G_ADD:
662 case TargetOpcode::G_SUB:
663 case TargetOpcode::G_MUL:
664 case TargetOpcode::G_SDIV:
665 case TargetOpcode::G_UDIV:
666 case TargetOpcode::G_SREM:
667 case TargetOpcode::G_UREM:
668 case TargetOpcode::G_SMIN:
669 case TargetOpcode::G_SMAX:
670 case TargetOpcode::G_UMIN:
671 case TargetOpcode::G_UMAX:
672 // Floating point.
673 case TargetOpcode::G_FMINNUM:
674 case TargetOpcode::G_FMAXNUM:
675 case TargetOpcode::G_FMINNUM_IEEE:
676 case TargetOpcode::G_FMAXNUM_IEEE:
677 case TargetOpcode::G_FMINIMUM:
678 case TargetOpcode::G_FMAXIMUM:
679 case TargetOpcode::G_FADD:
680 case TargetOpcode::G_FSUB:
681 case TargetOpcode::G_FMUL:
682 case TargetOpcode::G_FDIV:
683 case TargetOpcode::G_FPOW:
684 // Logical.
685 case TargetOpcode::G_AND:
686 case TargetOpcode::G_OR:
687 case TargetOpcode::G_XOR:
688 return true;
689 default:
690 return false;
691 }
692 };
693};
694
695/// Represents an integer binary operation.
696class GIntBinOp : public GBinOp {
697public:
698 static bool classof(const MachineInstr *MI) {
699 switch (MI->getOpcode()) {
700 case TargetOpcode::G_ADD:
701 case TargetOpcode::G_SUB:
702 case TargetOpcode::G_MUL:
703 case TargetOpcode::G_SDIV:
704 case TargetOpcode::G_UDIV:
705 case TargetOpcode::G_SREM:
706 case TargetOpcode::G_UREM:
707 case TargetOpcode::G_SMIN:
708 case TargetOpcode::G_SMAX:
709 case TargetOpcode::G_UMIN:
710 case TargetOpcode::G_UMAX:
711 return true;
712 default:
713 return false;
714 }
715 };
716};
717
718/// Represents a floating point binary operation.
719class GFBinOp : public GBinOp {
720public:
721 static bool classof(const MachineInstr *MI) {
722 switch (MI->getOpcode()) {
723 case TargetOpcode::G_FMINNUM:
724 case TargetOpcode::G_FMAXNUM:
725 case TargetOpcode::G_FMINNUM_IEEE:
726 case TargetOpcode::G_FMAXNUM_IEEE:
727 case TargetOpcode::G_FMINIMUM:
728 case TargetOpcode::G_FMAXIMUM:
729 case TargetOpcode::G_FADD:
730 case TargetOpcode::G_FSUB:
731 case TargetOpcode::G_FMUL:
732 case TargetOpcode::G_FDIV:
733 case TargetOpcode::G_FPOW:
734 return true;
735 default:
736 return false;
737 }
738 };
739};
740
741/// Represents a logical binary operation.
742class GLogicalBinOp : public GBinOp {
743public:
744 static bool classof(const MachineInstr *MI) {
745 switch (MI->getOpcode()) {
746 case TargetOpcode::G_AND:
747 case TargetOpcode::G_OR:
748 case TargetOpcode::G_XOR:
749 return true;
750 default:
751 return false;
752 }
753 };
754};
755
756/// Represents an integer addition.
757class GAdd : public GIntBinOp {
758public:
759 static bool classof(const MachineInstr *MI) {
760 return MI->getOpcode() == TargetOpcode::G_ADD;
761 };
762};
763
764/// Represents a logical and.
765class GAnd : public GLogicalBinOp {
766public:
767 static bool classof(const MachineInstr *MI) {
768 return MI->getOpcode() == TargetOpcode::G_AND;
769 };
770};
771
772/// Represents a logical or.
773class GOr : public GLogicalBinOp {
774public:
775 static bool classof(const MachineInstr *MI) {
776 return MI->getOpcode() == TargetOpcode::G_OR;
777 };
778};
779
780/// Represents an extract vector element.
782public:
783 Register getVectorReg() const { return getOperand(1).getReg(); }
784 Register getIndexReg() const { return getOperand(2).getReg(); }
785
786 static bool classof(const MachineInstr *MI) {
787 return MI->getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT;
788 }
789};
790
791/// Represents an insert vector element.
793public:
794 Register getVectorReg() const { return getOperand(1).getReg(); }
795 Register getElementReg() const { return getOperand(2).getReg(); }
796 Register getIndexReg() const { return getOperand(3).getReg(); }
797
798 static bool classof(const MachineInstr *MI) {
799 return MI->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
800 }
801};
802
803/// Represents a freeze.
805public:
806 Register getSourceReg() const { return getOperand(1).getReg(); }
807
808 static bool classof(const MachineInstr *MI) {
809 return MI->getOpcode() == TargetOpcode::G_FREEZE;
810 }
811};
812
813/// Represents a cast operation.
814/// It models the llvm::CastInst concept.
815/// The exception is bitcast.
817public:
818 Register getSrcReg() const { return getOperand(1).getReg(); }
819
820 static bool classof(const MachineInstr *MI) {
821 switch (MI->getOpcode()) {
822 case TargetOpcode::G_ADDRSPACE_CAST:
823 case TargetOpcode::G_FPEXT:
824 case TargetOpcode::G_FPTOSI:
825 case TargetOpcode::G_FPTOUI:
826 case TargetOpcode::G_FPTRUNC:
827 case TargetOpcode::G_INTTOPTR:
828 case TargetOpcode::G_PTRTOINT:
829 case TargetOpcode::G_SEXT:
830 case TargetOpcode::G_SITOFP:
831 case TargetOpcode::G_TRUNC:
832 case TargetOpcode::G_UITOFP:
833 case TargetOpcode::G_ZEXT:
834 case TargetOpcode::G_ANYEXT:
835 return true;
836 default:
837 return false;
838 }
839 };
840};
841
842/// Represents a sext.
843class GSext : public GCastOp {
844public:
845 static bool classof(const MachineInstr *MI) {
846 return MI->getOpcode() == TargetOpcode::G_SEXT;
847 };
848};
849
850/// Represents a zext.
851class GZext : public GCastOp {
852public:
853 static bool classof(const MachineInstr *MI) {
854 return MI->getOpcode() == TargetOpcode::G_ZEXT;
855 };
856};
857
858/// Represents a trunc.
859class GTrunc : public GCastOp {
860public:
861 static bool classof(const MachineInstr *MI) {
862 return MI->getOpcode() == TargetOpcode::G_TRUNC;
863 };
864};
865
866/// Represents a vscale.
868public:
869 APInt getSrc() const { return getOperand(1).getCImm()->getValue(); }
870
871 static bool classof(const MachineInstr *MI) {
872 return MI->getOpcode() == TargetOpcode::G_VSCALE;
873 };
874};
875
876/// Represents an integer subtraction.
877class GSub : public GIntBinOp {
878public:
879 static bool classof(const MachineInstr *MI) {
880 return MI->getOpcode() == TargetOpcode::G_SUB;
881 };
882};
883
884/// Represents an integer multiplication.
885class GMul : public GIntBinOp {
886public:
887 static bool classof(const MachineInstr *MI) {
888 return MI->getOpcode() == TargetOpcode::G_MUL;
889 };
890};
891
892/// Represents a shift left.
893class GShl : public GenericMachineInstr {
894public:
895 Register getSrcReg() const { return getOperand(1).getReg(); }
896 Register getShiftReg() const { return getOperand(2).getReg(); }
897
898 static bool classof(const MachineInstr *MI) {
899 return MI->getOpcode() == TargetOpcode::G_SHL;
900 };
901};
902
903/// Represents a threeway compare.
905public:
906 Register getLHSReg() const { return getOperand(1).getReg(); }
907 Register getRHSReg() const { return getOperand(2).getReg(); }
908
909 bool isSigned() const { return getOpcode() == TargetOpcode::G_SCMP; }
910
911 static bool classof(const MachineInstr *MI) {
912 switch (MI->getOpcode()) {
913 case TargetOpcode::G_SCMP:
914 case TargetOpcode::G_UCMP:
915 return true;
916 default:
917 return false;
918 }
919 };
920};
921
922/// Represents an integer-like extending operation.
923class GExtOp : public GCastOp {
924public:
925 static bool classof(const MachineInstr *MI) {
926 switch (MI->getOpcode()) {
927 case TargetOpcode::G_SEXT:
928 case TargetOpcode::G_ZEXT:
929 case TargetOpcode::G_ANYEXT:
930 return true;
931 default:
932 return false;
933 }
934 };
935};
936
937/// Represents an integer-like extending or truncating operation.
938class GExtOrTruncOp : public GCastOp {
939public:
940 static bool classof(const MachineInstr *MI) {
941 switch (MI->getOpcode()) {
942 case TargetOpcode::G_SEXT:
943 case TargetOpcode::G_ZEXT:
944 case TargetOpcode::G_ANYEXT:
945 case TargetOpcode::G_TRUNC:
946 return true;
947 default:
948 return false;
949 }
950 };
951};
952
953} // namespace llvm
954
955#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
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:757
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:146
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 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 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 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 G_STORE.
static bool classof(const MachineInstr *MI)
Register getValueReg() const
Get the stored value register.
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:569
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:572
void clearFlags(unsigned flags)
Definition: MachineInstr.h:424
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:800
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:579
uint32_t getFlags() const
Return the MI flags bitvector.
Definition: MachineInstr.h:391
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