diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 1b42d3d..c26766a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -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; } |