<div dir="ltr">Sorry, I'm not understanding. Are you referring to the opcode selection of 'and' / 'or' before calling CreateBinOp()? That's a result of hoisting the code so it can be called from visitAnd / visitOr, and I added the assert to make sure this helper wouldn't be misused. Let me know if there's a hole in that logic.<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 9, 2015 at 2:27 PM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Tue, Sep 8, 2015 at 1:14 PM, Sanjay Patel via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: spatel<br>
Date: Tue Sep  8 15:14:13 2015<br>
New Revision: 247061<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=247061&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=247061&view=rev</a><br>
Log:<br>
refactor matches for De Morgan's Laws; NFCI<br>
<br>
Modified:<br>
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp<br>
<br>
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=247061&r1=247060&r2=247061&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=247061&r1=247060&r2=247061&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Tue Sep  8 15:14:13 2015<br>
@@ -1200,6 +1200,34 @@ Value *InstCombiner::FoldAndOfFCmps(FCmp<br>
   return nullptr;<br>
 }<br>
<br>
+/// Match De Morgan's Laws:<br>
+/// (~A & ~B) == (~(A | B))<br>
+/// (~A | ~B) == (~(A & B))<br>
+static Instruction *matchDeMorgansLaws(BinaryOperator &I,<br>
+                                       InstCombiner::BuilderTy *Builder) {<br>
+  auto Opcode = I.getOpcode();<br>
+  assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&<br>
+         "Trying to match De Morgan's Laws with something other than and/or");<br>
+<br>
+  Value *Op0 = I.getOperand(0);<br>
+  Value *Op1 = I.getOperand(1);<br>
+  // TODO: Use pattern matchers instead of dyn_cast.<br>
+  if (Value *Op0NotVal = dyn_castNotVal(Op0))<br>
+    if (Value *Op1NotVal = dyn_castNotVal(Op1))<br>
+      if (Op0->hasOneUse() && Op1->hasOneUse()) {<br>
+        // Flip the logic operation.<br>
+        if (Opcode == Instruction::And)<br>
+          Opcode = Instruction::Or;<br>
+        else<br>
+          Opcode = Instruction::And;<br></blockquote><div><br></div></div></div><div>Excuse me but how is this "no functional change" ?  I don't believe we had the logic to conditional create an Or before.</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        Value *LogicOp = Builder->CreateBinOp(Opcode, Op0NotVal, Op1NotVal,<br>
+                                              I.getName() + ".demorgan");<br>
+        return BinaryOperator::CreateNot(LogicOp);<br>
+      }<br>
+<br>
+  return nullptr;<br>
+}<br>
+<br>
 Instruction *InstCombiner::visitAnd(BinaryOperator &I) {<br>
   bool Changed = SimplifyAssociativeOrCommutative(I);<br>
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);<br>
@@ -1330,15 +1358,8 @@ Instruction *InstCombiner::visitAnd(Bina<br>
         return NV;<br>
   }<br>
<br>
-<br>
-  // (~A & ~B) == (~(A | B)) - De Morgan's Law<br>
-  if (Value *Op0NotVal = dyn_castNotVal(Op0))<br>
-    if (Value *Op1NotVal = dyn_castNotVal(Op1))<br>
-      if (Op0->hasOneUse() && Op1->hasOneUse()) {<br>
-        Value *Or = Builder->CreateOr(Op0NotVal, Op1NotVal,<br>
-                                      I.getName()+".demorgan");<br>
-        return BinaryOperator::CreateNot(Or);<br>
-      }<br>
+  if (Instruction *DeMorgan = matchDeMorgansLaws(I, Builder))<br>
+    return DeMorgan;<br>
<br>
   {<br>
     Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr;<br>
@@ -2360,14 +2381,8 @@ Instruction *InstCombiner::visitOr(Binar<br>
   if (match(Op0, m_And(m_Or(m_Specific(Op1), m_Value(C)), m_Value(A))))<br>
     return BinaryOperator::CreateOr(Op1, Builder->CreateAnd(A, C));<br>
<br>
-  // (~A | ~B) == (~(A & B)) - De Morgan's Law<br>
-  if (Value *Op0NotVal = dyn_castNotVal(Op0))<br>
-    if (Value *Op1NotVal = dyn_castNotVal(Op1))<br>
-      if (Op0->hasOneUse() && Op1->hasOneUse()) {<br>
-        Value *And = Builder->CreateAnd(Op0NotVal, Op1NotVal,<br>
-                                        I.getName()+".demorgan");<br>
-        return BinaryOperator::CreateNot(And);<br>
-      }<br>
+  if (Instruction *DeMorgan = matchDeMorgansLaws(I, Builder))<br>
+    return DeMorgan;<br>
<br>
   // Canonicalize xor to the RHS.<br>
   bool SwappedForXor = false;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>