-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Fix -Zregparm
for LLVM builtins
#145309
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
base: master
Are you sure you want to change the base?
Fix -Zregparm
for LLVM builtins
#145309
Conversation
I think this should fix it already, let me know if I am missing something! Working on the tests now. |
rustbot has assigned @petrochenkov. Use |
I added a test verifying that the |
r? nikic |
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.
Thank you for doing a quick fix here!
Just a few requests to make sure we're testing what we expect
This PR modifies cc @jieyouxu |
This comment has been minimized.
This comment has been minimized.
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.
Two small nits but this looks good to me once CI passes, please squash
@nikic anything else?
74a664c
to
2e24b51
Compare
I squashed, let me know if there is anything else I can do! |
2e24b51
to
02d4666
Compare
Looks great! Thanks for making this happen, and welcome :) @bors r+ |
Thank you very much for all the help! I'll keep an eye on the issue tracker, but if you come across anything you think would be a good fit, please let me know! |
If you want something tiny then as Miguel mentioned, If you're looking for something in particular or just looking to get more involved, https://rust-lang.zulipchat.com/ is a great place to stop by. |
Should I create a separate issue for the asm tests, or just submit a PR when I'm done? |
No need for a new issue! |
…ross35 Fix `-Zregparm` for LLVM builtins This fixes the issue where `-Zregparm=N` was not working correctly when calling LLVM intrinsics By default on `x86-32`, arguments are passed on the stack. The `-Zregparm=N` flag allows the first `N` arguments to be passed in registers instead. When calling intrinsics like `memset`, LLVM still passes parameters on the stack, which prevents optimizations like tail calls. As proposed by `@tgross35,` I fixed this by setting the `NumRegisterParameters` LLVM module flag to `N` when the `-Zregparm=N` is set. ```rust // compiler/rust_codegen_llvm/src/context.rs#375-382 if let Some(regparm_count) = sess.opts.unstable_opts.regparm { llvm::add_module_flag_u32( llmod, llvm::ModuleFlagMergeBehavior::Error, "NumRegisterParameters", regparm_count, ); } ``` [Here](https://rust.godbolt.org/z/YMezreo48) is a before/after compiler explorer. Here is the final result for the code snippet in the original issue: ```asm entrypoint: push esi mov esi, eax mov eax, ecx mov ecx, esi pop esi jmp memset ; Tail call parameters in registers ``` Fixes: rust-lang#145271
…ross35 Fix `-Zregparm` for LLVM builtins This fixes the issue where `-Zregparm=N` was not working correctly when calling LLVM intrinsics By default on `x86-32`, arguments are passed on the stack. The `-Zregparm=N` flag allows the first `N` arguments to be passed in registers instead. When calling intrinsics like `memset`, LLVM still passes parameters on the stack, which prevents optimizations like tail calls. As proposed by `@tgross35,` I fixed this by setting the `NumRegisterParameters` LLVM module flag to `N` when the `-Zregparm=N` is set. ```rust // compiler/rust_codegen_llvm/src/context.rs#375-382 if let Some(regparm_count) = sess.opts.unstable_opts.regparm { llvm::add_module_flag_u32( llmod, llvm::ModuleFlagMergeBehavior::Error, "NumRegisterParameters", regparm_count, ); } ``` [Here](https://rust.godbolt.org/z/YMezreo48) is a before/after compiler explorer. Here is the final result for the code snippet in the original issue: ```asm entrypoint: push esi mov esi, eax mov eax, ecx mov ecx, esi pop esi jmp memset ; Tail call parameters in registers ``` Fixes: rust-lang#145271
Rollup of 9 pull requests Successful merges: - #122661 (Change the desugaring of `assert!` for better error output) - #138736 (Sanitizers target modificators) - #144955 (search graph: lazily update parent goals) - #145120 (llvm: Accept new LLVM lifetime format) - #145153 (Handle macros with multiple kinds, and improve errors) - #145189 (Weekly `cargo update`) - #145250 (Add regression test for former ICE involving malformed meta items containing interpolated tokens) - #145309 (Fix `-Zregparm` for LLVM builtins) - #145331 (Make std use the edition 2024 prelude) r? `@ghost` `@rustbot` modify labels: rollup
set * Enforce the `-Zregparm=N` flag by setting the NumRegisterParameters LLVM module flag * Add assembly tests verifying that the parameters are passed in registers for reparm values 1, 2, and 3, for both LLVM intrinsics and non-builtin functions * Add c_void type to minicore
02d4666
to
04ff144
Compare
Fixed the typo, thank you! |
@bors r=tgross35 rollup=iffy assembly test |
This fixes the issue where
-Zregparm=N
was not working correctly when calling LLVM intrinsicsBy default on
x86-32
, arguments are passed on the stack. The-Zregparm=N
flag allows the firstN
arguments to be passed in registers instead.When calling intrinsics like
memset
, LLVM still passes parameters on the stack, which prevents optimizations like tail calls.As proposed by @tgross35, I fixed this by setting the
NumRegisterParameters
LLVM module flag toN
when the-Zregparm=N
is set.Here is a before/after compiler explorer.
Here is the final result for the code snippet in the original issue:
Fixes: #145271