-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Remove i128
and u128
from improper_ctypes_definitions
#137306
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
Remove i128
and u128
from improper_ctypes_definitions
#137306
Conversation
rustbot has assigned @petrochenkov. Use |
I may be misunderstanding, but it seems like rustc is removing the fixes from the data layout string when it detects LLVM < 20, so unless that's changed to not remove the 128-bit layout from the layout string, rustc would still be broken on LLVM < 20: rust/compiler/rustc_codegen_llvm/src/context.rs Lines 168 to 190 in 6d3c050
|
All the sizes and alignments of While 32-bit platforms don't support
Additionally, the Clang documentation states:
|
ideally x86-64 would fix its broken ABIs so |
The alignment is only removed when passing the layout to LLVM, so this will only matter if LLVM uses the alignment itself for e.g. low-level function call ABI details. I'm not aware of any cases that this happens for the affected targets, but I haven't looked into it in depth so it's possible there are cases where it matters. |
I would expect i128 arguments that are passed on the stack to be aligned to 16 bytes with the fix and to be aligned to 4 or 8 bytes without the fix. This changes the offset where the argument is passed and thus affects the ABI. |
Given the fact that i128 maps to __int128, but not _BitInt(128) on x86_64, I don't think that mapping it to _BitInt(128) on other platforms is a good idea. I think it would be preferable to treat i128 as not a proper FFI type on platforms that do not actually specify an ABI for __int128. |
Could not assign reviewer from: |
r? @RalfJung |
Sorry, I don't have the low level ABI / LLVM knowledge to review this.
r? @nikic
|
I don't actually think this will be an easy decision. |
I've just checked; 64-bit PowerPC, 64-bit MIPS and 64-bit SPARC all appear to only align i128 to 8 bytes when it is passed as an argument on the stack, even with LLVM 20 (this is consistent with the PowerPC64 ELFv2 ABI specification). |
This FIXME does not seem to be addressed for 64-bit Power: rust/compiler/rustc_target/src/callconv/powerpc64.rs Lines 1 to 3 in a18bd8a
|
Reminder, once the PR becomes ready for a review, use |
To be clear; this PR removes the lint on all targets and does not add a check against a list of known good/problematic targets. Is that what is desired, or is there still interest in the target-specific lint? I think it would be a good idea to update the |
Having looked back over the minutes from our call, my read and recollection is that we were OK with doing this without the target-specific check, so this should be OK to go forward just with the rebase and with the documentation. The theme of our conversation was that it's not worth linting on this any longer if it's working well enough on the platforms with which people are actually likely to use this. We were OK if the lint had some false negatives. @tgross35 and I talked this over just now and double checked some other details. One thing we discussed is that if
Good idea. |
ce734ba
to
8d82555
Compare
☔ The latest upstream changes (presumably #141717) made this pull request unmergeable. Please resolve the merge conflicts. |
Rust's 128-bit integers have historically been incompatible with C [1]. However, there have been a number of changes in Rust and LLVM that mean this is no longer the case: * Incorrect alignment of `i128` on x86 [1]: adjusting Rust's alignment proposed at rust-lang/compiler-team#683, implemented at rust-lang#116672. * LLVM version of the above: resolved in LLVM, including ABI fix. Present in LLVM18 (our minimum supported version). * Incorrect alignment of `i128` on 64-bit PowerPC, SPARC, and MIPS [2]: Rust's data layouts adjusted at rust-lang#132422, rust-lang#132741, rust-lang#134115. * LLVM version of the above: done in LLVM 20 llvm/llvm-project#102783. * Incorrect return convention of `i128` on Windows: adjusted to match GCC and Clang at rust-lang#134290. At [3], the lang team considered it acceptable to remove `i128` from `improper_ctypes_definitions` if the LLVM version is known to be compatible. Time has elapsed since then and we have dropped support for LLVM versions that do not have the x86 fixes, meaning a per-llvm-version lint should no longer be necessary. The PowerPC, SPARC, and MIPS changes only came in LLVM 20 but since Rust's datalayouts have also been updated to match, we will be using the correct alignment regardless of LLVM version. `repr(i128)` was added to this lint in [4], but is also removed here. Part of the decision is that `i128` should match `__int128` in C on platforms that provide it, which documentation is updated to indicate. We will not guarantee that `i128` matches `_BitInt(128)` since that can be different from `__int128`. Some platforms (usually 32-bit) do not provide `__int128`; if any ABIs are extended in the future to define it, we will need to make sure that our ABI matches. Closes: rust-lang#134288 Closes: rust-lang#128950 [1]: rust-lang#54341 [2]: rust-lang#128950 [3]: rust-lang/lang-team#255 (comment) [4]: rust-lang#138282
8d82555
to
0cba7fb
Compare
Rebased. @workingjubilee I think this mostly just needs an ack from you regarding the new documentation; the rest is pretty straightforward. |
Thank you, apologies for the latency. This looks good to ship. @bors r+ rollup |
@bors r=traviscross,workingjubilee |
💡 This pull request was already approved, no need to approve it again.
|
Rollup of 8 pull requests Successful merges: - #136687 (Improve the documentation of `Display` and `FromStr`, and their interactions) - #137306 (Remove `i128` and `u128` from `improper_ctypes_definitions`) - #138699 (build dist for x86_64-pc-solaris and sparcv9-sun-solaris) - #141250 (add s390x z17 target features) - #141467 (make `OsString::new` and `PathBuf::new` unstably const) - #141871 (index: add method for checking range on DenseBitSet) - #141888 (Use non-2015 edition paths in tests that do not test for their resolution) - #142000 (bootstrap: don't symlink source dir into stage0 sysroot) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of #137306 - tgross35:remove-i128-u128-improper-ctypes, r=traviscross,workingjubilee Remove `i128` and `u128` from `improper_ctypes_definitions` Rust's 128-bit integers have historically been incompatible with C [1]. However, there have been a number of changes in Rust and LLVM that mean this is no longer the case: * Incorrect alignment of `i128` on x86 [1]: adjusting Rust's alignment proposed at rust-lang/compiler-team#683, implemented at #116672. * LLVM version of the above: resolved in LLVM, including ABI fix. Present in LLVM18 (our minimum supported version). * Incorrect alignment of `i128` on 64-bit PowerPC, SPARC, and MIPS [2]: Rust's data layouts adjusted at #132422, #132741, #134115. * LLVM version of the above: done in LLVM 20 llvm/llvm-project#102783. * Incorrect return convention of `i128` on Windows: adjusted to match GCC and Clang at #134290. At rust-lang/lang-team#255 (comment), the lang team considered it acceptable to remove `i128` from `improper_ctypes_definitions` if the LLVM version is known to be compatible. Time has elapsed since then and we have dropped support for LLVM versions that do not have the x86 fixes, meaning a per-llvm-version lint should no longer be necessary. The PowerPC, SPARC, and MIPS changes only came in LLVM 20 but since Rust's datalayouts have also been updated to match, we will be using the correct alignment regardless of LLVM version. `repr(i128)` was added to this lint in #138282, but is also removed here. Part of the decision is that `i128` should match `__int128` in C on platforms that provide it, which documentation is updated to indicate. We will not guarantee that `i128` matches `_BitInt(128)` since that can be different from `__int128`. Some platforms (usually 32-bit) do not provide `__int128`; if any ABIs are extended in the future to define it, we will need to make sure that our ABI matches. Closes: #134288 [1]: #54341 [2]: #128950
Rollup of 8 pull requests Successful merges: - rust-lang/rust#136687 (Improve the documentation of `Display` and `FromStr`, and their interactions) - rust-lang/rust#137306 (Remove `i128` and `u128` from `improper_ctypes_definitions`) - rust-lang/rust#138699 (build dist for x86_64-pc-solaris and sparcv9-sun-solaris) - rust-lang/rust#141250 (add s390x z17 target features) - rust-lang/rust#141467 (make `OsString::new` and `PathBuf::new` unstably const) - rust-lang/rust#141871 (index: add method for checking range on DenseBitSet) - rust-lang/rust#141888 (Use non-2015 edition paths in tests that do not test for their resolution) - rust-lang/rust#142000 (bootstrap: don't symlink source dir into stage0 sysroot) r? `@ghost` `@rustbot` modify labels: rollup
Rust's 128-bit integers have historically been incompatible with C 1. However, there have been a number of changes in Rust and LLVM that mean this is no longer the case:
i128
on x86 1: adjusting Rust's alignment proposed at Set alignment ofi128
to 128 bits for x86 compiler-team#683, implemented at LLVM 18 x86 data layout update #116672.i128
on 64-bit PowerPC, SPARC, and MIPS 2: Rust's data layouts adjusted at llvm: Match new LLVM 128-bit integer alignment on sparc #132422, Update mips64 data layout to match LLVM 20 change #132741, rustc_target: ppc64 target string fixes for LLVM 20 #134115.i128
doesn't match Clang's alignment of__int128_t
on 64-bit PowerPC, 64-bit SPARC and 64-bit MIPS llvm/llvm-project#102783.i128
on Windows: adjusted to match GCC and Clang at Windows x86: Change i128 to return via the vector ABI #134290.At rust-lang/lang-team#255 (comment), the lang team considered it acceptable to remove
i128
fromimproper_ctypes_definitions
if the LLVM version is known to be compatible. Time has elapsed since then and we have dropped support for LLVM versions that do not have the x86 fixes, meaning a per-llvm-version lint should no longer be necessary. The PowerPC, SPARC, and MIPS changes only came in LLVM 20 but since Rust's datalayouts have also been updated to match, we will be using the correct alignment regardless of LLVM version.repr(i128)
was added to this lint in #138282, but is also removed here.Part of the decision is that
i128
should match__int128
in C on platforms that provide it, which documentation is updated to indicate. We will not guarantee thati128
matches_BitInt(128)
since that can be different from__int128
. Some platforms (usually 32-bit) do not provide__int128
; if any ABIs are extended in the future to define it, we will need to make sure that our ABI matches.Closes: #134288