InstCombine: Don't miscompile (x lshr C1) udiv C2

We have a transform that changes:
  (x lshr C1) udiv C2
into:
  x udiv (C2 << C1)

However, it is unsafe to do so if C2 << C1 discards any of C2's bits.

This fixes PR21255.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219634 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer
2014-10-13 21:48:30 +00:00
parent 2061a56b8a
commit dfe81adbce
4 changed files with 40 additions and 13 deletions

View File

@@ -965,11 +965,17 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
return Common;
// (x lshr C1) udiv C2 --> x udiv (C2 << C1)
if (Constant *C2 = dyn_cast<Constant>(Op1)) {
{
Value *X;
Constant *C1;
if (match(Op0, m_LShr(m_Value(X), m_Constant(C1))))
return BinaryOperator::CreateUDiv(X, ConstantExpr::getShl(C2, C1));
const APInt *C1, *C2;
if (match(Op0, m_LShr(m_Value(X), m_APInt(C1))) &&
match(Op1, m_APInt(C2))) {
bool Overflow;
APInt C2ShlC1 = C2->ushl_ov(*C1, Overflow);
if (!Overflow)
return BinaryOperator::CreateUDiv(
X, ConstantInt::get(X->getType(), C2ShlC1));
}
}
// (zext A) udiv (zext B) --> zext (A udiv B)