mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-04 19:28:29 +00:00

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: https://github.com/rust-lang/rust/issues/145271
The codegen
crate contains the code to convert from MIR into LLVM IR,
and then from LLVM IR into machine code. In general it contains code
that runs towards the end of the compilation process.
For more information about how codegen works, see the rustc dev guide.