Skip to content

Commit

Permalink
InstCombine: Don't unconditionally preserve 'nsw' when shrinking cons…
Browse files Browse the repository at this point in the history
…tants

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
  • Loading branch information
majnemer committed Aug 22, 2014
1 parent 6ca2d8b commit c86bdc7
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
8 changes: 8 additions & 0 deletions lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
14 changes: 13 additions & 1 deletion test/Transforms/InstCombine/cast.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,19 @@ define i64 @test83(i16 %a, i64 %k) {
ret i64 %sh_prom1

; CHECK-LABEL: @test83(
; CHECK: %sub = add nsw i64 %k, 4294967295
; CHECK: %sub = add i64 %k, 4294967295
; CHECK: %sh_prom = trunc i64 %sub to i32
; CHECK: %shl = shl i32 %conv, %sh_prom
}

define i8 @test84(i32 %a) {
%add = add nsw i32 %a, -16777216
%shr = lshr exact i32 %add, 23
%trunc = trunc i32 %shr to i8
ret i8 %trunc

; CHECK-LABEL: @test84(
; CHECK: [[ADD:%.*]] = add i32 %a, 2130706432
; CHECK: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
; CHECK: [[CST:%.*]] = trunc i32 [[SHR]] to i8
}

0 comments on commit c86bdc7

Please sign in to comment.