summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-05-25 22:53:38 +0000
committerChris Lattner <sabre@nondot.org>2006-05-25 22:53:38 +0000
commit83f6578b0c5e9b6ef5367f1c8878489826495ec3 (patch)
tree3610dda827719f3e9009a1ff8fcc8eeed041a3cf /llvm/lib/Transforms/Scalar/InstructionCombining.cpp
parentf322bf6297bccb28fa14287105918b1a7c777ba0 (diff)
downloadbcm5719-llvm-83f6578b0c5e9b6ef5367f1c8878489826495ec3.tar.gz
bcm5719-llvm-83f6578b0c5e9b6ef5367f1c8878489826495ec3.zip
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] llvm-svn: 28485
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp53
1 files changed, 41 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 2a48fc06c94..8bb23226e48 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -7072,7 +7072,7 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
return ReplaceInstUsesWith(EI, Elt);
}
- if (Instruction *I = dyn_cast<Instruction>(EI.getOperand(0)))
+ if (Instruction *I = dyn_cast<Instruction>(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<InsertElementInst>(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<Constant>(IE->getOperand(2)) &&
- isa<Constant>(EI.getOperand(1))) {
- AddUsesToWorkList(EI);
- EI.setOperand(0, IE->getOperand(0));
- return &EI;
+ }
+ }
+ if (InsertElementInst *IE = dyn_cast<InsertElementInst>(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<Constant>(IE->getOperand(2)) &&
+ isa<Constant>(EI.getOperand(1))) {
+ AddUsesToWorkList(EI);
+ EI.setOperand(0, IE->getOperand(0));
+ return &EI;
+ }
+ } else if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(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<ConstantUInt>(EI.getOperand(1))) {
+ unsigned ExtractedIdx = Elt->getValue();
+ if (ConstantPacked *CP = dyn_cast<ConstantPacked>(SVI->getOperand(2))) {
+ unsigned Idx = 0;
+ if (ConstantUInt *CI =
+ dyn_cast<ConstantUInt>(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<ConstantAggregateZero>(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;
}
OpenPOWER on IntegriCloud