Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -5059,10 +5059,10 @@ in ``op2``. If the ``nuw`` keyword is present, then the shift produces a :ref:`poison -value ` if it shifts out any non-zero bits. If the -``nsw`` keyword is present, then the shift produces a :ref:`poison -value ` if it shifts out any bits that disagree with the -resultant sign bit. As such, NUW/NSW have the same semantics as they +value ` if it shifts out any non-zero bits. +If the ``nsw`` keyword is present, then the shift produces a :ref:`poison +value ` if ``op1`` is not one and it shifts out any non-sign bits. +As such, NUW/NSW have the same semantics as they would if the shift were expressed as a mul instruction with the same nsw/nuw bits in (mul %op1, (shl 1, %op2)). Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -2302,8 +2302,14 @@ Lower = CI2->getValue().shl(ShiftAmount); Upper = CI2->getValue() + 1; } else { - // 'shl nsw CI2, x' produces [CI2, CI2 << CLZ(CI2)-1] - unsigned ShiftAmount = CI2->getValue().countLeadingZeros() - 1; + unsigned ShiftAmount; + if (CI2->isOne()) { + // 'shl nsw 1, x' produces [1, 1 << (Width-1)] + ShiftAmount = Width - 1; + } else { + // 'shl nsw CI2, x' produces [CI2, CI2 << CLZ(CI2)-1] + ShiftAmount = CI2->getValue().countLeadingZeros() - 1; + } Lower = CI2->getValue(); Upper = CI2->getValue().shl(ShiftAmount) + 1; } Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -200,8 +200,7 @@ BinaryOperator *BO = BinaryOperator::CreateMul(NewOp, Shl); if (I.hasNoUnsignedWrap() && Mul->hasNoUnsignedWrap()) BO->setHasNoUnsignedWrap(); - if (I.hasNoSignedWrap() && Mul->hasNoSignedWrap() && - Shl->isNotMinSignedValue()) + if (I.hasNoSignedWrap() && Mul->hasNoSignedWrap()) BO->setHasNoSignedWrap(); return BO; } @@ -221,7 +220,7 @@ if (I.hasNoUnsignedWrap()) Shl->setHasNoUnsignedWrap(); - if (I.hasNoSignedWrap() && NewCst->isNotMinSignedValue()) + if (I.hasNoSignedWrap()) Shl->setHasNoSignedWrap(); return Shl; Index: test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll =================================================================== --- test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll +++ test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll @@ -15,7 +15,7 @@ ;