Skip to content

Commit 5d68411

Browse files
committed
[GlobalISel] Add and use a m_GAddLike pattern matcher. NFC
This adds a Flags parameter to the BinaryOp_match, allowing it to detect different flags like Disjoint. A m_GDisjointOr is added to detect Or's with disjoint flags, and G_AddLike is then either a m_GADD or m_GDisjointOr. The rest is trying to allow matching `const MachineInstr&`, as opposed to non-const references.
1 parent 070e129 commit 5d68411

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
3743
template <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+
340361
template <> 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

369390
inline bind_ty<Register> m_Reg(Register &R) { return R; }
370391
inline bind_ty<MachineInstr *> m_MInstr(MachineInstr *&MI) { return MI; }
392+
inline bind_ty<const MachineInstr *> m_MInstr(const MachineInstr *&MI) {
393+
return MI;
394+
}
371395
inline bind_ty<LLT> m_Type(LLT &Ty) { return Ty; }
372396
inline bind_ty<CmpInst::Predicate> m_Pred(CmpInst::Predicate &P) { return P; }
373397
inline 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
420444
template <typename LHS_P, typename RHS_P, unsigned Opcode,
421-
bool Commutable = false>
445+
bool Commutable = false, unsigned Flags = MachineInstr::NoFlags>
422446
struct 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+
562603
template <typename LHS, typename RHS>
563604
inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SHL, false>
564605
m_GShl(const LHS &L, const RHS &R) {

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,7 @@ def add_and_or_is_add : PatFrags<(ops node:$lhs, node:$rhs),
10271027
return CurDAG->isADDLike(SDValue(N,0));
10281028
}]> {
10291029
let GISelPredicateCode = [{
1030-
return MI.getOpcode() == TargetOpcode::G_ADD ||
1031-
(MI.getOpcode() == TargetOpcode::G_OR &&
1032-
MI.getFlag(MachineInstr::MIFlag::Disjoint));
1030+
return mi_match(MI, MRI, m_GAddLike(m_Reg(), m_Reg()));
10331031
}];
10341032
}
10351033

0 commit comments

Comments
 (0)