@@ -1716,7 +1716,8 @@ template <typename T0, typename T1, unsigned Opcode> struct TwoOps_match {
17161716};
17171717
17181718// / Matches instructions with Opcode and three operands.
1719- template <typename T0, typename T1, typename T2, unsigned Opcode>
1719+ template <typename T0, typename T1, typename T2, unsigned Opcode,
1720+ bool CommutableOp2Op3 = false >
17201721struct ThreeOps_match {
17211722 T0 Op1;
17221723 T1 Op2;
@@ -1728,8 +1729,12 @@ struct ThreeOps_match {
17281729 template <typename OpTy> bool match (OpTy *V) {
17291730 if (V->getValueID () == Value::InstructionVal + Opcode) {
17301731 auto *I = cast<Instruction>(V);
1731- return Op1.match (I->getOperand (0 )) && Op2.match (I->getOperand (1 )) &&
1732- Op3.match (I->getOperand (2 ));
1732+ if (!Op1.match (I->getOperand (0 )))
1733+ return false ;
1734+ if (Op2.match (I->getOperand (1 )) && Op3.match (I->getOperand (2 )))
1735+ return true ;
1736+ return CommutableOp2Op3 && Op2.match (I->getOperand (2 )) &&
1737+ Op3.match (I->getOperand (1 ));
17331738 }
17341739 return false ;
17351740 }
@@ -1781,6 +1786,14 @@ m_SelectCst(const Cond &C) {
17811786 return m_Select (C, m_ConstantInt<L>(), m_ConstantInt<R>());
17821787}
17831788
1789+ // / Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
1790+ template <typename LHS, typename RHS>
1791+ inline ThreeOps_match<decltype (m_Value()), LHS, RHS, Instruction::Select, true >
1792+ m_c_Select (const LHS &L, const RHS &R) {
1793+ return ThreeOps_match<decltype (m_Value ()), LHS, RHS, Instruction::Select,
1794+ true >(m_Value (), L, R);
1795+ }
1796+
17841797// / Matches FreezeInst.
17851798template <typename OpTy>
17861799inline OneOps_match<OpTy, Instruction::Freeze> m_Freeze (const OpTy &Op) {
0 commit comments