-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
i128 and u128 support #37900
i128 and u128 support #37900
Conversation
r? @aturon (rust_highfive has picked a reviewer for you, use r? to override) |
|
||
//! The 128-bit signed integer type. | ||
//! | ||
//! *[See also the `i128` primitive type](../../std/primitive.i128.html).* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should maybe be:
[See also the `i128` primitive type](../primitive.i128.html)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frewsxcv I think this wouldn't work. The other integer primitive types link via ../../std/primitive.$name.html
as well, and I can't see generated doc files for them in libcore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the problem is that the primitive.i128.html isn't being generated at all so changing this won't help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ollie27 yes, that is consistent with my observations, I can find primitive.i64.html
at the linked path, but none for i128.
By the looks of it the files won't be generated. You'll need to add entries to |
☔ The latest upstream changes (presumably #37824) made this pull request unmergeable. Please resolve the merge conflicts. |
cc @rust-lang/compiler |
Okay, running on 32 bit into a linker error of the form:
Apparently the I'm not sure whether or not I should panic here, and how to fix the linker issue if I should indeed panic. Setting panic=abort for the libcompiler_builtin crate does not remove the panic invocations for some reason, nor the linker failure... |
@est31 |
☔ The latest upstream changes (presumably #37487) made this pull request unmergeable. Please resolve the merge conflicts. |
The approach we've used so far in compiler-builtins is to use explicit wrapping operations everywhere. Given that we're mostly translating C code it may make sense to just use Using the cc @japaric |
Progress update: I've been able to eliminate the linker errors by substituting the operations that could fail with I've right now arrived at debugging the functionality of the actual intrinsics themselves... Right now the failure is with the i128 unit tests, when parsing the literals for very large integers, apparently it overflows which it shouldn't. |
☔ The latest upstream changes (presumably #37890) made this pull request unmergeable. Please resolve the merge conflicts. |
match a.signum() { | ||
1 => u128_as_f64(a.abs() as u128_), | ||
0 => 0.0, | ||
-1 => -u128_as_f64(a.abs() as u128_), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a.abs() as u128_
This abs might be dangerous. Namely, the i128::min_value().abs()
cannot be represented in i128 so it ought to panic, just like the i64 variation of the same does:
i64::min_value().abs()
// thread 'main' panicked at 'attempt to negate with overflow', ../src/libcore/num/mod.rs:1207
// note: Run with `RUST_BACKTRACE=1` for a backtrace.
We might want some helper like abs : i128 -> u128
or some such for use here. Similar note may apply to other uses of abs
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, will do that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't really work well for __muloti4
as you have to negate the value, but I've changed it everywhere else. For __muloti4
its no big deal either way as we already check it manually beforehand. To make sure that there is really no panic (LLVM may remove the call but it may not, which then will lead to a linker error later on) I've made a non panicking iabs
method
Okay, the PR is ready for review. I've finished the work on intrinsics and wouldn't know of anything broken or which needs to be done. The tests succeed for both 64 bit and 32 bit platforms. |
I am quite happy for the future availability of 128 bit numbers in Rust. The "mul_mod" operation is used by "pow_mod" (modular pow), that is sufficiently common:
If you have 128 bits you can perform the 64 bit mul_mod using 128 bit values, but it's more efficient to use the "divq" instruction and work on 64 bit values. And you can probably perform the 128 bit mul_mod more efficiently without 256 bit numbers. Are you going to support those mul_mod (or something similar), or should this enhancement request be moved elsewhere? |
@leonardo-m I think providing modular pow is outside of the scope of this PR. Feel free to open an issue or RFC at https://github.com/rust-lang/rfcs . Also, you might be interested in https://github.com/rust-num/num |
My suggestion was about mul_mod (not about pow_mod), and I think it needs a low-level implementation with intrinsics or asm to be efficient. I'll probably open an issue here. |
r? @eddyb (feel free to transfer) |
7115923
to
76784e1
Compare
just as ceil(log10(2^64)) == 20
Current stage0 with version "1.14.0-beta.1 (d4aea2d 2016-11-15)" suffers from issue 37686. You can confirm this on master by running ./x.py test --stage 0 src/test/run-pass --test-args 37686 Add this workaround until there is a fix. No idea how it works, but it does work.
The check inside compiler-rt file int_types.h to #define CRT_HAS_128BIT looks like: #if (defined(__LP64__) || defined(__wasm__)) && \ !(defined(__mips__) && defined(__clang__)) #define CRT_HAS_128BIT #endif Windows uses LLP64 instead of LP64, so it doesn't ship with the C based intrinsics. Also, add libcompiler_builtins to the list of crates that may have platform specific checks (like the ones we just added).
* shift so that no panics are generated (otherwise results in linker error) * no_std as insurance to not get into issues with errors like "cannot satisfy dependencies so `rustc_i128` only shows up once" (pure guessing here, but it doesn't hurt...)
There was a linker error on 32 bit platforms with optimisations turned off, complaining that there was an undefined reference to "rust_eh_personality", when compiling the rustc_const_math as stage1 artifact. Apparently the compiler_builtins crate includes a call to "rust_eh_personality". If compiled for 64 bits, this call doesn't appear, which explains why the linker error only happens on 32 bit platforms, and optimisations will get it removed on 32 bit as well. There were two origins of the call: 1. A for loop where apparently the compiler wasn't sure whether next() could panic or not, and therefore generated a landing pad for the worst case. The minimal reproducible example is "for _ in 0..sr { }". 2. A default impl of uabs where the compiler apparently wasn't sure either whether iabs() could panic or not. Many thanks to nagisa for contributing the fix. This commit also puts extern "C" to the intrinsics, as this is generally a good thing to do.
Otherwise, we codegen panic calls which create problems with debug assertions turned on.
on suggestion by nagisa.
...this time with the float intrinsics.
Rebased. r? @eddyb |
Keep going! :-) |
Release is close, and this may cause regressions. It'd be better to have it at the start of a release period, not that it gets reverted before release because of the regressions it caused. Gonna reopen once the release is over. |
See #38482 for the continuation |
And #37900 was such a rememberable number too 😢 |
i128 and u128 support Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs. Rebased version of #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue... [plugin-breaking-change] cc #35118 (tracking issue)
Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.
Thanks @nagisa for mentoring this PR!
Some of the problems that were resolved:
Confirm that intrinsics work on 32 bit platforms and fix them if needed
Wait for rustbuild: linker error during 32 bit compilation #37906 to get fixed, so that work on intrinsics can be completed (worked around by merging the PR on my local setup)
Investigate and fix linkcheck failure
[plugin-breaking-change]
cc #35118