<div><font>Hi:</font></div><div><font><br></font></div><div><font>I was trying to match the following pattern:</font></div><div><font><br></font></div><div><font>```</font></div><div><font><div>...</div><div>%8 = load i64, i64* %3, align 8</div><div>%9 = xor i64 %8, -1</div><div>...</div><div>%11 = or i64 %9, %10</div><div>...</div></font></div><div><font>```</font></div><div><font><br></font></div><div><font>which is roughly (~X | Y).</font></div><div><font><br></font></div><div><font>Given Or is commutative, I was under the assumption that trying to match (X | ~Y) would match (X | ~Y) and (~X | Y), but from testing with LLVM 11 it seems I had to match the pattern twice:</font></div><div><font><br></font></div><div><font>```</font></div><div><font><div>if (match(bo, m_Or(m_Value(X), m_Not(m_Value(Y))))) {</div><div>  // X | (~Y)</div><div>  ....</div><div>} else if (match(bo, m_Or(m_Not(m_Value(X)), m_Value(Y)))) {</div><div>  // (~X) | Y</div><div>  ....</div><div>}</div></font></div><div><font>```</font></div><div><font><br></font></div><div>and only the second code path is used.</div><div><br></div><div><br></div><div><br></div><div>Going through IR/PatternMatch.h , it seems that while the template BinaryOp_match has an optional argument Commutable, it defaults to false and none of m_Or, m_Xor or m_And seem to set it to true.</div><div><br></div><div>What am I misunderstanding here?</div><div><br></div><div><br></div><div>Zhang</div><div><includetail><!--<![endif]--></includetail></div>