[llvm] 85378b7 - [KnownBits] Factor out and improve the lowbit computation for {u,s}div
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 6 13:14:21 PDT 2023
Author: Noah Goldstein
Date: 2023-06-06T15:14:10-05:00
New Revision: 85378b7663763e6639123088aa8a82289c62ca0e
URL: https://github.com/llvm/llvm-project/commit/85378b7663763e6639123088aa8a82289c62ca0e
DIFF: https://github.com/llvm/llvm-project/commit/85378b7663763e6639123088aa8a82289c62ca0e.diff
LOG: [KnownBits] Factor out and improve the lowbit computation for {u,s}div
There are some new cases if the division is `exact`:
1: If `TZ(LHS) == TZ(RHS)` then the result is always Odd
2: If `TZ(LHS) > TZ(RHS)` then the `TZ(LHS)-TZ(RHS)` bits of the
result are zero.
Proofs: https://alive2.llvm.org/ce/z/3rAZqF
As well, return zero in known poison cases to be consistent rather
than just working about the bits we are changing.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D150923
Added:
Modified:
llvm/lib/Support/KnownBits.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index ce2813e2fb3a3..097c22d33dd12 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -748,6 +748,42 @@ KnownBits KnownBits::mulhu(const KnownBits &LHS, const KnownBits &RHS) {
return mul(WideLHS, WideRHS).extractBits(BitWidth, BitWidth);
}
+static KnownBits divComputeLowBit(KnownBits Known, const KnownBits &LHS,
+ const KnownBits &RHS, bool Exact) {
+
+ if (!Exact)
+ return Known;
+
+ // If LHS is Odd, the result is Odd no matter what.
+ // Odd / Odd -> Odd
+ // Odd / Even -> Impossible (because its exact division)
+ if (LHS.One[0])
+ Known.One.setBit(0);
+
+ int MinTZ =
+ (int)LHS.countMinTrailingZeros() - (int)RHS.countMaxTrailingZeros();
+ int MaxTZ =
+ (int)LHS.countMaxTrailingZeros() - (int)RHS.countMinTrailingZeros();
+ if (MinTZ >= 0) {
+ // Result has at least MinTZ trailing zeros.
+ Known.Zero.setLowBits(MinTZ);
+ if (MinTZ == MaxTZ) {
+ // Result has exactly MinTZ trailing zeros.
+ Known.One.setBit(MinTZ);
+ }
+ } else if (MaxTZ < 0) {
+ // Poison Result
+ Known.setAllZero();
+ }
+
+ // In the KnownBits exhaustive tests, we have poison inputs for exact values
+ // a LOT. If we have a conflict, just return all zeros.
+ if (Known.hasConflict())
+ Known.setAllZero();
+
+ return Known;
+}
+
KnownBits KnownBits::sdiv(const KnownBits &LHS, const KnownBits &RHS,
bool Exact) {
// Equivalent of `udiv`. We must have caught this before it was folded.
@@ -801,20 +837,7 @@ KnownBits KnownBits::sdiv(const KnownBits &LHS, const KnownBits &RHS,
}
}
- if (Exact) {
- // Odd / Odd -> Odd
- if (LHS.One[0] && RHS.One[0]) {
- Known.Zero.clearBit(0);
- Known.One.setBit(0);
- }
- // Even / Odd -> Even
- else if (LHS.Zero[0] && RHS.One[0]) {
- Known.One.clearBit(0);
- Known.Zero.setBit(0);
- }
- // Odd / Even -> impossible
- // Even / Even -> unknown
- }
+ Known = divComputeLowBit(Known, LHS, RHS, Exact);
assert(!Known.hasConflict() && "Bad Output");
return Known;
@@ -843,20 +866,7 @@ KnownBits KnownBits::udiv(const KnownBits &LHS, const KnownBits &RHS,
unsigned LeadZ = MaxRes.countLeadingZeros();
Known.Zero.setHighBits(LeadZ);
- if (Exact) {
- // Odd / Odd -> Odd
- if (LHS.One[0] && RHS.One[0]) {
- Known.Zero.clearBit(0);
- Known.One.setBit(0);
- }
- // Even / Odd -> Even
- else if (LHS.Zero[0] && RHS.One[0]) {
- Known.One.clearBit(0);
- Known.Zero.setBit(0);
- }
- // Odd / Even -> impossible
- // Even / Even -> unknown
- }
+ Known = divComputeLowBit(Known, LHS, RHS, Exact);
assert(!Known.hasConflict() && "Bad Output");
return Known;
More information about the llvm-commits
mailing list