1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[KnownBits] Merge the minimum shift amount and leading/trailing shift 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).
This commit is contained in:
Simon Pilgrim 2020-11-13 16:25:44 +00:00
parent 3cd3307a93
commit 88d2ac2817

View File

@ -160,12 +160,16 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
return Known;
}
// Minimum shift amount low bits are known zero.
if (RHS.getMinValue().ult(BitWidth))
Known.Zero.setLowBits(RHS.getMinValue().getZExtValue());
// No matter the shift amount, the trailing zeros will stay zero.
Known.Zero.setLowBits(LHS.countMinTrailingZeros());
unsigned MinTrailingZeros = LHS.countMinTrailingZeros();
// Minimum shift amount low bits are known zero.
if (RHS.getMinValue().ult(BitWidth)) {
MinTrailingZeros += RHS.getMinValue().getZExtValue();
MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
}
Known.Zero.setLowBits(MinTrailingZeros);
return Known;
}
@ -183,12 +187,16 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
return Known;
}
// Minimum shift amount high bits are known zero.
if (RHS.getMinValue().ult(BitWidth))
Known.Zero.setHighBits(RHS.getMinValue().getZExtValue());
// No matter the shift amount, the leading zeros will stay zero.
Known.Zero.setHighBits(LHS.countMinLeadingZeros());
unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
// Minimum shift amount high bits are known zero.
if (RHS.getMinValue().ult(BitWidth)) {
MinLeadingZeros += RHS.getMinValue().getZExtValue();
MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
}
Known.Zero.setHighBits(MinLeadingZeros);
return Known;
}
@ -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;
}