Skip to content

Commit

Permalink
[KnownBits] Merge the minimum shift amount and leading/trailing shift…
Browse files Browse the repository at this point in the history
… value bits handling.

By starting with the source shift value minimum leading/trailing bits, we can then add the minimum known shift amount to more accurately predict the minimum leading/trailing bits of the result.

This is currently only covered by the exhaustive unit tests in KnownBitsTests.cpp, but will help with some of the regressions encountered in D90479 (PR44526).
  • Loading branch information
RKSimon committed Nov 13, 2020
1 parent 46ca880 commit 27e9f0f
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions llvm/lib/Support/KnownBits.cpp
Expand Up @@ -160,12 +160,16 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
return Known;
}

// No matter the shift amount, the trailing zeros will stay zero.
unsigned MinTrailingZeros = LHS.countMinTrailingZeros();

// Minimum shift amount low bits are known zero.
if (RHS.getMinValue().ult(BitWidth))
Known.Zero.setLowBits(RHS.getMinValue().getZExtValue());
if (RHS.getMinValue().ult(BitWidth)) {
MinTrailingZeros += RHS.getMinValue().getZExtValue();
MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
}

// No matter the shift amount, the trailing zeros will stay zero.
Known.Zero.setLowBits(LHS.countMinTrailingZeros());
Known.Zero.setLowBits(MinTrailingZeros);
return Known;
}

Expand All @@ -183,12 +187,16 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
return Known;
}

// No matter the shift amount, the leading zeros will stay zero.
unsigned MinLeadingZeros = LHS.countMinLeadingZeros();

// Minimum shift amount high bits are known zero.
if (RHS.getMinValue().ult(BitWidth))
Known.Zero.setHighBits(RHS.getMinValue().getZExtValue());
if (RHS.getMinValue().ult(BitWidth)) {
MinLeadingZeros += RHS.getMinValue().getZExtValue();
MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
}

// No matter the shift amount, the leading zeros will stay zero.
Known.Zero.setHighBits(LHS.countMinLeadingZeros());
Known.Zero.setHighBits(MinLeadingZeros);
return Known;
}

Expand All @@ -204,8 +212,24 @@ KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
return Known;
}

// TODO: Minimum shift amount high bits are known sign bits.
// TODO: No matter the shift amount, the leading sign bits will stay.
// No matter the shift amount, the leading sign bits will stay.
unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
unsigned MinLeadingOnes = LHS.countMinLeadingOnes();

// Minimum shift amount high bits are known sign bits.
if (RHS.getMinValue().ult(BitWidth)) {
if (MinLeadingZeros) {
MinLeadingZeros += RHS.getMinValue().getZExtValue();
MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
}
if (MinLeadingOnes) {
MinLeadingOnes += RHS.getMinValue().getZExtValue();
MinLeadingOnes = std::min(MinLeadingOnes, BitWidth);
}
}

Known.Zero.setHighBits(MinLeadingZeros);
Known.One.setHighBits(MinLeadingOnes);
return Known;
}

Expand Down

0 comments on commit 27e9f0f

Please sign in to comment.