Skip to content

Commit 9aab517

Browse files
committed
rust_for_linux: -Zreg-struct-return commandline flag for X86 (rust-lang#116973)
1 parent f005c74 commit 9aab517

File tree

15 files changed

+279
-4
lines changed

15 files changed

+279
-4
lines changed

compiler/rustc_codegen_gcc/src/context.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,10 @@ impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> {
544544

545545
impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> {
546546
fn x86_abi_opt(&self) -> X86Abi {
547-
X86Abi { regparm: self.tcx.sess.opts.unstable_opts.regparm }
547+
X86Abi {
548+
regparm: self.tcx.sess.opts.unstable_opts.regparm,
549+
reg_struct_return: self.tcx.sess.opts.unstable_opts.reg_struct_return,
550+
}
548551
}
549552
}
550553

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ fn test_unstable_options_tracking_hash() {
831831
tracked!(precise_enum_drop_elaboration, false);
832832
tracked!(profile_sample_use, Some(PathBuf::from("abc")));
833833
tracked!(profiler_runtime, "abc".to_string());
834+
tracked!(reg_struct_return, true);
834835
tracked!(regparm, Some(3));
835836
tracked!(relax_elf_relocations, Some(true));
836837
tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,10 @@ impl<'tcx> HasWasmCAbiOpt for TyCtxt<'tcx> {
552552

553553
impl<'tcx> HasX86AbiOpt for TyCtxt<'tcx> {
554554
fn x86_abi_opt(&self) -> X86Abi {
555-
X86Abi { regparm: self.sess.opts.unstable_opts.regparm }
555+
X86Abi {
556+
regparm: self.sess.opts.unstable_opts.regparm,
557+
reg_struct_return: self.sess.opts.unstable_opts.reg_struct_return,
558+
}
556559
}
557560
}
558561

compiler/rustc_session/messages.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,6 @@ session_unsupported_crate_type_for_target =
135135
136136
session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is greater than 5
137137
138+
session_unsupported_reg_struct_return_arch = `-Zreg-struct-return` is only supported on x86
138139
session_unsupported_regparm = `-Zregparm={$regparm}` is unsupported (valid values 0-3)
139140
session_unsupported_regparm_arch = `-Zregparm=N` is only supported on x86

compiler/rustc_session/src/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ pub(crate) struct UnsupportedRegparm {
489489
#[diag(session_unsupported_regparm_arch)]
490490
pub(crate) struct UnsupportedRegparmArch;
491491

492+
#[derive(Diagnostic)]
493+
#[diag(session_unsupported_reg_struct_return_arch)]
494+
pub(crate) struct UnsupportedRegStructReturnArch;
495+
492496
#[derive(Diagnostic)]
493497
#[diag(session_failed_to_create_profiler)]
494498
pub(crate) struct FailedToCreateProfiler {

compiler/rustc_session/src/options.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,6 +1985,9 @@ options! {
19851985
"enable queries of the dependency graph for regression testing (default: no)"),
19861986
randomize_layout: bool = (false, parse_bool, [TRACKED],
19871987
"randomize the layout of types (default: no)"),
1988+
reg_struct_return: bool = (false, parse_bool, [TRACKED],
1989+
"On x86-32 targets, it overrides the default ABI to return small structs in registers.
1990+
It is UNSOUND to link together crates that use different values for this flag!"),
19881991
regparm: Option<u32> = (None, parse_opt_number, [TRACKED],
19891992
"On x86-32 targets, setting this to N causes the compiler to pass N arguments \
19901993
in registers EAX, EDX, and ECX instead of on the stack for\

compiler/rustc_session/src/session.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
13051305
sess.dcx().emit_err(errors::UnsupportedRegparmArch);
13061306
}
13071307
}
1308+
if sess.opts.unstable_opts.reg_struct_return {
1309+
if sess.target.arch != "x86" {
1310+
sess.dcx().emit_err(errors::UnsupportedRegStructReturnArch);
1311+
}
1312+
}
13081313

13091314
// The code model check applies to `thunk` and `thunk-extern`, but not `thunk-inline`, so it is
13101315
// kept as a `match` to force a change if new ones are added, even if we currently only support

compiler/rustc_target/src/callconv/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,9 @@ impl<'a, Ty> FnAbi<'a, Ty> {
661661
}
662662
_ => (x86::Flavor::General, None),
663663
};
664-
x86::compute_abi_info(cx, self, x86::X86Options { flavor, regparm });
664+
let reg_struct_return = cx.x86_abi_opt().reg_struct_return;
665+
let opts = x86::X86Options { flavor, regparm, reg_struct_return };
666+
x86::compute_abi_info(cx, self, opts);
665667
}
666668
"x86_64" => match abi {
667669
spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),

compiler/rustc_target/src/callconv/x86.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub(crate) enum Flavor {
1414
pub(crate) struct X86Options {
1515
pub flavor: Flavor,
1616
pub regparm: Option<u32>,
17+
pub reg_struct_return: bool,
1718
}
1819

1920
pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, opts: X86Options)
@@ -31,7 +32,7 @@ where
3132
// https://www.angelcode.com/dev/callconv/callconv.html
3233
// Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp
3334
let t = cx.target_spec();
34-
if t.abi_return_struct_as_int {
35+
if t.abi_return_struct_as_int || opts.reg_struct_return {
3536
// According to Clang, everyone but MSVC returns single-element
3637
// float aggregates directly in a floating-point register.
3738
if !t.is_like_msvc && fn_abi.ret.layout.is_single_fp_element(cx) {

compiler/rustc_target/src/spec/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,8 @@ pub struct X86Abi {
21082108
/// On x86-32 targets, the regparm N causes the compiler to pass arguments
21092109
/// in registers EAX, EDX, and ECX instead of on the stack.
21102110
pub regparm: Option<u32>,
2111+
/// Override the default ABI to return small structs in registers
2112+
pub reg_struct_return: bool,
21112113
}
21122114

21132115
pub trait HasX86AbiOpt {

0 commit comments

Comments
 (0)