aboutsummaryrefslogtreecommitdiff
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
commit73fa49d69742ac5277aa4be5a48e8f6fc3481412 (patch)
tree2c72b95e9711954d9ce62c6d5cd1a430b2efae2a
parent78b3c420b2191acde160492510c4a0ab90f94c1c (diff)
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
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp53
1 files changed, 41 insertions, 12 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 2a48fc06c9..8bb23226e4 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<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;
}