[llvm] [AMDGPU] Avoid errors with 23-bit division and remainder. (PR #202753)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 10 03:02:57 PDT 2026
================
@@ -1057,28 +1056,28 @@ unsigned AMDGPUCodeGenPrepareImpl::getDivNumBits(BinaryOperator &I, Value *Num,
// The fractional part of a float is enough to accurately represent up to
// a 24-bit signed integer.
-Value *AMDGPUCodeGenPrepareImpl::expandDivRem24(IRBuilder<> &Builder,
+Value *AMDGPUCodeGenPrepareImpl::expandDivRem23(IRBuilder<> &Builder,
BinaryOperator &I, Value *Num,
Value *Den, bool IsDiv,
bool IsSigned) const {
- unsigned DivBits = getDivNumBits(I, Num, Den, 24, IsSigned);
+ unsigned DivBits = getDivNumBits(I, Num, Den, 23, IsSigned);
// v_rcp_f32(float(X)) can have an error of 1 ulp.
- // This can cause expandDivRem24Impl to sometimes calculate Y/X incorrectly
- // when abs(Y)>0x800000.
+ // This can cause expandDivRem23Impl to sometimes calculate Y/X incorrectly
+ // when:
+ // Y = (0x7FFFFF/X)*(X-0)-1
+ // There are no problems with:
+ // Y = (0x7FFFFF/X)*(X-0)-2
+ // Y = (0x7FFFFF/X)*(X-1)-1
// For example,
- // (0xbf2758/0xbf2759) erroneously produces 1 instead of 0.
- // (0xe3170d/0x000c32) erroneously produces 4767 instead of 4766.
- //
- // Note that for DivBits==24 && IsSigned, Y is in the range
- // [-0x800000:0x7FFFFF]. abs(Y) is at most
- // 0x800000 so it cannot hit this issue.
- if (DivBits > (IsSigned ? 24 : 23))
+ // (0x7FF6D3/0x000FE7) erroneously produces 2060 instead of 2059.
+ // (0x7FF8F5/0x007EFB) erroneously produces 258 instead of 257.
----------------
arsenm wrote:
I don't understand the comment here. It's sometimes wrong if the conditions aren't right? but they are checked?
https://github.com/llvm/llvm-project/pull/202753
More information about the llvm-commits
mailing list