diff options
author | Ramkumar Ramachandra <ramkumar.ramachandra@codasip.com> | 2024-09-27 12:00:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-27 12:00:50 +0100 |
commit | 3fee3e83a8a802cd23e79fbf2f1320bb8f961d0c (patch) | |
tree | 8b0a4d77992fb25a4551deaa562c30db23270bfd /llvm/lib/Support/KnownBits.cpp | |
parent | 5cc64bf60bc04b9315de3c679eb753de4d554a8a (diff) | |
download | llvm-3fee3e83a8a802cd23e79fbf2f1320bb8f961d0c.zip llvm-3fee3e83a8a802cd23e79fbf2f1320bb8f961d0c.tar.gz llvm-3fee3e83a8a802cd23e79fbf2f1320bb8f961d0c.tar.bz2 |
KnownBits: refine srem for high-bits (#109121)
KnownBits::srem does not correctly set the leader zero-bits, omitting
the fact that LHS may be known-negative or known-non-negative. Fix this.
Alive2 proof: https://alive2.llvm.org/ce/z/Ugh-Dq
Diffstat (limited to 'llvm/lib/Support/KnownBits.cpp')
-rw-r--r-- | llvm/lib/Support/KnownBits.cpp | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 8e31e0c..6863c5c 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -1075,9 +1075,13 @@ KnownBits KnownBits::srem(const KnownBits &LHS, const KnownBits &RHS) { // The sign bit is the LHS's sign bit, except when the result of the // remainder is zero. The magnitude of the result should be less than or - // equal to the magnitude of the LHS. Therefore any leading zeros that exist - // in the left hand side must also exist in the result. - Known.Zero.setHighBits(LHS.countMinLeadingZeros()); + // equal to the magnitude of either operand. + if (LHS.isNegative() && Known.isNonZero()) + Known.One.setHighBits( + std::max(LHS.countMinLeadingOnes(), RHS.countMinSignBits())); + else if (LHS.isNonNegative()) + Known.Zero.setHighBits( + std::max(LHS.countMinLeadingZeros(), RHS.countMinSignBits())); return Known; } |