-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
rust_for_linux: -Zreg-struct-return commandline flag for X86 (#116973) #130777
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. |
☔ The latest upstream changes (presumably #132020) made this pull request unmergeable. Please resolve the merge conflicts. |
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
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.-Zreg-struct-return
support inrustc
#116973