@@ -33,6 +33,12 @@ template <typename Pattern>
3333 return P.match (MRI, &MI);
3434}
3535
36+ template <typename Pattern>
37+ [[nodiscard]] bool mi_match (const MachineInstr &MI,
38+ const MachineRegisterInfo &MRI, Pattern &&P) {
39+ return P.match (MRI, &MI);
40+ }
41+
3642// TODO: Extend for N use.
3743template <typename SubPatternT> struct OneUse_match {
3844 SubPatternT SubPat;
@@ -337,6 +343,21 @@ template <> struct bind_helper<MachineInstr *> {
337343 }
338344};
339345
346+ template <> struct bind_helper <const MachineInstr *> {
347+ static bool bind (const MachineRegisterInfo &MRI, const MachineInstr *&MI,
348+ Register Reg) {
349+ MI = MRI.getVRegDef (Reg);
350+ if (MI)
351+ return true ;
352+ return false ;
353+ }
354+ static bool bind (const MachineRegisterInfo &MRI, const MachineInstr *&MI,
355+ const MachineInstr *Inst) {
356+ MI = Inst;
357+ return MI;
358+ }
359+ };
360+
340361template <> struct bind_helper <LLT> {
341362 static bool bind (const MachineRegisterInfo &MRI, LLT &Ty, Register Reg) {
342363 Ty = MRI.getType (Reg);
@@ -368,6 +389,9 @@ template <typename Class> struct bind_ty {
368389
369390inline bind_ty<Register> m_Reg (Register &R) { return R; }
370391inline bind_ty<MachineInstr *> m_MInstr (MachineInstr *&MI) { return MI; }
392+ inline bind_ty<const MachineInstr *> m_MInstr (const MachineInstr *&MI) {
393+ return MI;
394+ }
371395inline bind_ty<LLT> m_Type (LLT &Ty) { return Ty; }
372396inline bind_ty<CmpInst::Predicate> m_Pred (CmpInst::Predicate &P) { return P; }
373397inline operand_type_match m_Pred () { return operand_type_match (); }
@@ -418,26 +442,30 @@ inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
418442
419443// General helper for all the binary generic MI such as G_ADD/G_SUB etc
420444template <typename LHS_P, typename RHS_P, unsigned Opcode,
421- bool Commutable = false >
445+ bool Commutable = false , unsigned Flags = MachineInstr::NoFlags >
422446struct BinaryOp_match {
423447 LHS_P L;
424448 RHS_P R;
425449
426450 BinaryOp_match (const LHS_P &LHS, const RHS_P &RHS) : L(LHS), R(RHS) {}
427451 template <typename OpTy>
428452 bool match (const MachineRegisterInfo &MRI, OpTy &&Op) {
429- MachineInstr *TmpMI;
453+ const MachineInstr *TmpMI;
430454 if (mi_match (Op, MRI, m_MInstr (TmpMI))) {
431455 if (TmpMI->getOpcode () == Opcode && TmpMI->getNumOperands () == 3 ) {
432- return (L.match (MRI, TmpMI->getOperand (1 ).getReg ()) &&
433- R.match (MRI, TmpMI->getOperand (2 ).getReg ())) ||
434- // NOTE: When trying the alternative operand ordering
435- // with a commutative operation, it is imperative to always run
436- // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
437- // (i.e. `R`). Otherwsie, m_DeferredReg/Type will not work as
438- // expected.
439- (Commutable && (L.match (MRI, TmpMI->getOperand (2 ).getReg ()) &&
440- R.match (MRI, TmpMI->getOperand (1 ).getReg ())));
456+ if (!(L.match (MRI, TmpMI->getOperand (1 ).getReg ()) &&
457+ R.match (MRI, TmpMI->getOperand (2 ).getReg ())) &&
458+ // NOTE: When trying the alternative operand ordering
459+ // with a commutative operation, it is imperative to always run
460+ // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
461+ // (i.e. `R`). Otherwsie, m_DeferredReg/Type will not work as
462+ // expected.
463+ !(Commutable && (L.match (MRI, TmpMI->getOperand (2 ).getReg ()) &&
464+ R.match (MRI, TmpMI->getOperand (1 ).getReg ()))))
465+ return false ;
466+ if (Flags == MachineInstr::NoFlags)
467+ return true ;
468+ return (TmpMI->getFlags () & Flags) == Flags;
441469 }
442470 }
443471 return false ;
@@ -559,6 +587,19 @@ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true> m_GOr(const LHS &L,
559587 return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true >(L, R);
560588}
561589
590+ template <typename LHS, typename RHS>
591+ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
592+ MachineInstr::Disjoint>
593+ m_GDisjointOr (const LHS &L, const RHS &R) {
594+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
595+ MachineInstr::Disjoint>(L, R);
596+ }
597+
598+ template <typename LHS, typename RHS>
599+ inline auto m_GAddLike (const LHS &L, const RHS &R) {
600+ return m_any_of (m_GAdd (L, R), m_GDisjointOr (L, R));
601+ }
602+
562603template <typename LHS, typename RHS>
563604inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SHL, false >
564605m_GShl (const LHS &L, const RHS &R) {
0 commit comments