[Cross-platform] Bug fix for #39646 regarding downsizing of division operation
Summary
This merge request fixes the issue raised over at #39646 (closed) where a nested division operation inside a bitwise AND operation was incorrectly truncated and caused incorrect results if the numerator was greater than or equal to 2^32.
System
- Processor architecture: x86_64, AArch64
What is the current bug behavior?
With an expression of the form Result := (Input div 100000000) and $FF
, with Input of type QWord and Result of type SmallInt, the division would produce an incorrect quotient if Input was >= 2^32 due to the compiler truncating the operands to a LongWord.
What is the behavior after applying this patch?
Results from nested DIV and MOD operations inside bitwise AND operations should now be correct.
Additional Notes
- See #39646 (closed) for more information.
- The root of this bug was the special handling of bitwise AND operations when it comes to using internal typecasting to downsize integer operations, specifically the nested
docheckremoveinttypeconvs
in thecheckremovebiginttypeconvs
subroutine, in the ncnv unit. If any of the operands in the AND node was expanded at an earlier stage, the compiler tries to shrink them down again. Nested DIV and MOD operations, much like SHR nodes already, are exempt from this process. - From the above, the bug only appears to fully manifest in situations where the fast division algorithm is implemented on 64-bit platforms, where divisions by a constant are converted into a high multiplication and bit shift. As a result, this bug also gets triggered on AArch64.
Edited by J. Gareth "Kit" Moreton