LLVM 19.0.0git
MIPatternMatch.h
Go to the documentation of this file.
1//==------ llvm/CodeGen/GlobalISel/MIPatternMatch.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/// Contains matchers for matching SSA Machine Instructions.
10///
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CODEGEN_GLOBALISEL_MIPATTERNMATCH_H
14#define LLVM_CODEGEN_GLOBALISEL_MIPATTERNMATCH_H
15
16#include "llvm/ADT/APInt.h"
19#include "llvm/IR/InstrTypes.h"
20
21namespace llvm {
22namespace MIPatternMatch {
23
24template <typename Reg, typename Pattern>
25[[nodiscard]] bool mi_match(Reg R, const MachineRegisterInfo &MRI,
26 Pattern &&P) {
27 return P.match(MRI, R);
28}
29
30template <typename Pattern>
31[[nodiscard]] bool mi_match(MachineInstr &MI, const MachineRegisterInfo &MRI,
32 Pattern &&P) {
33 return P.match(MRI, &MI);
34}
35
36// TODO: Extend for N use.
37template <typename SubPatternT> struct OneUse_match {
38 SubPatternT SubPat;
39 OneUse_match(const SubPatternT &SP) : SubPat(SP) {}
40
42 return MRI.hasOneUse(Reg) && SubPat.match(MRI, Reg);
43 }
44};
45
46template <typename SubPat>
47inline OneUse_match<SubPat> m_OneUse(const SubPat &SP) {
48 return SP;
49}
50
51template <typename SubPatternT> struct OneNonDBGUse_match {
52 SubPatternT SubPat;
53 OneNonDBGUse_match(const SubPatternT &SP) : SubPat(SP) {}
54
56 return MRI.hasOneNonDBGUse(Reg) && SubPat.match(MRI, Reg);
57 }
58};
59
60template <typename SubPat>
62 return SP;
63}
64
65template <typename ConstT>
66inline std::optional<ConstT> matchConstant(Register,
67 const MachineRegisterInfo &);
68
69template <>
70inline std::optional<APInt> matchConstant(Register Reg,
71 const MachineRegisterInfo &MRI) {
73}
74
75template <>
76inline std::optional<int64_t> matchConstant(Register Reg,
77 const MachineRegisterInfo &MRI) {
79}
80
81template <typename ConstT> struct ConstantMatch {
82 ConstT &CR;
83 ConstantMatch(ConstT &C) : CR(C) {}
85 if (auto MaybeCst = matchConstant<ConstT>(Reg, MRI)) {
86 CR = *MaybeCst;
87 return true;
88 }
89 return false;
90 }
91};
92
94 return ConstantMatch<APInt>(Cst);
95}
96inline ConstantMatch<int64_t> m_ICst(int64_t &Cst) {
97 return ConstantMatch<int64_t>(Cst);
98}
99
100template <typename ConstT>
101inline std::optional<ConstT> matchConstantSplat(Register,
102 const MachineRegisterInfo &);
103
104template <>
105inline std::optional<APInt> matchConstantSplat(Register Reg,
106 const MachineRegisterInfo &MRI) {
108}
109
110template <>
111inline std::optional<int64_t>
114}
115
116template <typename ConstT> struct ICstOrSplatMatch {
117 ConstT &CR;
118 ICstOrSplatMatch(ConstT &C) : CR(C) {}
120 if (auto MaybeCst = matchConstant<ConstT>(Reg, MRI)) {
121 CR = *MaybeCst;
122 return true;
123 }
124
125 if (auto MaybeCstSplat = matchConstantSplat<ConstT>(Reg, MRI)) {
126 CR = *MaybeCstSplat;
127 return true;
128 }
129
130 return false;
131 };
132};
133
135 return ICstOrSplatMatch<APInt>(Cst);
136}
137
139 return ICstOrSplatMatch<int64_t>(Cst);
140}
141
143 std::optional<ValueAndVReg> &ValReg;
144 GCstAndRegMatch(std::optional<ValueAndVReg> &ValReg) : ValReg(ValReg) {}
147 return ValReg ? true : false;
148 }
149};
150
151inline GCstAndRegMatch m_GCst(std::optional<ValueAndVReg> &ValReg) {
152 return GCstAndRegMatch(ValReg);
153}
154
156 std::optional<FPValueAndVReg> &FPValReg;
157 GFCstAndRegMatch(std::optional<FPValueAndVReg> &FPValReg)
158 : FPValReg(FPValReg) {}
161 return FPValReg ? true : false;
162 }
163};
164
165inline GFCstAndRegMatch m_GFCst(std::optional<FPValueAndVReg> &FPValReg) {
166 return GFCstAndRegMatch(FPValReg);
167}
168
170 std::optional<FPValueAndVReg> &FPValReg;
171 GFCstOrSplatGFCstMatch(std::optional<FPValueAndVReg> &FPValReg)
172 : FPValReg(FPValReg) {}
174 return (FPValReg = getFConstantSplat(Reg, MRI)) ||
176 };
177};
178
179inline GFCstOrSplatGFCstMatch
180m_GFCstOrSplat(std::optional<FPValueAndVReg> &FPValReg) {
181 return GFCstOrSplatGFCstMatch(FPValReg);
182}
183
184/// Matcher for a specific constant value.
189 int64_t MatchedVal;
190 return mi_match(Reg, MRI, m_ICst(MatchedVal)) && MatchedVal == RequestedVal;
191 }
192};
193
194/// Matches a constant equal to \p RequestedValue.
195inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
196 return SpecificConstantMatch(RequestedValue);
197}
198
199/// Matcher for a specific constant splat.
206 /* AllowUndef */ false);
207 }
208};
209
210/// Matches a constant splat of \p RequestedValue.
211inline SpecificConstantSplatMatch m_SpecificICstSplat(int64_t RequestedValue) {
212 return SpecificConstantSplatMatch(RequestedValue);
213}
214
215/// Matcher for a specific constant or constant splat.
221 int64_t MatchedVal;
222 if (mi_match(Reg, MRI, m_ICst(MatchedVal)) && MatchedVal == RequestedVal)
223 return true;
225 /* AllowUndef */ false);
226 }
227};
228
229/// Matches a \p RequestedValue constant or a constant splat of \p
230/// RequestedValue.
231inline SpecificConstantOrSplatMatch
232m_SpecificICstOrSplat(int64_t RequestedValue) {
233 return SpecificConstantOrSplatMatch(RequestedValue);
234}
235
236///{
237/// Convenience matchers for specific integer values.
240 return SpecificConstantMatch(-1);
241}
242///}
243
244/// Matcher for a specific register.
249 return Reg == RequestedReg;
250 }
251};
252
253/// Matches a register only if it is equal to \p RequestedReg.
255 return SpecificRegisterMatch(RequestedReg);
256}
257
258// TODO: Rework this for different kinds of MachineOperand.
259// Currently assumes the Src for a match is a register.
260// We might want to support taking in some MachineOperands and call getReg on
261// that.
262
264 bool match(const MachineRegisterInfo &MRI, Register Reg) { return true; }
266 return MO->isReg();
267 }
268};
269
271
272/// Matching combinators.
273template <typename... Preds> struct And {
274 template <typename MatchSrc>
275 bool match(const MachineRegisterInfo &MRI, MatchSrc &&src) {
276 return true;
277 }
278};
279
280template <typename Pred, typename... Preds>
281struct And<Pred, Preds...> : And<Preds...> {
282 Pred P;
283 And(Pred &&p, Preds &&... preds)
284 : And<Preds...>(std::forward<Preds>(preds)...), P(std::forward<Pred>(p)) {
285 }
286 template <typename MatchSrc>
287 bool match(const MachineRegisterInfo &MRI, MatchSrc &&src) {
288 return P.match(MRI, src) && And<Preds...>::match(MRI, src);
289 }
290};
291
292template <typename... Preds> struct Or {
293 template <typename MatchSrc>
294 bool match(const MachineRegisterInfo &MRI, MatchSrc &&src) {
295 return false;
296 }
297};
298
299template <typename Pred, typename... Preds>
300struct Or<Pred, Preds...> : Or<Preds...> {
301 Pred P;
302 Or(Pred &&p, Preds &&... preds)
303 : Or<Preds...>(std::forward<Preds>(preds)...), P(std::forward<Pred>(p)) {}
304 template <typename MatchSrc>
305 bool match(const MachineRegisterInfo &MRI, MatchSrc &&src) {
306 return P.match(MRI, src) || Or<Preds...>::match(MRI, src);
307 }
308};
309
310template <typename... Preds> And<Preds...> m_all_of(Preds &&... preds) {
311 return And<Preds...>(std::forward<Preds>(preds)...);
312}
313
314template <typename... Preds> Or<Preds...> m_any_of(Preds &&... preds) {
315 return Or<Preds...>(std::forward<Preds>(preds)...);
316}
317
318template <typename BindTy> struct bind_helper {
319 static bool bind(const MachineRegisterInfo &MRI, BindTy &VR, BindTy &V) {
320 VR = V;
321 return true;
322 }
323};
324
325template <> struct bind_helper<MachineInstr *> {
327 Register Reg) {
328 MI = MRI.getVRegDef(Reg);
329 if (MI)
330 return true;
331 return false;
332 }
334 MachineInstr *Inst) {
335 MI = Inst;
336 return MI;
337 }
338};
339
340template <> struct bind_helper<LLT> {
341 static bool bind(const MachineRegisterInfo &MRI, LLT Ty, Register Reg) {
342 Ty = MRI.getType(Reg);
343 if (Ty.isValid())
344 return true;
345 return false;
346 }
347};
348
349template <> struct bind_helper<const ConstantFP *> {
350 static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F,
351 Register Reg) {
353 if (F)
354 return true;
355 return false;
356 }
357};
358
359template <typename Class> struct bind_ty {
360 Class &VR;
361
362 bind_ty(Class &V) : VR(V) {}
363
364 template <typename ITy> bool match(const MachineRegisterInfo &MRI, ITy &&V) {
365 return bind_helper<Class>::bind(MRI, VR, V);
366 }
367};
368
369inline bind_ty<Register> m_Reg(Register &R) { return R; }
371inline bind_ty<LLT> m_Type(LLT Ty) { return Ty; }
374
377 MachineInstr *TmpMI;
378 if (mi_match(Reg, MRI, m_MInstr(TmpMI)))
379 return TmpMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
380 return false;
381 }
382};
383
385
386// Helper for matching G_FCONSTANT
388
389// General helper for all the binary generic MI such as G_ADD/G_SUB etc
390template <typename LHS_P, typename RHS_P, unsigned Opcode,
391 bool Commutable = false>
393 LHS_P L;
394 RHS_P R;
395
396 BinaryOp_match(const LHS_P &LHS, const RHS_P &RHS) : L(LHS), R(RHS) {}
397 template <typename OpTy>
398 bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
399 MachineInstr *TmpMI;
400 if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
401 if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 3) {
402 return (L.match(MRI, TmpMI->getOperand(1).getReg()) &&
403 R.match(MRI, TmpMI->getOperand(2).getReg())) ||
404 (Commutable && (R.match(MRI, TmpMI->getOperand(1).getReg()) &&
405 L.match(MRI, TmpMI->getOperand(2).getReg())));
406 }
407 }
408 return false;
409 }
410};
411
412// Helper for (commutative) binary generic MI that checks Opcode.
413template <typename LHS_P, typename RHS_P, bool Commutable = false>
415 unsigned Opc;
416 LHS_P L;
417 RHS_P R;
418
419 BinaryOpc_match(unsigned Opcode, const LHS_P &LHS, const RHS_P &RHS)
420 : Opc(Opcode), L(LHS), R(RHS) {}
421 template <typename OpTy>
422 bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
423 MachineInstr *TmpMI;
424 if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
425 if (TmpMI->getOpcode() == Opc && TmpMI->getNumDefs() == 1 &&
426 TmpMI->getNumOperands() == 3) {
427 return (L.match(MRI, TmpMI->getOperand(1).getReg()) &&
428 R.match(MRI, TmpMI->getOperand(2).getReg())) ||
429 (Commutable && (R.match(MRI, TmpMI->getOperand(1).getReg()) &&
430 L.match(MRI, TmpMI->getOperand(2).getReg())));
431 }
432 }
433 return false;
434 }
435};
436
437template <typename LHS, typename RHS>
438inline BinaryOpc_match<LHS, RHS, false> m_BinOp(unsigned Opcode, const LHS &L,
439 const RHS &R) {
440 return BinaryOpc_match<LHS, RHS, false>(Opcode, L, R);
441}
442
443template <typename LHS, typename RHS>
444inline BinaryOpc_match<LHS, RHS, true>
445m_CommutativeBinOp(unsigned Opcode, const LHS &L, const RHS &R) {
446 return BinaryOpc_match<LHS, RHS, true>(Opcode, L, R);
447}
448
449template <typename LHS, typename RHS>
451m_GAdd(const LHS &L, const RHS &R) {
453}
454
455template <typename LHS, typename RHS>
457m_GBuildVector(const LHS &L, const RHS &R) {
459}
460
461template <typename LHS, typename RHS>
463m_GBuildVectorTrunc(const LHS &L, const RHS &R) {
465 R);
466}
467
468template <typename LHS, typename RHS>
470m_GPtrAdd(const LHS &L, const RHS &R) {
472}
473
474template <typename LHS, typename RHS>
476 const RHS &R) {
478}
479
480template <typename LHS, typename RHS>
482m_GMul(const LHS &L, const RHS &R) {
484}
485
486template <typename LHS, typename RHS>
488m_GFAdd(const LHS &L, const RHS &R) {
490}
491
492template <typename LHS, typename RHS>
494m_GFMul(const LHS &L, const RHS &R) {
496}
497
498template <typename LHS, typename RHS>
500m_GFSub(const LHS &L, const RHS &R) {
502}
503
504template <typename LHS, typename RHS>
506m_GAnd(const LHS &L, const RHS &R) {
508}
509
510template <typename LHS, typename RHS>
512m_GXor(const LHS &L, const RHS &R) {
514}
515
516template <typename LHS, typename RHS>
518 const RHS &R) {
520}
521
522template <typename LHS, typename RHS>
524m_GShl(const LHS &L, const RHS &R) {
526}
527
528template <typename LHS, typename RHS>
530m_GLShr(const LHS &L, const RHS &R) {
532}
533
534template <typename LHS, typename RHS>
536m_GAShr(const LHS &L, const RHS &R) {
538}
539
540template <typename LHS, typename RHS>
542m_GSMax(const LHS &L, const RHS &R) {
544}
545
546template <typename LHS, typename RHS>
548m_GSMin(const LHS &L, const RHS &R) {
550}
551
552// Helper for unary instructions (G_[ZSA]EXT/G_TRUNC) etc
553template <typename SrcTy, unsigned Opcode> struct UnaryOp_match {
554 SrcTy L;
555
556 UnaryOp_match(const SrcTy &LHS) : L(LHS) {}
557 template <typename OpTy>
558 bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
559 MachineInstr *TmpMI;
560 if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
561 if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 2) {
562 return L.match(MRI, TmpMI->getOperand(1).getReg());
563 }
564 }
565 return false;
566 }
567};
568
569template <typename SrcTy>
570inline UnaryOp_match<SrcTy, TargetOpcode::G_ANYEXT>
571m_GAnyExt(const SrcTy &Src) {
573}
574
575template <typename SrcTy>
578}
579
580template <typename SrcTy>
583}
584
585template <typename SrcTy>
588}
589
590template <typename SrcTy>
593}
594
595template <typename SrcTy>
596inline UnaryOp_match<SrcTy, TargetOpcode::G_BITCAST>
597m_GBitcast(const SrcTy &Src) {
599}
600
601template <typename SrcTy>
602inline UnaryOp_match<SrcTy, TargetOpcode::G_PTRTOINT>
603m_GPtrToInt(const SrcTy &Src) {
605}
606
607template <typename SrcTy>
608inline UnaryOp_match<SrcTy, TargetOpcode::G_INTTOPTR>
609m_GIntToPtr(const SrcTy &Src) {
611}
612
613template <typename SrcTy>
614inline UnaryOp_match<SrcTy, TargetOpcode::G_FPTRUNC>
615m_GFPTrunc(const SrcTy &Src) {
617}
618
619template <typename SrcTy>
622}
623
624template <typename SrcTy>
627}
628
629template <typename SrcTy>
631 return UnaryOp_match<SrcTy, TargetOpcode::COPY>(std::forward<SrcTy>(Src));
632}
633
634template <typename SrcTy>
637}
638
639// General helper for generic MI compares, i.e. G_ICMP and G_FCMP
640// TODO: Allow checking a specific predicate.
641template <typename Pred_P, typename LHS_P, typename RHS_P, unsigned Opcode,
642 bool Commutable = false>
644 Pred_P P;
645 LHS_P L;
646 RHS_P R;
647
648 CompareOp_match(const Pred_P &Pred, const LHS_P &LHS, const RHS_P &RHS)
649 : P(Pred), L(LHS), R(RHS) {}
650
651 template <typename OpTy>
652 bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
653 MachineInstr *TmpMI;
654 if (!mi_match(Op, MRI, m_MInstr(TmpMI)) || TmpMI->getOpcode() != Opcode)
655 return false;
656
657 auto TmpPred =
658 static_cast<CmpInst::Predicate>(TmpMI->getOperand(1).getPredicate());
659 if (!P.match(MRI, TmpPred))
660 return false;
661 Register LHS = TmpMI->getOperand(2).getReg();
662 Register RHS = TmpMI->getOperand(3).getReg();
663 if (L.match(MRI, LHS) && R.match(MRI, RHS))
664 return true;
665 if (Commutable && L.match(MRI, RHS) && R.match(MRI, LHS) &&
666 P.match(MRI, CmpInst::getSwappedPredicate(TmpPred)))
667 return true;
668 return false;
669 }
670};
671
672template <typename Pred, typename LHS, typename RHS>
673inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP>
674m_GICmp(const Pred &P, const LHS &L, const RHS &R) {
676}
677
678template <typename Pred, typename LHS, typename RHS>
679inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP>
680m_GFCmp(const Pred &P, const LHS &L, const RHS &R) {
682}
683
684/// G_ICMP matcher that also matches commuted compares.
685/// E.g.
686///
687/// m_c_GICmp(m_Pred(...), m_GAdd(...), m_GSub(...))
688///
689/// Could match both of:
690///
691/// icmp ugt (add x, y) (sub a, b)
692/// icmp ult (sub a, b) (add x, y)
693template <typename Pred, typename LHS, typename RHS>
694inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP, true>
695m_c_GICmp(const Pred &P, const LHS &L, const RHS &R) {
697}
698
699/// G_FCMP matcher that also matches commuted compares.
700/// E.g.
701///
702/// m_c_GFCmp(m_Pred(...), m_FAdd(...), m_GFMul(...))
703///
704/// Could match both of:
705///
706/// fcmp ogt (fadd x, y) (fmul a, b)
707/// fcmp olt (fmul a, b) (fadd x, y)
708template <typename Pred, typename LHS, typename RHS>
709inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP, true>
710m_c_GFCmp(const Pred &P, const LHS &L, const RHS &R) {
712}
713
714// Helper for checking if a Reg is of specific type.
715struct CheckType {
717 CheckType(const LLT Ty) : Ty(Ty) {}
718
720 return MRI.getType(Reg) == Ty;
721 }
722};
723
724inline CheckType m_SpecificType(LLT Ty) { return Ty; }
725
726template <typename Src0Ty, typename Src1Ty, typename Src2Ty, unsigned Opcode>
728 Src0Ty Src0;
729 Src1Ty Src1;
730 Src2Ty Src2;
731
732 TernaryOp_match(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
733 : Src0(Src0), Src1(Src1), Src2(Src2) {}
734 template <typename OpTy>
735 bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
736 MachineInstr *TmpMI;
737 if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
738 if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 4) {
739 return (Src0.match(MRI, TmpMI->getOperand(1).getReg()) &&
740 Src1.match(MRI, TmpMI->getOperand(2).getReg()) &&
741 Src2.match(MRI, TmpMI->getOperand(3).getReg()));
742 }
743 }
744 return false;
745 }
746};
747template <typename Src0Ty, typename Src1Ty, typename Src2Ty>
748inline TernaryOp_match<Src0Ty, Src1Ty, Src2Ty,
749 TargetOpcode::G_INSERT_VECTOR_ELT>
750m_GInsertVecElt(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2) {
751 return TernaryOp_match<Src0Ty, Src1Ty, Src2Ty,
752 TargetOpcode::G_INSERT_VECTOR_ELT>(Src0, Src1, Src2);
753}
754
755template <typename Src0Ty, typename Src1Ty, typename Src2Ty>
756inline TernaryOp_match<Src0Ty, Src1Ty, Src2Ty, TargetOpcode::G_SELECT>
757m_GISelect(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2) {
759 Src0, Src1, Src2);
760}
761
762/// Matches a register negated by a G_SUB.
763/// G_SUB 0, %negated_reg
764template <typename SrcTy>
766m_Neg(const SrcTy &&Src) {
767 return m_GSub(m_ZeroInt(), Src);
768}
769
770/// Matches a register not-ed by a G_XOR.
771/// G_XOR %not_reg, -1
772template <typename SrcTy>
774m_Not(const SrcTy &&Src) {
775 return m_GXor(Src, m_AllOnesInt());
776}
777
778} // namespace MIPatternMatch
779} // namespace llvm
780
781#endif
unsigned const MachineRegisterInfo * MRI
aarch64 promote const
This file implements a class to represent arbitrary precision integral constant values and operations...
basic Basic Alias true
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
unsigned Reg
#define P(N)
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:76
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:960
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition: InstrTypes.h:1134
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:268
This class represents an Operation in the Expression.
constexpr bool isValid() const
Definition: LowLevelType.h:145
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:546
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:549
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:556
unsigned getNumDefs() const
Returns the total number of definitions.
Definition: MachineInstr.h:615
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
unsigned getPredicate() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
operand_type_match m_Reg()
SpecificConstantOrSplatMatch m_SpecificICstOrSplat(int64_t RequestedValue)
Matches a RequestedValue constant or a constant splat of RequestedValue.
std::optional< ConstT > matchConstantSplat(Register, const MachineRegisterInfo &)
BinaryOp_match< LHS, RHS, TargetOpcode::G_BUILD_VECTOR, false > m_GBuildVector(const LHS &L, const RHS &R)
bind_ty< LLT > m_Type(LLT Ty)
GCstAndRegMatch m_GCst(std::optional< ValueAndVReg > &ValReg)
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
SpecificConstantMatch m_SpecificICst(int64_t RequestedValue)
Matches a constant equal to RequestedValue.
operand_type_match m_Pred()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_XOR, true > m_GXor(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_SEXT > m_GSExt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_FPEXT > m_GFPExt(const SrcTy &Src)
SpecificConstantMatch m_ZeroInt()
{ Convenience matchers for specific integer values.
BinaryOp_match< LHS, RHS, TargetOpcode::G_SMAX, false > m_GSMax(const LHS &L, const RHS &R)
ConstantMatch< APInt > m_ICst(APInt &Cst)
UnaryOp_match< SrcTy, TargetOpcode::G_FSQRT > m_GFSqrt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_INTTOPTR > m_GIntToPtr(const SrcTy &Src)
SpecificConstantMatch m_AllOnesInt()
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
ICstOrSplatMatch< APInt > m_ICstOrSplat(APInt &Cst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SMIN, false > m_GSMin(const LHS &L, const RHS &R)
SpecificConstantSplatMatch m_SpecificICstSplat(int64_t RequestedValue)
Matches a constant splat of RequestedValue.
ImplicitDefMatch m_GImplicitDef()
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
CheckType m_SpecificType(LLT Ty)
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
BinaryOpc_match< LHS, RHS, true > m_CommutativeBinOp(unsigned Opcode, const LHS &L, const RHS &R)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP > m_GICmp(const Pred &P, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_FADD, true > m_GFAdd(const LHS &L, const RHS &R)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_FCMP, true > m_c_GFCmp(const Pred &P, const LHS &L, const RHS &R)
G_FCMP matcher that also matches commuted compares.
UnaryOp_match< SrcTy, TargetOpcode::G_PTRTOINT > m_GPtrToInt(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_FSUB, false > m_GFSub(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ASHR, false > m_GAShr(const LHS &L, const RHS &R)
TernaryOp_match< Src0Ty, Src1Ty, Src2Ty, TargetOpcode::G_SELECT > m_GISelect(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
SpecificRegisterMatch m_SpecificReg(Register RequestedReg)
Matches a register only if it is equal to RequestedReg.
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
Or< Preds... > m_any_of(Preds &&... preds)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_BITCAST > m_GBitcast(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_BUILD_VECTOR_TRUNC, false > m_GBuildVectorTrunc(const LHS &L, const RHS &R)
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
UnaryOp_match< SrcTy, TargetOpcode::G_FNEG > m_GFNeg(const SrcTy &Src)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP, true > m_c_GICmp(const Pred &P, const LHS &L, const RHS &R)
G_ICMP matcher that also matches commuted compares.
GFCstAndRegMatch m_GFCst(std::optional< FPValueAndVReg > &FPValReg)
TernaryOp_match< Src0Ty, Src1Ty, Src2Ty, TargetOpcode::G_INSERT_VECTOR_ELT > m_GInsertVecElt(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
GFCstOrSplatGFCstMatch m_GFCstOrSplat(std::optional< FPValueAndVReg > &FPValReg)
And< Preds... > m_all_of(Preds &&... preds)
UnaryOp_match< SrcTy, TargetOpcode::G_FABS > m_GFabs(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_ANYEXT > m_GAnyExt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_FPTRUNC > m_GFPTrunc(const SrcTy &Src)
std::optional< ConstT > matchConstant(Register, const MachineRegisterInfo &)
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, TargetOpcode::G_FMUL, true > m_GFMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_MUL, true > m_GMul(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_FCMP > m_GFCmp(const Pred &P, const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
Definition: PatternMatch.h:100
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
const ConstantFP * getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:438
std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
Definition: Utils.cpp:293
std::optional< APInt > getIConstantSplatVal(const Register Reg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1304
std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
Definition: Utils.cpp:305
std::optional< FPValueAndVReg > getFConstantSplat(Register VReg, const MachineRegisterInfo &MRI, bool AllowUndef=true)
Returns a floating point scalar constant of a build vector splat if it exists.
Definition: Utils.cpp:1337
std::optional< FPValueAndVReg > getFConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_FCONSTANT returns it...
Definition: Utils.cpp:427
bool isBuildVectorConstantSplat(const Register Reg, const MachineRegisterInfo &MRI, int64_t SplatValue, bool AllowUndef)
Return true if the specified register is defined by G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all ...
Definition: Utils.cpp:1288
std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
Definition: Utils.cpp:413
std::optional< int64_t > getIConstantSplatSExtVal(const Register Reg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1322
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
Matching combinators.
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
BinaryOp_match(const LHS_P &LHS, const RHS_P &RHS)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
BinaryOpc_match(unsigned Opcode, const LHS_P &LHS, const RHS_P &RHS)
bool match(const MachineRegisterInfo &MRI, Register Reg)
CompareOp_match(const Pred_P &Pred, const LHS_P &LHS, const RHS_P &RHS)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
GCstAndRegMatch(std::optional< ValueAndVReg > &ValReg)
std::optional< ValueAndVReg > & ValReg
GFCstAndRegMatch(std::optional< FPValueAndVReg > &FPValReg)
std::optional< FPValueAndVReg > & FPValReg
bool match(const MachineRegisterInfo &MRI, Register Reg)
GFCstOrSplatGFCstMatch(std::optional< FPValueAndVReg > &FPValReg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
std::optional< FPValueAndVReg > & FPValReg
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
OneNonDBGUse_match(const SubPatternT &SP)
bool match(const MachineRegisterInfo &MRI, Register Reg)
OneUse_match(const SubPatternT &SP)
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
Matcher for a specific constant value.
bool match(const MachineRegisterInfo &MRI, Register Reg)
Matcher for a specific constant or constant splat.
bool match(const MachineRegisterInfo &MRI, Register Reg)
Matcher for a specific constant splat.
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
TernaryOp_match(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
static bool bind(const MachineRegisterInfo &MRI, LLT Ty, Register Reg)
static bool bind(const MachineRegisterInfo &MRI, MachineInstr *&MI, Register Reg)
static bool bind(const MachineRegisterInfo &MRI, MachineInstr *&MI, MachineInstr *Inst)
static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F, Register Reg)
static bool bind(const MachineRegisterInfo &MRI, BindTy &VR, BindTy &V)
bool match(const MachineRegisterInfo &MRI, ITy &&V)
bool match(const MachineRegisterInfo &MRI, MachineOperand *MO)
bool match(const MachineRegisterInfo &MRI, Register Reg)