[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:
Sanjay Patel 2018-06-21 14:59:35 +00:00
parent ad71333b92
commit 3e5c051a06
2 changed files with 24 additions and 13 deletions

View File

@ -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

View File

@ -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);