Skip to content

[Bits] Use abs(rhs) in getMaxBits for rem_s - #9364

Open
tlively wants to merge 1 commit into
bits-cppfrom
max-bits-rem-s
Open

tlively wants to merge 1 commit into
bits-cppfrom
max-bits-rem-s

Conversation

@tlively

@tlively tlively commented Nov 7, 2026

Copy link
Copy Markdown
Member

Previously, Provider::getMaxBits passed the signed constant divisor directly to ceilLog2 for RemSInt32 and RemSInt64. For negative divisors (other than INT_MIN), converting to unsigned produced a value with the high bit set, causing ceilLog2 to return 32 or 64 and losing precision even when the dividend was known to be non-negative. Take the unsigned absolute value of the divisor before calling ceilLog2 so negative divisors get the same magnitude bit bound as positive ones.

Previously, Provider::getMaxBits passed the signed constant divisor directly to ceilLog2 for RemSInt32 and RemSInt64. For negative divisors (other than INT_MIN), converting to unsigned produced a value with the high bit set, causing ceilLog2 to return 32 or 64 and losing precision even when the dividend was known to be non-negative. Take the unsigned absolute value of the divisor before calling ceilLog2 so negative divisors get the same magnitude bit bound as positive ones.
@tlively
tlively requested a review from a team as a code owner November 7, 2026 03:14
@tlively
tlively requested review from stevenfontanella and removed request for a team November 7, 2026 03:15

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates Provider::getMaxBits in src/ir/bits.cpp to handle negative divisors by calculating their absolute value as unsigned integers before computing ceilLog2. This enables optimizations like folding redundant masks for negative constant divisors, which is verified by the newly added unit and integration tests. The review feedback points out that applying the unary minus operator to unsigned types (e.g., -uint32_t(rhs)) can trigger MSVC warning C4146, potentially breaking builds that treat warnings as errors. It is recommended to use the suggested 0 - uint32_t(rhs) and 0 - uint64_t(rhs) alternatives to avoid this warning.

Comment thread src/ir/bits.cpp
}
auto bitsRight = Index(ceilLog2(c->value.geti32()));
int32_t rhs = c->value.geti32();
uint32_t absRhs = rhs < 0 ? -uint32_t(rhs) : uint32_t(rhs);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Applying the unary minus operator to an unsigned type (e.g., -uint32_t(rhs)) can trigger compiler warnings on MSVC (specifically warning C4146: 'unary minus operator applied to unsigned type, result still unsigned'). Since this codebase is compiled on multiple platforms including Windows with MSVC, and warnings are often treated as errors, this can break the build. Using 0 - uint32_t(rhs) is a safe, warning-free alternative that achieves the same result.

Suggested change
uint32_t absRhs = rhs < 0 ? -uint32_t(rhs) : uint32_t(rhs);
uint32_t absRhs = rhs < 0 ? 0 - uint32_t(rhs) : uint32_t(rhs);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ew no.

Comment thread src/ir/bits.cpp
}
auto bitsRight = Index(ceilLog2(c->value.geti64()));
int64_t rhs = c->value.geti64();
uint64_t absRhs = rhs < 0 ? -uint64_t(rhs) : uint64_t(rhs);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Applying the unary minus operator to an unsigned type (e.g., -uint64_t(rhs)) can trigger compiler warnings on MSVC (specifically warning C4146: 'unary minus operator applied to unsigned type, result still unsigned'). Since this codebase is compiled on multiple platforms including Windows with MSVC, and warnings are often treated as errors, this can break the build. Using 0 - uint64_t(rhs) is a safe, warning-free alternative that achieves the same result.

Suggested change
uint64_t absRhs = rhs < 0 ? -uint64_t(rhs) : uint64_t(rhs);
uint64_t absRhs = rhs < 0 ? 0 - uint64_t(rhs) : uint64_t(rhs);

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant