@@ -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,19 @@ 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+ return MI;
351+ }
352+ static bool bind (const MachineRegisterInfo &MRI, const MachineInstr *&MI,
353+ const MachineInstr *Inst) {
354+ MI = Inst;
355+ return MI;
356+ }
357+ };
358+
340359template <> struct bind_helper <LLT> {
341360 static bool bind (const MachineRegisterInfo &MRI, LLT &Ty, Register Reg) {
342361 Ty = MRI.getType (Reg);
@@ -368,6 +387,9 @@ template <typename Class> struct bind_ty {
368387
369388inline bind_ty<Register> m_Reg (Register &R) { return R; }
370389inline bind_ty<MachineInstr *> m_MInstr (MachineInstr *&MI) { return MI; }
390+ inline bind_ty<const MachineInstr *> m_MInstr (const MachineInstr *&MI) {
391+ return MI;
392+ }
371393inline bind_ty<LLT> m_Type (LLT &Ty) { return Ty; }
372394inline bind_ty<CmpInst::Predicate> m_Pred (CmpInst::Predicate &P) { return P; }
373395inline operand_type_match m_Pred () { return operand_type_match (); }
@@ -418,26 +440,28 @@ inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
418440
419441// General helper for all the binary generic MI such as G_ADD/G_SUB etc
420442template <typename LHS_P, typename RHS_P, unsigned Opcode,
421- bool Commutable = false >
443+ bool Commutable = false , unsigned Flags = MachineInstr::NoFlags >
422444struct BinaryOp_match {
423445 LHS_P L;
424446 RHS_P R;
425447
426448 BinaryOp_match (const LHS_P &LHS, const RHS_P &RHS) : L(LHS), R(RHS) {}
427449 template <typename OpTy>
428450 bool match (const MachineRegisterInfo &MRI, OpTy &&Op) {
429- MachineInstr *TmpMI;
451+ const MachineInstr *TmpMI;
430452 if (mi_match (Op, MRI, m_MInstr (TmpMI))) {
431453 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 ())));
454+ if ((!L.match (MRI, TmpMI->getOperand (1 ).getReg ()) ||
455+ !R.match (MRI, TmpMI->getOperand (2 ).getReg ())) &&
456+ // NOTE: When trying the alternative operand ordering
457+ // with a commutative operation, it is imperative to always run
458+ // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
459+ // (i.e. `R`). Otherwise, m_DeferredReg/Type will not work as
460+ // expected.
461+ (!Commutable || !L.match (MRI, TmpMI->getOperand (2 ).getReg ()) ||
462+ !R.match (MRI, TmpMI->getOperand (1 ).getReg ())))
463+ return false ;
464+ return (TmpMI->getFlags () & Flags) == Flags;
441465 }
442466 }
443467 return false ;
@@ -464,7 +488,7 @@ struct BinaryOpc_match {
464488 // NOTE: When trying the alternative operand ordering
465489 // with a commutative operation, it is imperative to always run
466490 // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
467- // (i.e. `R`). Otherwsie , m_DeferredReg/Type will not work as
491+ // (i.e. `R`). Otherwise , m_DeferredReg/Type will not work as
468492 // expected.
469493 (Commutable && (L.match (MRI, TmpMI->getOperand (2 ).getReg ()) &&
470494 R.match (MRI, TmpMI->getOperand (1 ).getReg ())));
@@ -559,6 +583,19 @@ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true> m_GOr(const LHS &L,
559583 return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true >(L, R);
560584}
561585
586+ template <typename LHS, typename RHS>
587+ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
588+ MachineInstr::Disjoint>
589+ m_GDisjointOr (const LHS &L, const RHS &R) {
590+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
591+ MachineInstr::Disjoint>(L, R);
592+ }
593+
594+ template <typename LHS, typename RHS>
595+ inline auto m_GAddLike (const LHS &L, const RHS &R) {
596+ return m_any_of (m_GAdd (L, R), m_GDisjointOr (L, R));
597+ }
598+
562599template <typename LHS, typename RHS>
563600inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SHL, false >
564601m_GShl (const LHS &L, const RHS &R) {
@@ -717,7 +754,7 @@ struct CompareOp_match {
717754 // NOTE: When trying the alternative operand ordering
718755 // with a commutative operation, it is imperative to always run
719756 // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
720- // (i.e. `R`). Otherwsie , m_DeferredReg/Type will not work as expected.
757+ // (i.e. `R`). Otherwise , m_DeferredReg/Type will not work as expected.
721758 if (Commutable && L.match (MRI, RHS) && R.match (MRI, LHS) &&
722759 P.match (MRI, CmpInst::getSwappedPredicate (TmpPred)))
723760 return true ;
0 commit comments