InstCombine: Infer nuw for multiplies

A multiply cannot unsigned wrap if there are bitwidth, or more, leading
zero bits between the two operands.

llvm-svn: 224849
This commit is contained in:
David Majnemer 2014-12-26 09:50:35 +00:00
parent a55027f68a
commit b1296ec0fd
4 changed files with 57 additions and 6 deletions

View File

@ -286,6 +286,7 @@ private:
bool WillNotOverflowSignedSub(Value *LHS, Value *RHS, Instruction *CxtI);
bool WillNotOverflowUnsignedSub(Value *LHS, Value *RHS, Instruction *CxtI);
bool WillNotOverflowSignedMul(Value *LHS, Value *RHS, Instruction *CxtI);
bool WillNotOverflowUnsignedMul(Value *LHS, Value *RHS, Instruction *CxtI);
Value *EmitGEPOffset(User *GEP);
Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN);
Value *EvaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask);

View File

@ -165,6 +165,39 @@ bool InstCombiner::WillNotOverflowSignedMul(Value *LHS, Value *RHS,
return false;
}
/// \brief Return true if we can prove that:
/// (mul LHS, RHS) === (mul nuw LHS, RHS)
bool InstCombiner::WillNotOverflowUnsignedMul(Value *LHS, Value *RHS,
Instruction *CxtI) {
// Multiplying n * m significant bits yields a result of n + m significant
// bits. If the total number of significant bits does not exceed the
// result bit width (minus 1), there is no overflow.
// This means if we have enough leading zero bits in the operands
// we can guarantee that the result does not overflow.
// Ref: "Hacker's Delight" by Henry Warren
unsigned BitWidth = LHS->getType()->getScalarSizeInBits();
APInt LHSKnownZero(BitWidth, 0);
APInt RHSKnownZero(BitWidth, 0);
APInt TmpKnownOne(BitWidth, 0);
computeKnownBits(LHS, LHSKnownZero, TmpKnownOne, 0, CxtI);
computeKnownBits(RHS, RHSKnownZero, TmpKnownOne, 0, CxtI);
// Note that underestimating the number of zero bits gives a more
// conservative answer.
unsigned ZeroBits = LHSKnownZero.countLeadingOnes() +
RHSKnownZero.countLeadingOnes();
// First handle the easy case: if we have enough zero bits there's
// definitely no overflow.
if (ZeroBits >= BitWidth)
return true;
// There is an ambiguous cases where there can be no overflow:
// ZeroBits == BitWidth - 1
// However, determining overflow requires calculating the sign bit of
// LHS * RHS/2.
return false;
}
Instruction *InstCombiner::visitMul(BinaryOperator &I) {
bool Changed = SimplifyAssociativeOrCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@ -380,6 +413,11 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
I.setHasNoSignedWrap(true);
}
if (!I.hasNoUnsignedWrap() && WillNotOverflowUnsignedMul(Op0, Op1, &I)) {
Changed = true;
I.setHasNoUnsignedWrap(true);
}
return Changed ? &I : nullptr;
}

View File

@ -148,7 +148,7 @@ define %ov.result.32 @smultest1_nsw(i32 %a, i32 %b) {
%x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
ret %ov.result.32 %x
; CHECK-LABEL: @smultest1_nsw
; CHECK: %x = mul nsw i32 %A, %B
; CHECK: %x = mul nuw nsw i32 %A, %B
; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
; CHECK-NEXT: ret %ov.result.32 %1
}

View File

@ -258,12 +258,24 @@ define i32 @test28(i32 %A) {
define i64 @test29(i31 %A, i31 %B) {
; CHECK-LABEL: @test29(
%C = zext i31 %A to i64
%D = zext i31 %B to i64
%C = sext i31 %A to i64
%D = sext i31 %B to i64
%E = mul i64 %C, %D
ret i64 %E
; CHECK: %[[zext1:.*]] = zext i31 %A to i64
; CHECK-NEXT: %[[zext2:.*]] = zext i31 %B to i64
; CHECK-NEXT: %[[mul:.*]] = mul nsw i64 %[[zext1]], %[[zext2]]
; CHECK: %[[sext1:.*]] = sext i31 %A to i64
; CHECK-NEXT: %[[sext2:.*]] = sext i31 %B to i64
; CHECK-NEXT: %[[mul:.*]] = mul nsw i64 %[[sext1]], %[[sext2]]
; CHECK-NEXT: ret i64 %[[mul]]
}
define i64 @test30(i32 %A, i32 %B) {
; CHECK-LABEL: @test30(
%C = zext i32 %A to i64
%D = zext i32 %B to i64
%E = mul i64 %C, %D
ret i64 %E
; CHECK: %[[zext1:.*]] = zext i32 %A to i64
; CHECK-NEXT: %[[zext2:.*]] = zext i32 %B to i64
; CHECK-NEXT: %[[mul:.*]] = mul nuw i64 %[[zext1]], %[[zext2]]
; CHECK-NEXT: ret i64 %[[mul]]
}