[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Thu May 25 16:48:50 PDT 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.485 -> 1.486
---
Log message:
Introduce a helper function that simplifies interpretation of shuffle masks.
No functionality change.
---
Diffs of the changes: (+64 -91)
InstructionCombining.cpp | 155 +++++++++++++++++++----------------------------
1 files changed, 64 insertions(+), 91 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.485 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.486
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.485 Thu May 25 18:24:33 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 25 18:48:38 2006
@@ -7024,6 +7024,25 @@
return false;
}
+/// getShuffleMask - Read and decode a shufflevector mask. It turns undef
+/// elements into values that are larger than the #elts in the input.
+static std::vector<unsigned> getShuffleMask(const ShuffleVectorInst *SVI) {
+ unsigned NElts = SVI->getType()->getNumElements();
+ if (isa<ConstantAggregateZero>(SVI->getOperand(2)))
+ return std::vector<unsigned>(NElts, 0);
+ if (isa<UndefValue>(SVI->getOperand(2)))
+ return std::vector<unsigned>(NElts, 2*NElts);
+
+ std::vector<unsigned> Result;
+ const ConstantPacked *CP = cast<ConstantPacked>(SVI->getOperand(2));
+ for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
+ if (isa<UndefValue>(CP->getOperand(i)))
+ Result.push_back(NElts*2); // undef -> 8
+ else
+ Result.push_back(cast<ConstantUInt>(CP->getOperand(i))->getValue());
+ return Result;
+}
+
/// FindScalarElement - Given a vector and an element number, see if the scalar
/// value is already around as a register, for example if it were inserted then
/// extracted from the vector.
@@ -7053,18 +7072,13 @@
// vector input.
return FindScalarElement(III->getOperand(0), EltNo);
} else if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(V)) {
- if (isa<ConstantAggregateZero>(SVI->getOperand(2))) {
- return FindScalarElement(SVI->getOperand(0), 0);
- } else if (ConstantPacked *CP =
- dyn_cast<ConstantPacked>(SVI->getOperand(2))) {
- if (isa<UndefValue>(CP->getOperand(EltNo)))
- return UndefValue::get(PTy->getElementType());
- unsigned InEl = cast<ConstantUInt>(CP->getOperand(EltNo))->getValue();
- if (InEl < Width)
- return FindScalarElement(SVI->getOperand(0), InEl);
- else
- return FindScalarElement(SVI->getOperand(1), InEl - Width);
- }
+ unsigned InEl = getShuffleMask(SVI)[EltNo];
+ if (InEl < Width)
+ return FindScalarElement(SVI->getOperand(0), InEl);
+ else if (InEl < Width*2)
+ return FindScalarElement(SVI->getOperand(1), InEl - Width);
+ else
+ return UndefValue::get(PTy->getElementType());
}
// Otherwise, we don't know.
@@ -7144,28 +7158,18 @@
// 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));
+ unsigned SrcIdx = getShuffleMask(SVI)[Elt->getValue()];
+ Value *Src;
+ if (SrcIdx < SVI->getType()->getNumElements())
+ Src = SVI->getOperand(0);
+ else if (SrcIdx < SVI->getType()->getNumElements()*2) {
+ SrcIdx -= SVI->getType()->getNumElements();
+ Src = SVI->getOperand(1);
+ } else {
+ return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType()));
}
+ return new ExtractElementInst(Src,
+ ConstantUInt::get(Type::UIntTy, SrcIdx));
}
}
}
@@ -7373,84 +7377,53 @@
Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
Value *LHS = SVI.getOperand(0);
Value *RHS = SVI.getOperand(1);
- Constant *Mask = cast<Constant>(SVI.getOperand(2));
+ std::vector<unsigned> Mask = getShuffleMask(&SVI);
bool MadeChange = false;
- if (isa<UndefValue>(Mask))
+ if (isa<UndefValue>(SVI.getOperand(2)))
return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType()));
// TODO: If we have shuffle(x, undef, mask) and any elements of mask refer to
// the undef, change them to undefs.
- // Canonicalize shuffle(x,x) -> shuffle(x,undef)
- if (LHS == RHS) {
- if (isa<UndefValue>(LHS)) {
+ // Canonicalize shuffle(x ,x,mask) -> shuffle(x, undef,mask')
+ // Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask').
+ if (LHS == RHS || isa<UndefValue>(LHS)) {
+ if (isa<UndefValue>(LHS) && LHS == RHS) {
// 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);
+ // Remap any references to RHS to use LHS.
+ std::vector<Constant*> Elts;
+ for (unsigned i = 0, e = Mask.size(); i != e; ++i) {
+ if (Mask[i] > 2*e)
+ Elts.push_back(UndefValue::get(Type::UIntTy));
+ else
+ Elts.push_back(ConstantUInt::get(Type::UIntTy, Mask[i] & (e-1)));
}
+ SVI.setOperand(0, SVI.getOperand(1));
SVI.setOperand(1, UndefValue::get(RHS->getType()));
- SVI.setOperand(2, Mask);
+ SVI.setOperand(2, ConstantPacked::get(Elts));
MadeChange = true;
}
- // Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask').
- if (isa<UndefValue>(LHS)) {
- // shuffle(undef,x,<0,0,0,0>) -> undef.
- if (isa<ConstantAggregateZero>(Mask))
- return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType()));
+ // Analyze the shuffle, are the LHS or RHS and identity shuffle?
+ bool isLHSID = true, isRHSID = true;
- ConstantPacked *CPM = cast<ConstantPacked>(Mask);
- std::vector<Constant*> Elts;
- for (unsigned i = 0, e = CPM->getNumOperands(); i != e; ++i) {
- if (isa<UndefValue>(CPM->getOperand(i)))
- Elts.push_back(CPM->getOperand(i));
- else {
- unsigned EltNo = cast<ConstantUInt>(CPM->getOperand(i))->getRawValue();
- if (EltNo >= e)
- Elts.push_back(ConstantUInt::get(Type::UIntTy, EltNo-e));
- else // Referring to the undef.
- Elts.push_back(UndefValue::get(Type::UIntTy));
- }
- }
- return new ShuffleVectorInst(RHS, LHS, ConstantPacked::get(Elts));
- }
-
- 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();
+ for (unsigned i = 0, e = Mask.size(); i != e; ++i) {
+ if (Mask[i] >= e*2) continue; // Ignore undef values.
+ // Is this an identity shuffle of the LHS value?
+ isLHSID &= (Mask[i] == i);
- // 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);
+ // Is this an identity shuffle of the RHS value?
+ isRHSID &= (Mask[i]-e == i);
}
+
+ // Eliminate identity shuffles.
+ if (isLHSID) return ReplaceInstUsesWith(SVI, LHS);
+ if (isRHSID) return ReplaceInstUsesWith(SVI, RHS);
return MadeChange ? &SVI : 0;
}
More information about the llvm-commits
mailing list