From: Chris Lattner Date: Thu, 25 May 2006 22:53:38 +0000 (+0000) Subject: extract element from a shuffle vector can be trivially turned into an X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=73fa49d69742ac5277aa4be5a48e8f6fc3481412;p=oota-llvm.git extract element from a shuffle vector can be trivially turned into an extractelement from the SV's source. This implement vec_shuffle.ll:test[45] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28485 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 2a48fc06c94..8bb23226e48 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -7072,7 +7072,7 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { return ReplaceInstUsesWith(EI, Elt); } - if (Instruction *I = dyn_cast(EI.getOperand(0))) + if (Instruction *I = dyn_cast(EI.getOperand(0))) { if (I->hasOneUse()) { // Push extractelement into predecessor operation if legal and // profitable to do so @@ -7097,20 +7097,49 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { I->getName() + ".gep"); InsertNewInstBefore(GEP, EI); return new LoadInst(GEP); - } else if (InsertElementInst *IE = dyn_cast(I)) { - // Extracting the inserted element? - if (IE->getOperand(2) == EI.getOperand(1)) - return ReplaceInstUsesWith(EI, IE->getOperand(1)); - // If the inserted and extracted elements are constants, they must not - // be the same value, extract from the pre-inserted value instead. - if (isa(IE->getOperand(2)) && - isa(EI.getOperand(1))) { - AddUsesToWorkList(EI); - EI.setOperand(0, IE->getOperand(0)); - return &EI; + } + } + if (InsertElementInst *IE = dyn_cast(I)) { + // Extracting the inserted element? + if (IE->getOperand(2) == EI.getOperand(1)) + return ReplaceInstUsesWith(EI, IE->getOperand(1)); + // If the inserted and extracted elements are constants, they must not + // be the same value, extract from the pre-inserted value instead. + if (isa(IE->getOperand(2)) && + isa(EI.getOperand(1))) { + AddUsesToWorkList(EI); + EI.setOperand(0, IE->getOperand(0)); + return &EI; + } + } else if (ShuffleVectorInst *SVI = dyn_cast(I)) { + // If this is extracting an element from a shufflevector, figure out where + // it came from and extract from the appropriate input element instead. + if (ConstantUInt *Elt = dyn_cast(EI.getOperand(1))) { + unsigned ExtractedIdx = Elt->getValue(); + if (ConstantPacked *CP = dyn_cast(SVI->getOperand(2))) { + unsigned Idx = 0; + if (ConstantUInt *CI = + dyn_cast(CP->getOperand(ExtractedIdx))) + Idx = CI->getValue(); + Value *Src; + if (Idx < CP->getNumOperands()) + Src = SVI->getOperand(0); + else { + Idx -= CP->getNumOperands(); + Src = SVI->getOperand(0); + } + return new ExtractElementInst(Src, + ConstantUInt::get(Type::UIntTy, Idx)); + + } else if (isa(SVI->getOperand(2))) { + // If extracting from a splat of the 0th element, return an extract + // of the zero'th element of the input to the splat. + return new ExtractElementInst(SVI->getOperand(0), + ConstantUInt::get(Type::UIntTy, 0)); } } } + } return 0; }