(A & sext(C)) | (B & ~sext(C)  ->  C ? A : B


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58351 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 8ec775b..4ec36ad 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -4337,6 +4337,25 @@
         return BinaryOperator::CreateAnd(V1, Or);
       }
     }
+
+    // (A & sext(C0)) | (B & ~sext(C0) ->  C0 ? A : B
+    if (isa<SExtInst>(C) &&
+        cast<User>(C)->getOperand(0)->getType() == Type::Int1Ty) {
+      if (match(D, m_Not(m_Value(C))))
+        return SelectInst::Create(cast<User>(C)->getOperand(0), A, B);
+      // And commutes, try both ways.
+      if (match(B, m_Not(m_Value(C))))
+        return SelectInst::Create(cast<User>(C)->getOperand(0), A, D);
+    }
+    // Or commutes, try both ways.
+    if (isa<SExtInst>(D) &&
+        cast<User>(D)->getOperand(0)->getType() == Type::Int1Ty) {
+      if (match(C, m_Not(m_Value(D))))
+        return SelectInst::Create(cast<User>(D)->getOperand(0), A, B);
+      // And commutes, try both ways.
+      if (match(A, m_Not(m_Value(D))))
+        return SelectInst::Create(cast<User>(D)->getOperand(0), C, B);
+    }
   }
   
   // (X >> Z) | (Y >> Z)  -> (X|Y) >> Z  for all shifts.