Skip to content

Commit 27e9f0f

Browse files
committed
[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).
1 parent 46ca880 commit 27e9f0f

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

llvm/lib/Support/KnownBits.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,16 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
160160
return Known;
161161
}
162162

163+
// No matter the shift amount, the trailing zeros will stay zero.
164+
unsigned MinTrailingZeros = LHS.countMinTrailingZeros();
165+
163166
// Minimum shift amount low bits are known zero.
164-
if (RHS.getMinValue().ult(BitWidth))
165-
Known.Zero.setLowBits(RHS.getMinValue().getZExtValue());
167+
if (RHS.getMinValue().ult(BitWidth)) {
168+
MinTrailingZeros += RHS.getMinValue().getZExtValue();
169+
MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
170+
}
166171

167-
// No matter the shift amount, the trailing zeros will stay zero.
168-
Known.Zero.setLowBits(LHS.countMinTrailingZeros());
172+
Known.Zero.setLowBits(MinTrailingZeros);
169173
return Known;
170174
}
171175

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

190+
// No matter the shift amount, the leading zeros will stay zero.
191+
unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
192+
186193
// Minimum shift amount high bits are known zero.
187-
if (RHS.getMinValue().ult(BitWidth))
188-
Known.Zero.setHighBits(RHS.getMinValue().getZExtValue());
194+
if (RHS.getMinValue().ult(BitWidth)) {
195+
MinLeadingZeros += RHS.getMinValue().getZExtValue();
196+
MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
197+
}
189198

190-
// No matter the shift amount, the leading zeros will stay zero.
191-
Known.Zero.setHighBits(LHS.countMinLeadingZeros());
199+
Known.Zero.setHighBits(MinLeadingZeros);
192200
return Known;
193201
}
194202

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

207-
// TODO: Minimum shift amount high bits are known sign bits.
208-
// TODO: No matter the shift amount, the leading sign bits will stay.
215+
// No matter the shift amount, the leading sign bits will stay.
216+
unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
217+
unsigned MinLeadingOnes = LHS.countMinLeadingOnes();
218+
219+
// Minimum shift amount high bits are known sign bits.
220+
if (RHS.getMinValue().ult(BitWidth)) {
221+
if (MinLeadingZeros) {
222+
MinLeadingZeros += RHS.getMinValue().getZExtValue();
223+
MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
224+
}
225+
if (MinLeadingOnes) {
226+
MinLeadingOnes += RHS.getMinValue().getZExtValue();
227+
MinLeadingOnes = std::min(MinLeadingOnes, BitWidth);
228+
}
229+
}
230+
231+
Known.Zero.setHighBits(MinLeadingZeros);
232+
Known.One.setHighBits(MinLeadingOnes);
209233
return Known;
210234
}
211235

0 commit comments

Comments
 (0)