[PATCH] D20774: [InstCombine] look through bitcasts to find selects

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 2 16:15:34 PDT 2016


majnemer accepted this revision.
majnemer added a comment.
This revision is now accepted and ready to land.

LGTM with nits


================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:1647-1689
@@ -1646,17 +1646,45 @@
   // If A is not a select of -1/0, this cannot match.
   Value *Cond = nullptr;
-  if (!match(A, m_SExt(m_Value(Cond))) || !Cond->getType()->isIntegerTy(1))
-    return nullptr;
+  if (match(A, m_SExt(m_Value(Cond))) &&
+      Cond->getType()->getScalarType()->isIntegerTy(1)) {
 
-  // ((cond?-1:0)&C) | (B&(cond?0:-1)) -> cond ? C : B.
-  if (match(D, m_Not(m_SExt(m_Specific(Cond)))))
-    return SelectInst::Create(Cond, C, B);
-  if (match(D, m_SExt(m_Not(m_Specific(Cond)))))
-    return SelectInst::Create(Cond, C, B);
-
-  // ((cond?-1:0)&C) | ((cond?0:-1)&D) -> cond ? C : D.
-  if (match(B, m_Not(m_SExt(m_Specific(Cond)))))
-    return SelectInst::Create(Cond, C, D);
-  if (match(B, m_SExt(m_Not(m_Specific(Cond)))))
-    return SelectInst::Create(Cond, C, D);
+    // ((cond ? -1:0) & C) | (B & (cond ? 0:-1)) -> cond ? C : B.
+    if (match(D, m_Not(m_SExt(m_Specific(Cond)))))
+      return SelectInst::Create(Cond, C, B);
+    if (match(D, m_SExt(m_Not(m_Specific(Cond)))))
+      return SelectInst::Create(Cond, C, B);
+
+    // ((cond ? -1:0) & C) | ((cond ? 0:-1) & D) -> cond ? C : D.
+    if (match(B, m_Not(m_SExt(m_Specific(Cond)))))
+      return SelectInst::Create(Cond, C, D);
+    if (match(B, m_SExt(m_Not(m_Specific(Cond)))))
+      return SelectInst::Create(Cond, C, D);
+  }
+
+  // The sign-extended boolean condition may be hiding behind a bitcast. In that
+  // case, look for the same patterns as above. However, we need to bitcast the
+  // input operands to the select and bitcast the output of the select to match
+  // the expected types.
+  if (match(A, m_BitCast(m_SExt(m_Value(Cond)))) &&
+      Cond->getType()->getScalarType()->isIntegerTy(1)) {
+    Type *SrcType = cast<BitCastInst>(A)->getSrcTy();
+
+    // ((bc Cond) & C) | (B & (bc ~Cond)) --> bc (select Cond, (bc C), (bc B))
+    if (match(D, m_CombineOr(m_BitCast(m_Not(m_SExt(m_Specific(Cond)))),
+                             m_BitCast(m_SExt(m_Not(m_Specific(Cond))))))) {
+      Value *BitcastC = Builder.CreateBitCast(C, SrcType);
+      Value *BitcastB = Builder.CreateBitCast(B, SrcType);
+      Value *Select = Builder.CreateSelect(Cond, BitcastC, BitcastB);
+      return CastInst::Create(Instruction::BitCast, Select, A->getType());
+    }
+
+    // ((bc Cond) & C) | ((bc ~Cond) & D) --> bc (select Cond, (bc C), (bc D))
+    if (match(B, m_CombineOr(m_BitCast(m_Not(m_SExt(m_Specific(Cond)))),
+                             m_BitCast(m_SExt(m_Not(m_Specific(Cond))))))) {
+      Value *BitcastC = Builder.CreateBitCast(C, SrcType);
+      Value *BitcastD = Builder.CreateBitCast(D, SrcType);
+      Value *Select = Builder.CreateSelect(Cond, BitcastC, BitcastD);
+      return CastInst::Create(Instruction::BitCast, Select, A->getType());
+    }
+  }
 
----------------
It would be nice if we could find a way to fold the code which handles the bitcast case with the code which doesn't.


http://reviews.llvm.org/D20774





More information about the llvm-commits mailing list