-
Notifications
You must be signed in to change notification settings - Fork 13.9k
rust_for_linux: -Zreg-struct-return commandline flag for X86 (#116973) #130777
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
Conversation
This comment has been minimized.
This comment has been minimized.
ad600b5 to
d5888d4
Compare
This comment has been minimized.
This comment has been minimized.
d5888d4 to
0bb5469
Compare
This comment has been minimized.
This comment has been minimized.
|
cc @ojeda |
0bb5469 to
c8970c5
Compare
|
Some changes occurred in compiler/rustc_codegen_gcc These commits modify compiler targets. |
tests/codegen/reg-struct-return.rs
Outdated
| // reg-struct-return doesn't work for "Rust" calling conv | ||
| // CHECK: { i32, i32 } @f2() | ||
| #[no_mangle] | ||
| pub extern "Rust" fn f2() -> Foo { | ||
| Foo { x: 1, y: 2 } | ||
| } |
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.
Why doesn't it work for the Rust calling convention? Is that what we want? I assume that there's a reason we use this flag, but I don't know whether it's just a question of performance or if it's an important mitigation.
@andyhhp Do you know if this matters?
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.
At technical level, "external" abi's are processed a little in different way (another place in code). It is not a big problem to support the same behavior for "Rust" calling conv, I just need to know if it is required.
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.
Why doesn't it work for the Rust calling convention? Is that what we want? I assume that there's a reason we use this flag, but I don't know whether it's just a question of performance or if it's an important mitigation.
@andyhhp Do you know if this matters?
Rust and C need to agree on how to return >GPR sized values, if this happens to be used in either direction.
Whether that is via some bindings using the Rust calling conventions is something I can't answer.
The use of >GPR sized return values is rare in C because it's irritating to set up. You need a struct/typedef with a fairly precise layout, but the code generation improvements are substantial, hence why they do get used occasionally.
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.
The Rust ABI is not stable. C should not call an extern "Rust" fn. This matters for extern "C" fn and a few others. And reusing this code, tuned for extern "C" and other foreign ABIs, for Rust ABI code? Proved incapable of compiling libcore in #130432.
We're not going to be scope-creeping this PR into extern "Rust". That can be addressed alongside the extensive cleanups of our ABI code that it will require.
c8970c5 to
44fec08
Compare
This comment has been minimized.
This comment has been minimized.
44fec08 to
7e72e24
Compare
|
Cc @vincenzopalazzo who was interested in this. |
7e72e24 to
8413bba
Compare
|
☔ The latest upstream changes (presumably #131458) made this pull request unmergeable. Please resolve the merge conflicts. |
|
I'm not in capacity to review this. |
491526e to
8fedf94
Compare
|
☔ The latest upstream changes (presumably #132079) made this pull request unmergeable. Please resolve the merge conflicts. |
compiler/rustc_ty_utils/src/abi.rs
Outdated
| let is_indirect_not_on_stack = !matches!(arg.layout.abi, Abi::Aggregate { .. }) | ||
| || matches!(arg.mode, PassMode::Indirect { on_stack: false, .. }); | ||
| assert!(is_indirect_not_on_stack, "is_indirect_not_on_stack: {:?}", arg); | ||
|
|
||
| let size = arg.layout.size; | ||
| if !arg.layout.is_unsized() && size <= Pointer(AddressSpace::DATA).size(cx) { | ||
| let ptr_size = Pointer(AddressSpace::DATA).size(cx); | ||
|
|
||
| // In x86 we may return 2x pointer sized struct as i64 | ||
| let reg_struct_return_case = tcx.sess.target.arch == "x86" | ||
| && arg_idx.is_none() | ||
| && tcx.sess.opts.unstable_opts.reg_struct_return | ||
| && abi != SpecAbi::RustIntrinsic; | ||
|
|
||
| if !arg.layout.is_unsized() | ||
| && (size <= ptr_size || (reg_struct_return_case && (size <= 2 * ptr_size))) | ||
| { |
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.
some of this code has moved into rustc_target.
8fedf94 to
f3eef25
Compare
|
Reverted changes for "Rust" calling conv (flag works only for extern "C"-like calling conventions). Added unstable-book record, error about wrong arch and related test. |
tests/codegen/reg-struct-return.rs
Outdated
| #![feature(no_core, lang_items)] | ||
|
|
||
| #[lang = "sized"] | ||
| trait Sized {} | ||
| #[lang = "copy"] | ||
| trait Copy {} |
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.
You can just use //@ add-core-stubs for this now: #130693
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.
We should test this slightly more exhaustively. I'd like to see
- single-field structs, too
- structs with fields that aren't valid for all bitpatterns, like, say,
{ bool, bool, i16 }... I am not aware of a reason it should differ in handling, mind. - oddly-shaped structs that don't exactly match the sizes we're looking for, but are under the 64-bit limit, like e.g.
{ char, bool, u8 } - larger-than-64-bits structs, which obviously shouldn't be changed to integers
f3eef25 to
3e7266f
Compare
3e7266f to
9aab517
Compare
| // ENABLED: double @f15() | ||
| // DISABLED: void @f15(ptr {{.*}}sret | ||
| #[no_mangle] | ||
| pub extern "C" fn f15() -> FooFloat2 { | ||
| FooFloat2 { x: 1.0 } | ||
| } | ||
|
|
||
| // ENABLED: float @f16() | ||
| // DISABLED: void @f16(ptr {{.*}}sret | ||
| #[no_mangle] | ||
| pub extern "C" fn f16() -> FooFloat3 { | ||
| FooFloat3 { x: 1.0 } | ||
| } |
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.
Hrm. Tried to disable float features and the LLVMIR we emit for matching the C ABI on such a "soft float" target didn't undergo a substantial change.
I should probably take a closer look at that later.
|
This should be purely additive: @bors r+ rollup |
… r=workingjubilee rust_for_linux: -Zreg-struct-return commandline flag for X86 (rust-lang#116973) Command line flag `-Zreg-struct-return` for X86 (32-bit) for rust-for-linux. This flag enables the same behavior as the `abi_return_struct_as_int` target spec key. - Tracking issue: rust-lang#116973
…iaskrgr Rollup of 5 pull requests Successful merges: - rust-lang#130777 (rust_for_linux: -Zreg-struct-return commandline flag for X86 (rust-lang#116973)) - rust-lang#133211 (Extend Miri to correctly pass mutable pointers through FFI) - rust-lang#133294 (crashes: more tests) - rust-lang#133790 (Improve documentation for Vec::extend_from_within) - rust-lang#133930 (rustbook: update to use new mdbook-trpl package from The Book) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 5 pull requests Successful merges: - rust-lang#130777 (rust_for_linux: -Zreg-struct-return commandline flag for X86 (rust-lang#116973)) - rust-lang#133211 (Extend Miri to correctly pass mutable pointers through FFI) - rust-lang#133790 (Improve documentation for Vec::extend_from_within) - rust-lang#133930 (rustbook: update to use new mdbook-trpl package from The Book) - rust-lang#133931 (Only allow PassMode::Direct for aggregates on wasm when using the C ABI) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#130777 - azhogin:azhogin/reg-struct-return, r=workingjubilee rust_for_linux: -Zreg-struct-return commandline flag for X86 (rust-lang#116973) Command line flag `-Zreg-struct-return` for X86 (32-bit) for rust-for-linux. This flag enables the same behavior as the `abi_return_struct_as_int` target spec key. - Tracking issue: rust-lang#116973
… r=workingjubilee rust_for_linux: -Zreg-struct-return commandline flag for X86 (rust-lang#116973) Command line flag `-Zreg-struct-return` for X86 (32-bit) for rust-for-linux. This flag enables the same behavior as the `abi_return_struct_as_int` target spec key. - Tracking issue: rust-lang#116973
Command line flag
-Zreg-struct-returnfor X86 (32-bit) for rust-for-linux.This flag enables the same behavior as the
abi_return_struct_as_inttarget spec key.-Zreg-struct-returnsupport inrustc#116973