InstCombine: Don't unconditionally preserve 'nsw' when shrinking constants

Consider:
  %add = add nsw i32 %a, -16777216
  %and = and i32 %add, 255

Regardless of whether or not we demand the sign bit of %add, we cannot
replace -16777216 with 2130706432 without also removing 'nsw' from the
instruction.

This fixes PR20377.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216261 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer
2014-08-22 07:56:32 +00:00
parent 6ca2d8b7c7
commit c86bdc73e8
2 changed files with 21 additions and 1 deletions

View File

@ -43,6 +43,14 @@ static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo,
// This instruction is producing bits that are not demanded. Shrink the RHS.
Demanded &= OpC->getValue();
I->setOperand(OpNo, ConstantInt::get(OpC->getType(), Demanded));
// If 'nsw' is set and the constant is negative, removing *any* bits from the
// constant could make overflow occur. Remove 'nsw' from the instruction in
// this case.
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I))
if (OBO->hasNoSignedWrap() && OpC->getValue().isNegative())
cast<BinaryOperator>(OBO)->setHasNoSignedWrap(false);
return true;
}