[llvm] [DAG] SDPatternMatch - add matchers for reassociatable binops (PR #119985)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 10 06:22:59 PDT 2025


================
@@ -1134,6 +1136,87 @@ inline BinaryOpc_match<ValTy, AllOnes_match, true> m_Not(const ValTy &V) {
   return m_Xor(V, m_AllOnes());
 }
 
+template <typename... PatternTs> struct ReassociatableOpc_match {
+  unsigned Opcode;
+  std::tuple<PatternTs...> Patterns;
+
+  ReassociatableOpc_match(unsigned Opcode, const PatternTs &...Patterns)
+      : Opcode(Opcode), Patterns(Patterns...) {}
+
+  template <typename MatchContext>
+  bool match(const MatchContext &Ctx, SDValue N) {
+    SmallVector<SDValue> Leaves;
+    collectLeaves(N, Leaves);
+    if (Leaves.size() != std::tuple_size_v<std::tuple<PatternTs...>>)
+      return false;
+
+    // Matches[I][J] == true iff sd_context_match(Leaves[I], Ctx,
+    // std::get<J>(Patterns)) == true
+    std::array<SmallBitVector, std::tuple_size_v<std::tuple<PatternTs...>>>
+        Matches;
+    for (size_t I = 0, N = Leaves.size(); I < N; I++) {
+      SmallVector<bool> MatchResults;
+      std::apply(
+          [&](auto &...P) {
+            (Matches[I].push_back(sd_context_match(Leaves[I], Ctx, P)), ...);
----------------
RKSimon wrote:

@Esan5 I'm hitting an issue with this with m_Value() leaves that can match in multiple positions - it looks like the last leaf is binding to every m_Value() instead of sharing the matches correctly - do we need to run the matches again after reassociatableMatchHelper to ensure that each leaf is allocated and matched to a single pattern? I think technically this could still fail with m_Deferred() matches wdyt?

```ll
define i64 @test_lsb_i64(i64 %a0, i64 %a1) nounwind {
  %s0 = lshr i64 %a0, 1
  %s1 = lshr i64 %a1, 1
  %s = add i64 %s1, %s0
  %m0 = and i64 %a0, 1
  %m1 = and i64 %m0, %a1
  %res = add i64 %s, %m1
  ret i64 %res
}
```
```cpp
    if (sd_match(N, m_ReassociatableAdd(m_Srl(m_Value(A), m_SpecificInt(1)),
                                        m_Srl(m_Value(B), m_SpecificInt(1)),
                                        m_Value(C))))
      if (sd_match(C, m_ReassociatableAnd(m_Specific(A), m_Specific(B),
                                          m_SpecificInt(1))))
        return DAG.getNode(ISD::AVGFLOORU, DL, VT, A, B);
```

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


More information about the llvm-commits mailing list