InstCombine: Scalarize single use icmp/fcmp

llvm-svn: 348801
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index bc14f10..7ad29a5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -48,6 +48,8 @@
 /// Return true if the value is cheaper to scalarize than it is to leave as a
 /// vector operation. isConstant indicates whether we're extracting one known
 /// element. If false we're extracting a variable index.
+//
+// FIXME: It's possible to create more instructions that previously existed.
 static bool cheapToScalarize(Value *V, bool isConstant) {
   if (Constant *C = dyn_cast<Constant>(V)) {
     if (isConstant) return true;
@@ -310,6 +312,16 @@
     return BinaryOperator::CreateWithCopiedFlags(BO->getOpcode(), E0, E1, BO);
   }
 
+  Value *X, *Y;
+  CmpInst::Predicate Pred;
+  if (match(SrcVec, m_Cmp(Pred, m_Value(X), m_Value(Y))) &&
+      cheapToScalarize(SrcVec, IndexC)) {
+    // extelt (cmp X, Y), Index --> cmp (extelt X, Index), (extelt Y, Index)
+    Value *E0 = Builder.CreateExtractElement(X, Index);
+    Value *E1 = Builder.CreateExtractElement(Y, Index);
+    return CmpInst::Create(cast<CmpInst>(SrcVec)->getOpcode(), Pred, E0, E1);
+  }
+
   if (auto *I = dyn_cast<Instruction>(SrcVec)) {
     if (auto *IE = dyn_cast<InsertElementInst>(I)) {
       // Extracting the inserted element?