Implement InstCombine/vec_shuffle.ll:test[12]

llvm-svn: 27571
This commit is contained in:
Chris Lattner 2006-04-10 22:45:52 +00:00
parent 76b0813040
commit fbb77a408b
1 changed files with 62 additions and 0 deletions

View File

@ -138,6 +138,7 @@ namespace {
Instruction *visitBranchInst(BranchInst &BI);
Instruction *visitSwitchInst(SwitchInst &SI);
Instruction *visitExtractElementInst(ExtractElementInst &EI);
Instruction *visitShuffleVectorInst(ShuffleVectorInst &SVI);
// visitInstruction - Specify what to return for unhandled instructions...
Instruction *visitInstruction(Instruction &I) { return 0; }
@ -6876,6 +6877,67 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
return 0;
}
Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
Value *LHS = SVI.getOperand(0);
Value *RHS = SVI.getOperand(1);
Constant *Mask = cast<Constant>(SVI.getOperand(2));
bool MadeChange = false;
if (isa<UndefValue>(Mask))
return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType()));
// Canonicalize shuffle(x,x) -> shuffle(x,undef)
if (LHS == RHS) {
if (isa<UndefValue>(LHS)) {
// shuffle(undef,undef,mask) -> undef.
return ReplaceInstUsesWith(SVI, LHS);
}
if (!isa<ConstantAggregateZero>(Mask)) {
// Remap any references to RHS to use LHS.
ConstantPacked *CP = cast<ConstantPacked>(Mask);
std::vector<Constant*> Elts;
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
Elts.push_back(CP->getOperand(i));
if (isa<UndefValue>(CP->getOperand(i)))
continue;
unsigned MV = cast<ConstantInt>(CP->getOperand(i))->getRawValue();
if (MV >= e)
Elts.back() = ConstantUInt::get(Type::UIntTy, MV & (e-1));
}
Mask = ConstantPacked::get(Elts);
}
SVI.setOperand(1, UndefValue::get(RHS->getType()));
SVI.setOperand(2, Mask);
MadeChange = true;
}
if (ConstantPacked *CP = dyn_cast<ConstantPacked>(Mask)) {
bool isLHSID = true, isRHSID = true;
// Analyze the shuffle.
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
if (isa<UndefValue>(CP->getOperand(i)))
continue;
unsigned MV = cast<ConstantInt>(CP->getOperand(i))->getRawValue();
// Is this an identity shuffle of the LHS value?
isLHSID &= (MV == i);
// Is this an identity shuffle of the RHS value?
isRHSID &= (MV-e == i);
}
// Eliminate identity shuffles.
if (isLHSID) return ReplaceInstUsesWith(SVI, LHS);
if (isRHSID) return ReplaceInstUsesWith(SVI, RHS);
}
return MadeChange ? &SVI : 0;
}
void InstCombiner::removeFromWorkList(Instruction *I) {
WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),