diff options
Diffstat (limited to 'llvm/lib/Support/KnownBits.cpp')
| -rw-r--r-- | llvm/lib/Support/KnownBits.cpp | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 554e3248524c..8e154067abc0 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -420,11 +420,19 @@ KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS, assert((!SelfMultiply || (LHS.One == RHS.One && LHS.Zero == RHS.Zero)) && "Self multiplication knownbits mismatch"); - // Compute a conservative estimate for high known-0 bits. - unsigned LHSLeadZ = LHS.countMinLeadingZeros(); - unsigned RHSLeadZ = RHS.countMinLeadingZeros(); - unsigned LeadZ = std::max(LHSLeadZ + RHSLeadZ, BitWidth) - BitWidth; - assert(LeadZ <= BitWidth && "More zeros than bits?"); + // Compute the high known-0 bits by multiplying the unsigned max of each side. + // Conservatively, M active bits * N active bits results in M + N bits in the + // result. But if we know a value is a power-of-2 for example, then this + // computes one more leading zero. + // TODO: This could be generalized to number of sign bits (negative numbers). + APInt UMaxLHS = LHS.getMaxValue(); + APInt UMaxRHS = RHS.getMaxValue(); + + // For leading zeros in the result to be valid, the unsigned max product must + // fit in the bitwidth (it must not overflow). + bool HasOverflow; + APInt UMaxResult = UMaxLHS.umul_ov(UMaxRHS, HasOverflow); + unsigned LeadZ = HasOverflow ? 0 : UMaxResult.countLeadingZeros(); // The result of the bottom bits of an integer multiply can be // inferred by looking at the bottom bits of both operands and |
