mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-03 19:15:30 +00:00
Introduce a helper function that simplifies interpretation of shuffle masks.
No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28489 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cc1fc220a0
commit
863bcff183
@ -7024,6 +7024,25 @@ static bool CheapToScalarize(Value *V, bool isConstant) {
|
||||
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 @@ static Value *FindScalarElement(Value *V, unsigned EltNo) {
|
||||
// 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 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
|
||||
// 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::visitInsertElementInst(InsertElementInst &IE) {
|
||||
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));
|
||||
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 RHS value?
|
||||
isRHSID &= (Mask[i]-e == i);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// Eliminate identity shuffles.
|
||||
if (isLHSID) return ReplaceInstUsesWith(SVI, LHS);
|
||||
if (isRHSID) return ReplaceInstUsesWith(SVI, RHS);
|
||||
|
||||
return MadeChange ? &SVI : 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user