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
This commit is contained in:
Chris Lattner 2006-05-25 22:53:38 +00:00
parent 78b3c420b2
commit 73fa49d697

View File

@ -7072,7 +7072,7 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
return ReplaceInstUsesWith(EI, Elt); 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()) { if (I->hasOneUse()) {
// Push extractelement into predecessor operation if legal and // Push extractelement into predecessor operation if legal and
// profitable to do so // profitable to do so
@ -7097,7 +7097,9 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
I->getName() + ".gep"); I->getName() + ".gep");
InsertNewInstBefore(GEP, EI); InsertNewInstBefore(GEP, EI);
return new LoadInst(GEP); return new LoadInst(GEP);
} else if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) { }
}
if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) {
// Extracting the inserted element? // Extracting the inserted element?
if (IE->getOperand(2) == EI.getOperand(1)) if (IE->getOperand(2) == EI.getOperand(1))
return ReplaceInstUsesWith(EI, IE->getOperand(1)); return ReplaceInstUsesWith(EI, IE->getOperand(1));
@ -7109,6 +7111,33 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
EI.setOperand(0, IE->getOperand(0)); EI.setOperand(0, IE->getOperand(0));
return &EI; 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; return 0;