diff options
author | Chris Lattner <sabre@nondot.org> | 2006-04-10 22:45:52 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-04-10 22:45:52 +0000 |
commit | a844fc4cb026cbc5e29f5cd0d97c110147de3828 (patch) | |
tree | 0948e7f9760be0e1b5e6e1ae708358d4de991172 /lib/Transforms | |
parent | 7205684fa5753a8c0d9e5234f57e4acee9354246 (diff) | |
download | external_llvm-a844fc4cb026cbc5e29f5cd0d97c110147de3828.zip external_llvm-a844fc4cb026cbc5e29f5cd0d97c110147de3828.tar.gz external_llvm-a844fc4cb026cbc5e29f5cd0d97c110147de3828.tar.bz2 |
Implement InstCombine/vec_shuffle.ll:test[12]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27571 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index bfa4964..7674bd2 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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), |