forked from OSchip/llvm-project
[InstCombine] make div/rem vector constant utility function; NFCI
This was originally in D48401 and will be used there. llvm-svn: 335242
This commit is contained in:
parent
ad71333b92
commit
3e5c051a06
|
@ -212,6 +212,23 @@ IntrinsicIDToOverflowCheckFlavor(unsigned ID) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Integer division/remainder require special handling to avoid undefined
|
||||
/// behavior. If a constant vector has undef elements, replace those undefs with
|
||||
/// '1' because that's always safe to execute.
|
||||
static inline Constant *getSafeVectorConstantForIntDivRem(Constant *In) {
|
||||
assert(In->getType()->isVectorTy() && "Not expecting scalars here");
|
||||
assert(In->getType()->getVectorElementType()->isIntegerTy() &&
|
||||
"Not expecting FP opcodes/operands/constants here");
|
||||
|
||||
unsigned NumElts = In->getType()->getVectorNumElements();
|
||||
SmallVector<Constant *, 16> Out(NumElts);
|
||||
for (unsigned i = 0; i != NumElts; ++i) {
|
||||
Constant *C = In->getAggregateElement(i);
|
||||
Out[i] = isa<UndefValue>(C) ? ConstantInt::get(C->getType(), 1) : C;
|
||||
}
|
||||
return ConstantVector::get(Out);
|
||||
}
|
||||
|
||||
/// The core instruction combiner logic.
|
||||
///
|
||||
/// This class provides both the logic to recursively visit instructions and
|
||||
|
|
|
@ -1417,23 +1417,17 @@ Instruction *InstCombiner::foldShuffledBinop(BinaryOperator &Inst) {
|
|||
}
|
||||
}
|
||||
if (MayChange) {
|
||||
Constant *NewC = ConstantVector::get(NewVecC);
|
||||
// With integer div/rem instructions, it is not safe to use a vector with
|
||||
// undef elements because the entire instruction can be folded to undef.
|
||||
// So replace undef elements with '1' because that can never induce
|
||||
// undefined behavior. All other binop opcodes are always safe to
|
||||
// speculate, and therefore, it is fine to include undef elements for
|
||||
// unused lanes (and using undefs may help optimization).
|
||||
if (Inst.isIntDivRem()) {
|
||||
assert(C->getType()->getScalarType()->isIntegerTy() &&
|
||||
"Not expecting FP opcodes/operands/constants here");
|
||||
for (unsigned i = 0; i < VWidth; ++i)
|
||||
if (isa<UndefValue>(NewVecC[i]))
|
||||
NewVecC[i] = ConstantInt::get(NewVecC[i]->getType(), 1);
|
||||
}
|
||||
|
||||
// All other binop opcodes are always safe to speculate, and therefore, it
|
||||
// is fine to include undef elements for unused lanes (and using undefs
|
||||
// may help optimization).
|
||||
if (Inst.isIntDivRem())
|
||||
NewC = getSafeVectorConstantForIntDivRem(NewC);
|
||||
|
||||
// Op(shuffle(V1, Mask), C) -> shuffle(Op(V1, NewC), Mask)
|
||||
// Op(C, shuffle(V1, Mask)) -> shuffle(Op(NewC, V1), Mask)
|
||||
Constant *NewC = ConstantVector::get(NewVecC);
|
||||
Value *NewLHS = isa<Constant>(LHS) ? NewC : V1;
|
||||
Value *NewRHS = isa<Constant>(LHS) ? V1 : NewC;
|
||||
return createBinOpShuffle(NewLHS, NewRHS, Mask);
|
||||
|
|
Loading…
Reference in New Issue