Index: llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -256,6 +256,74 @@ } }; +// Helper for (commutable) binary generic MI. Doesn't check opcode. +template +struct AnyBinaryOp_match { + LHS_P L; + RHS_P R; + + AnyBinaryOp_match(const LHS_P &LHS, const RHS_P &RHS) : L(LHS), R(RHS) {} + template + bool match(const MachineRegisterInfo &MRI, OpTy &&Op) { + MachineInstr *TmpMI; + if (mi_match(Op, MRI, m_MInstr(TmpMI))) { + if (TmpMI->getNumOperands() == 3) { + return matchOperands(MRI, TmpMI->getOperand(1).getReg(), + TmpMI->getOperand(2).getReg()); + } + } + return false; + } + bool matchOperands(const MachineRegisterInfo &MRI, Register Op0, + Register Op1) { + return (L.match(MRI, Op0) && R.match(MRI, Op1)) || + (Commutable && R.match(MRI, Op0) && L.match(MRI, Op1)); + } +}; + +template +inline AnyBinaryOp_match m_BinOp(const LHS &L, const RHS &R) { + return AnyBinaryOp_match(L, R); +} + +template +inline AnyBinaryOp_match m_CommutableBinOp(const LHS &L, + const RHS &R) { + return AnyBinaryOp_match(L, R); +} + +// Helper for (commutable) binary generic MI that checks Opcode. +template +struct BinaryOpWithOpcode_match : AnyBinaryOp_match { + unsigned Opcode; + + BinaryOpWithOpcode_match(unsigned Opcode, const LHS_P &LHS, const RHS_P &RHS) + : AnyBinaryOp_match(LHS, RHS), Opcode(Opcode) {} + template + bool match(const MachineRegisterInfo &MRI, OpTy &&Op) { + MachineInstr *TmpMI; + if (mi_match(Op, MRI, m_MInstr(TmpMI))) { + if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 3) { + return this->matchOperands(MRI, TmpMI->getOperand(1).getReg(), + TmpMI->getOperand(2).getReg()); + } + } + return false; + } +}; + +template +inline BinaryOpWithOpcode_match +m_BinOp(unsigned Opcode, const LHS &L, const RHS &R) { + return BinaryOpWithOpcode_match(Opcode, L, R); +} + +template +inline BinaryOpWithOpcode_match +m_CommutableBinOp(unsigned Opcode, const LHS &L, const RHS &R) { + return BinaryOpWithOpcode_match(Opcode, L, R); +} + template inline BinaryOp_match m_GAdd(const LHS &L, const RHS &R) {