[PATCH] D150923: [KnownBits] Factor out and improve the lowbit computation for {u,s}div
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu May 18 17:38:47 PDT 2023
goldstein.w.n created this revision.
goldstein.w.n added reviewers: foad, nikic, RKSimon.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
goldstein.w.n requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
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.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D150923
Files:
llvm/lib/Support/KnownBits.cpp
Index: llvm/lib/Support/KnownBits.cpp
===================================================================
--- llvm/lib/Support/KnownBits.cpp
+++ llvm/lib/Support/KnownBits.cpp
@@ -536,6 +536,39 @@
return mul(WideLHS, WideRHS).extractBits(BitWidth, BitWidth);
}
+static KnownBits divComputeLowBit(const KnownBits &Known, const KnownBits &LHS,
+ const KnownBits &RHS, bool Exact) {
+
+ if (!Exact)
+ return Known;
+
+ // If we already have a constant, we can skip this.
+ unsigned BitWidth = LHS.getBitWidth();
+ KnownBits KnownOut(Known);
+ unsigned LHSMinTZ = LHS.countMinTrailingZeros();
+ assert(LHSMinTZ < BitWidth && "We should have already handled Zero LHS");
+
+ // Odd / X -> Odd
+ // X must be odd, otherwise the div is not exact.
+ // EvenX / EvenY [if TZ(X) == TZ(Y)] -> Odd
+ if (LHS.One[LHSMinTZ] &&
+ (LHSMinTZ == 0 ||
+ (RHS.countMinTrailingZeros() == LHSMinTZ && RHS.One[LHSMinTZ])))
+ KnownOut.One.setBit(0);
+
+ // For exact TZ(LHS) - TZ(RHS) bits must all be zero.
+ // This also covers Even / Odd -> Even
+ if (LHSMinTZ > RHS.countMaxTrailingZeros())
+ KnownOut.Zero.setLowBits(LHSMinTZ - RHS.countMaxTrailingZeros());
+
+ // In the KnownBits exhaustive tests, we have poison inputs for exact values
+ // a LOT. If we have a conflict, just return all zeros.
+ if (KnownOut.hasConflict())
+ KnownOut.setAllZero();
+
+ return KnownOut;
+}
+
KnownBits KnownBits::sdiv(const KnownBits &LHS, const KnownBits &RHS,
bool Exact) {
// Equivalent of `udiv`. We must have caught this before it was folded.
@@ -599,20 +632,7 @@
}
}
- 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;
@@ -640,20 +660,7 @@
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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150923.523616.patch
Type: text/x-patch
Size: 2707 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230519/40867423/attachment.bin>
More information about the llvm-commits
mailing list