[llvm] r273706 - [InstCombine] refactor optional bitcasting in matchSelectFromAndOr() into one code path (NFCI)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 24 11:55:28 PDT 2016


Author: spatel
Date: Fri Jun 24 13:55:27 2016
New Revision: 273706

URL: http://llvm.org/viewvc/llvm-project?rev=273706&view=rev
Log:
[InstCombine] refactor optional bitcasting in matchSelectFromAndOr() into one code path (NFCI)

Tests to verify that the commuted variants are all exercised were added with:
http://reviews.llvm.org/rL273702

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=273706&r1=273705&r2=273706&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Fri Jun 24 13:55:27 2016
@@ -1630,38 +1630,32 @@ Instruction *InstCombiner::MatchBSwap(Bi
 
 /// We have an expression of the form (A & C) | (B & D). If A is (Cond?-1:0)
 /// and B is ~(Cond?-1,0), then simplify this expression to "Cond ? C : D".
-static Instruction *matchSelectFromAndOr(Value *A, Value *C, Value *B, Value *D,
+static Value *matchSelectFromAndOr(Value *A, Value *C, Value *B, Value *D,
                                          InstCombiner::BuilderTy &Builder) {
-  // 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()->getScalarType()->isIntegerTy(1)) {
-
-    // ((cond ? -1:0) & C) | ((cond ? 0:-1) & D) -> cond ? C : D.
-    if (match(B, m_CombineOr(m_Not(m_SExt(m_Specific(Cond))),
-                             m_SExt(m_Not(m_Specific(Cond))))))
-      return SelectInst::Create(Cond, C, D);
+  // The potential condition of the select may be bitcasted. In that case, look
+  // through its bitcast and the corresponding bitcast of the 'not' condition.
+  Type *OrigType = A->getType();
+  Value *SrcA, *SrcB;
+  if (match(A, m_BitCast(m_Value(SrcA))) &&
+      match(B, m_BitCast(m_Value(SrcB)))) {
+    A = SrcA;
+    B = SrcB;
   }
 
-  // TODO: Refactor the pattern matching above and below so there's less code.
-
-  // 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();
-
+  // The condition must be a value of -1/0, and B must be the 'not' of that
+  // condition.
+  Value *Cond;
+  if (match(A, m_SExt(m_Value(Cond))) &&
+      Cond->getType()->getScalarType()->isIntegerTy(1) &&
+      match(B, m_CombineOr(m_Not(m_SExt(m_Specific(Cond))),
+                           m_SExt(m_Not(m_Specific(Cond)))))) {
     // ((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());
-    }
+    // The bitcasts will either all exist or all not exist. The builder will
+    // not create unnecessary casts if the types already match.
+    Value *BitcastC = Builder.CreateBitCast(C, A->getType());
+    Value *BitcastD = Builder.CreateBitCast(D, A->getType());
+    Value *Select = Builder.CreateSelect(Cond, BitcastC, BitcastD);
+    return Builder.CreateBitCast(Select, OrigType);
   }
 
   return nullptr;
@@ -2260,22 +2254,22 @@ Instruction *InstCombiner::visitOr(Binar
     }
 
     // (Cond & C) | (~Cond & D) -> Cond ? C : D, and commuted variants.
-    if (Instruction *Match = matchSelectFromAndOr(A, C, B, D, *Builder))
-      return Match;
-    if (Instruction *Match = matchSelectFromAndOr(A, C, D, B, *Builder))
-      return Match;
-    if (Instruction *Match = matchSelectFromAndOr(C, A, B, D, *Builder))
-      return Match;
-    if (Instruction *Match = matchSelectFromAndOr(C, A, D, B, *Builder))
-      return Match;
-    if (Instruction *Match = matchSelectFromAndOr(B, D, A, C, *Builder))
-      return Match;
-    if (Instruction *Match = matchSelectFromAndOr(B, D, C, A, *Builder))
-      return Match;
-    if (Instruction *Match = matchSelectFromAndOr(D, B, A, C, *Builder))
-      return Match;
-    if (Instruction *Match = matchSelectFromAndOr(D, B, C, A, *Builder))
-      return Match;
+    if (Value *V = matchSelectFromAndOr(A, C, B, D, *Builder))
+      return replaceInstUsesWith(I, V);
+    if (Value *V = matchSelectFromAndOr(A, C, D, B, *Builder))
+      return replaceInstUsesWith(I, V);
+    if (Value *V = matchSelectFromAndOr(C, A, B, D, *Builder))
+      return replaceInstUsesWith(I, V);
+    if (Value *V = matchSelectFromAndOr(C, A, D, B, *Builder))
+      return replaceInstUsesWith(I, V);
+    if (Value *V = matchSelectFromAndOr(B, D, A, C, *Builder))
+      return replaceInstUsesWith(I, V);
+    if (Value *V = matchSelectFromAndOr(B, D, C, A, *Builder))
+      return replaceInstUsesWith(I, V);
+    if (Value *V = matchSelectFromAndOr(D, B, A, C, *Builder))
+      return replaceInstUsesWith(I, V);
+    if (Value *V = matchSelectFromAndOr(D, B, C, A, *Builder))
+      return replaceInstUsesWith(I, V);
 
     // ((A&~B)|(~A&B)) -> A^B
     if ((match(C, m_Not(m_Specific(D))) &&




More information about the llvm-commits mailing list