Add workaround for 128-bit integer division/modulo on Windows#11551
Conversation
|
Is this a known LLVM bug? Can we fix LLVM to remove this workaround at some point? |
|
We still have to keep this workaround around, guarded behind |
|
But those are stdlib functions, we don't need libllvm for that. The comparsion would be with the LLVM version that the compiler was built with, which is |
|
I don't understand the state of this PR. Is the last comment by @straight-shoota agreed upon and requires changes? |
|
Apart from that there is also the issue that optimizations normally available to the corresponding LLVM instructions might not be available, instead they are optimized like normal function calls. Personally I'd like some more feedback from core members before deciding where to go with this. |
There was a problem hiding this comment.
The current approach actually looks fine to me. If others think it's not perfect, do you see any issue with merging this first (and have int128 actually working) and figuring out the exact correct way later? As I understand, this approach doesn't bring any baggage that can't be changed at a later point. In fact, it cleans things up almost as much.
What's the concern with failing at runtime? Isn't it specific to empty prelude (i.e. pretty much just Crystal specs) and to int128 math and to Windows? Which is exceedingly rare.
Merging this would save a lot of work marking specs as pending in #11571 (not to mention possibly even blocking it outright).
And anyway it would be very good to have int128 support on all platforms even if Windows is just a preview.
LLVM does not honor the Microsoft x64 ABI when it calls certain compiler-rt functions with 128-bit integer arguments from LLVM instructions, most notably the division and modulo intrinsics (
sdiv,udiv,srem,urem). But now that the required compiler-rt functions are all defined in Crystal, we can make those calls in Crystal directly, as these functions have no ABI issues whether they are defined as defs or global funs.This PR redefines the division and modulo primitive methods as non-primitives that call the respective compiler-rt functions on 64-bit Windows. The added overhead should be very small compared to those actual function bodies. The same calls will still break on an empty prelude, because
crystal/compiler_rtis then not required, and because our ports so far require many definitions fromsrc/int.cr.