rust_for_linux: -Zregparm= commandline flag for X86 (#116972) by azhogin · Pull Request #130432 · rust-lang/rust (original) (raw)

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 andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation87 Commits4 Checks12 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

azhogin

Command line flag -Zregparm=<N> for X86 (32-bit) for rust-for-linux: #116972
Implemented in the similar way as fastcall/vectorcall support (args are marked InReg if fit).

@rustbot

r? @pnkfelix

rustbot has assigned @pnkfelix.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review

Status: Awaiting review from the assignee but also interested parties.

T-compiler

Relevant to the compiler team, which will review and decide on the PR/issue.

labels

Sep 16, 2024

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bors

@azhogin azhogin marked this pull request as ready for review

September 17, 2024 10:12

@rustbot

@nikic

As this affects call ABI, doesn't this need to be a target option rather than compiler flag? Otherwise @RalfJung will be very sad.

@jieyouxu

As this affects call ABI, doesn't this need to be a target option rather than compiler flag? Otherwise @RalfJung will be very sad.

Am I understanding correctly that like -C soft-float, the problem that if this is a compiler flag, then it's easy to have code compiled with -Z regparam call code that is not -Z regparam even though they appear to be of the same concrete target, then dragons get summoned?

@nikic

@RalfJung

As a nightly flag I don't mind having this experimentally, but the docs should call out very clearly that all code that is linked together needs to use the same value for this flag.

But this can't be stabilized in that form.

RalfJung

RalfJung

@jieyouxu

As a nightly flag I don't mind having this experimentally, but the docs should call out very clearly that all code that is linked together needs to use the same value for this flag.

Although IIRC target options don't have a stable format either, so we may as well make this part of target options and implement this the "correct" way to make using it correctly less footgunny from the get-go instead of having the flag that's asking for fireworks? Since I imagine if RfL wants this flag then surely they'll want to actually use it. Especially if this is limited to a specific target architecture(?).

@RalfJung

Yeah if this can be made a target option that would probably be better. I just didn't want to block experimentation on these concerns.

@jieyouxu

Right, that's fair and fine by me as well.

@ojeda ojeda mentioned this pull request

Sep 26, 2024

56 tasks

@ojeda

I get an ICE building core, e.g.

rustc --edition=2021 --target i686-unknown-linux-gnu -Zregparm=3 --crate-type rlib library/core/src/lib.rs --sysroot=/dev/null

query stack during panic:
#0 [fn_abi_of_instance] computing call ABI of `slice::ascii::<impl at library/core/src/slice/ascii.rs:9:1: 9:10>::is_ascii`
#1 [eval_to_allocation_raw] const-evaluating + checking `ascii::ascii_char::<impl at library/core/src/ascii/ascii_char.rs:588:1: 588:30>::fmt::HEX_DIGITS`
end of query stack

The new tests pass though (by the way, since we pass --target, do we need only-x86? I noticed one of the sets was ignored)

@workingjubilee

Backtrace gives this:

  17:     0x7a29058f5943 - fill_inregs<rustc_middle::ty::Ty, rustc_middle::ty::layout::LayoutCx>
                               at /home/jubilee/rust/rustc/compiler/rustc_target/src/callconv/x86.rs:178:17

Panic is here, it seems:

unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode)

Error:

internal error: entered unreachable code: x86 shouldn't be passing arguments by Pair(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(1 bytes)) }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None })

I had a feeling that was unwarrantedly confident, but the error branch was preexisting, so it wasn't obvious how we'd start to hit it. Hmm...

@workingjubilee

oh, because we're now making the Rust ABI go through it.

@workingjubilee

@workingjubilee

@workingjubilee

@azhogin I have pushed a fix for the test omission and reverted extern "Rust" handling from the flag, you may wish to pull before you continue working. And feel free to drop/edit/squash/whatever those commits, naturally (though you may wish to branch off before you do so, as to have the extern "Rust" code around).

@ojeda Good catch for the only-x86! Yeah, it's completely unnecessary.

Let's try again, without the scope-creep into extern "Rust"? It builds library/core now with -Zregparm=3, at least.

workingjubilee

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your work on this, @azhogin. This needs a slight doc update if we keep it in its current state, but I'm fully content with this if it satisfies the extern "C" ABI requirements of the kernel.

It now seems obvious that @nbdd0121 was right: the goals of ABI compatibility and performance optimization are different. I realize it might be confusing, but c'est la vie. We shouldn't land this PR with extern "Rust" support for -Zregparm, unless we really want to be here for a few more weeks.

We also haven't even started to discuss other possibilities... like making extern "Rust" always be "fastcall-like" on x86.

@azhogin @workingjubilee

Co-authored-by: Jubilee workingjubilee@gmail.com

@azhogin

Thank you for your work on this, @azhogin. This needs a slight doc update if we keep it in its current state, but I'm fully content with this if it satisfies the extern "C" ABI requirements of the kernel.

Could it be better to just skip signatures (for Rust cc) with PassMode:: (Pair/Cast/Indirect with meta_attrs) ? Yes, it is still a temporary solution, but allows to support most of "Rust" calling conv signatures. I am just not sure if -Zregparm flag without Rust cc has valuable meaning for RfL.
I tested core compilation with this change (and its ok):

    // For types generating PassMode::Cast, PassMode::Indirect(meta_attrs) and PassMode::Pair,
    // InRegs will not be set.
    // Maybe, this is a FIXME
    let has_incompatibles = fn_abi.args.iter().any(
        |arg| matches!(arg.mode,
            PassMode::Pair { .. }
            | PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ }
            | PassMode::Cast { .. })
    );
    if has_incompatibles && rust_abi {
        return;
    }

@workingjubilee

Could it be better to just skip signatures (for Rust cc) with PassMode:: (Pair/Cast/Indirect with meta_attrs) ? Yes, it is still a temporary solution, but allows to support most of "Rust" calling conv signatures. I am just not sure if -Zregparm flag without Rust cc has valuable meaning for RfL.

The most core need here is to be able to match the ABI of the kernel's C code as it is normally built, so that Rust's presence does not force deoptimizing that C code. This patch should address that in its current state, even if it does not affect the Rust calling convention at all.

Landing this patch first will allow us to still implement whatever Rust-ABI optimizations we want. But there is no need to rush such, and we should in fact scrutinize it more closely. This is not the first time the Rust and C ABIs have had the oddity of the C ABI being actually preferable for something, and it won't be the last. Especially not as a temporary situation.

@ojeda

I am just not sure if -Zregparm flag without Rust cc has valuable meaning for RfL.

I think it has (well, assuming it actually has a positive effect for codegen for the Rust side too -- we will need to see if that is true or not), but like @workingjubilee says, it is more important to at least be able to build with the right ABI. With the docs that you added now clarifying where it applies, I think it is clear enough for users.

@workingjubilee

@bors

📌 Commit 37dc4ec has been approved by workingjubilee,pnkfelix

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors

Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

and removed S-waiting-on-review

Status: Awaiting review from the assignee but also interested parties.

labels

Oct 21, 2024

fmease added a commit to fmease/rust that referenced this pull request

Oct 22, 2024

@fmease

…jubilee,pnkfelix

rust_for_linux: -Zregparm= commandline flag for X86 (rust-lang#116972)

Command line flag -Zregparm=<N> for X86 (32-bit) for rust-for-linux: rust-lang#116972 Implemented in the similar way as fastcall/vectorcall support (args are marked InReg if fit).

bors added a commit to rust-lang-ci/rust that referenced this pull request

Oct 22, 2024

@bors

bors added a commit to rust-lang-ci/rust that referenced this pull request

Oct 22, 2024

@bors

rust-timer added a commit to rust-lang-ci/rust that referenced this pull request

Oct 22, 2024

@rust-timer

Rollup merge of rust-lang#130432 - azhogin:azhogin/regparm, r=workingjubilee,pnkfelix

rust_for_linux: -Zregparm= commandline flag for X86 (rust-lang#116972)

Command line flag -Zregparm=<N> for X86 (32-bit) for rust-for-linux: rust-lang#116972 Implemented in the similar way as fastcall/vectorcall support (args are marked InReg if fit).

@ojeda ojeda mentioned this pull request

Nov 18, 2024

95 tasks

antoyo pushed a commit to antoyo/rust that referenced this pull request

Jan 13, 2025

@workingjubilee

…jubilee,pnkfelix

rust_for_linux: -Zregparm= commandline flag for X86 (rust-lang#116972)

Command line flag -Zregparm=<N> for X86 (32-bit) for rust-for-linux: rust-lang#116972 Implemented in the similar way as fastcall/vectorcall support (args are marked InReg if fit).

Reviewers

@RalfJung RalfJung RalfJung left review comments

@ojeda ojeda ojeda left review comments

@Urgau Urgau Urgau left review comments

@nbdd0121 nbdd0121 nbdd0121 left review comments

@workingjubilee workingjubilee workingjubilee approved these changes

Labels

A-ABI

Area: Concerning the application binary interface (ABI)

A-CLI

Area: Command-line interface (CLI) to the compiler

A-rust-for-linux

Relevant for the Rust-for-Linux project

O-x86_32

Target: x86 processors, 32 bit (like i686-*) (IA-32)

S-waiting-on-bors

Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

T-compiler

Relevant to the compiler team, which will review and decide on the PR/issue.