diff options
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index bc14f1052ee..7ad29a5f83a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -48,6 +48,8 @@ using namespace PatternMatch; /// 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 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { 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? |