compiler-builtins
compiler-builtins copied to clipboard
AEABI functions must handle division by 0 properly.
Rust won't call an AEABI division function with a divide by 0, but other code compiled into the same program (eg: C code) might end up calling an AEABI function with a divide by 0.
Right now, zero_div_fn just makes the division by zero an unreachable_unchecked!()
, which puts us slightly out of spec with what the AEABI division functions are supposed to do.
This is a low-priority bug, but should be handled eventually.
The AEABI spec seems to require returning the same values as __aeabi_idiv0
and __aeabi_ldiv0
upon division by 0, which seem to either trap or return 0, though it also seems to accept returning a given parameter.
The spec also suggests for fused divmods that they either return "infinity" and 0, or 0 and the numerator.
It could also be worth mentioning RISC-V's behavior since it gives explicit division by 0 behavior, namely that it gives -1 as the quotient and the numerator as the remainder for both signed and unsigned division.
As a math enthusiast, my suggestion would be to preserve the behavior of n = (n / d) * d + (n % d). When d = 0, it becomes n = (...) * 0 + (n % 0) = n % 0, which is the behavior used by RISC-V and was one of the suggestions from AEABI, though isn't preserved by the other suggestion. For the quotient, -1 (aka 2N - 1), 0, 2N-1 - 1, and -2N-1 could all have arguments made for them.
Even though Rust code will never generate divisions by 0 unless using core::intrinsics::unchecked_div
, I agree that there's value in having a defined return value for code that does end up calling into it for one reason or another, especially when the alternative is undefined behavior.
A first step could be to make zero_div_fn
take an integer parameter of the numerator and then return a tuple of the chosen quotient and remainder values, but retain the current behavior by coercing the never
value from unreachable
.