[llvm] [DAG] Added m_AnyBinOp and m_c_AnyBinOp in SDPatternMatch.h (PR #86435)

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 25 09:50:10 PDT 2024


================
@@ -457,6 +457,53 @@ struct BinaryOpc_match {
   }
 };
 
+template <typename LHS_t, typename RHS_t, typename PredFuncT>
+struct AnyBinaryOp_match {
+  LHS_t L;
+  RHS_t R;
+  PredFuncT PredFunc;
+  bool Commutable;
+
+  AnyBinaryOp_match(const PredFuncT &Pred, const LHS_t &LHS, const RHS_t &RHS,
+                    const bool Commutable)
+      : PredFunc(Pred), L(LHS), R(RHS), Commutable(Commutable) {}
+
+  template <typename OpTy, typename MatchContext>
+  bool match(OpTy *V, const MatchContext &Ctx) {
+    assert(Ctx.getTLI() && "TargetLowering is required for this pattern");
+    if (auto *I = dyn_cast<BinaryOperator>(V))
+      return (PredFunc(*Ctx.getTLI()) &&
+              ((L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
+               (Commutable && L.match(I->getOperand(1)) &&
+                R.match(I->getOperand(0)))));
+    return false;
+  }
+};
+
+template <typename LHS, typename RHS>
+inline auto m_AnyBinOp(const LHS &L, const RHS &R) {
+  return AnyBinaryOp_match{[](const TargetLowering &TLI) { return true; }, L, R,
----------------
mshockwave wrote:

I think there is a misunderstanding here: the reason m_AnyBinOp is called "any" is because, as opposed to the existing m_BinOp who matches against a _fixed_ opcode given by user, m_AnyBinOp will match _any_ opcode that is TLI.isBinary/isCommutativeBinOp without any user-provided opcode to compare against with so you couldn't just return true here. 
Furthermore, `m_AnyBinOp(unsigned &Opc, LHS, RHS)` is basically extracting the opcode that fulfills `m_AnyBinOp(LHS, RHS)`. Therefore, I don't think PredFunc is necessary since both variants of `m_AnyBinOp` has to call TLI.isBinary/isCommutativeBinOp.


https://github.com/llvm/llvm-project/pull/86435


More information about the llvm-commits mailing list