Skip to content

Commit 2e24b51

Browse files
committed
Set NumRegisterParameters LLVM module flag to N when -Zregparm=N is set
* Implement the -Zregparm=N flag by setting the NumRegisterParameters LLVM module flag. * Add assembly tests verifying that the parameters are correctly passed in registers for regparm values 1, 2, and 3, for both LLVM intrinsics and non-builtin function * Add c_void type to minicore
1 parent a153133 commit 2e24b51

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,15 @@ pub(crate) unsafe fn create_module<'ll>(
372372
}
373373
}
374374

375+
if let Some(regparm_count) = sess.opts.unstable_opts.regparm {
376+
llvm::add_module_flag_u32(
377+
llmod,
378+
llvm::ModuleFlagMergeBehavior::Error,
379+
"NumRegisterParameters",
380+
regparm_count,
381+
);
382+
}
383+
375384
if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
376385
if sess.target.arch == "aarch64" {
377386
llvm::add_module_flag_u32(
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Test the regparm ABI with builtin and non-builtin calls
2+
// Issue: https://github.com/rust-lang/rust/issues/145271
3+
//@ add-core-stubs
4+
//@ assembly-output: emit-asm
5+
//@ compile-flags: -O --target=i686-unknown-linux-gnu -Crelocation-model=static
6+
//@ revisions: REGPARM1 REGPARM2 REGPARM3
7+
//@[REGPARM1] compile-flags: -Zregparm=1
8+
//@[REGPARM2] compile-flags: -Zregparm=2
9+
//@[REGPARM3] compile-flags: -Zregparm=3
10+
//@ needs-llvm-components: x86
11+
#![feature(no_core)]
12+
#![no_std]
13+
#![no_core]
14+
#![crate_type = "lib"]
15+
16+
extern crate minicore;
17+
use minicore::*;
18+
19+
unsafe extern "C" {
20+
fn memset(p: *mut c_void, val: i32, len: usize) -> *mut c_void;
21+
fn non_builtin_memset(p: *mut c_void, val: i32, len: usize) -> *mut c_void;
22+
}
23+
24+
#[unsafe(no_mangle)]
25+
pub unsafe extern "C" fn entrypoint(len: usize, ptr: *mut c_void, val: i32) -> *mut c_void {
26+
// REGPARM1-LABEL: entrypoint
27+
// REGPARM1: movl %e{{.*}}, %ecx
28+
// REPGARM1: pushl
29+
// REGPARM1: calll memset
30+
31+
// REGPARM2-LABEL: entrypoint
32+
// REGPARM2: movl 16(%esp), %edx
33+
// REGPARM2: movl %e{{.*}}, (%esp)
34+
// REGPARM2: movl %e{{.*}}, %eax
35+
// REGPARM2: calll memset
36+
37+
// REGPARM3-LABEL: entrypoint
38+
// REGPARM3: movl %e{{.*}}, %esi
39+
// REGPARM3: movl %e{{.*}}, %eax
40+
// REGPARM3: movl %e{{.*}}, %ecx
41+
// REGPARM3: jmp memset
42+
unsafe { memset(ptr, val, len) }
43+
}
44+
45+
#[unsafe(no_mangle)]
46+
pub unsafe extern "C" fn non_builtin_entrypoint(
47+
len: usize,
48+
ptr: *mut c_void,
49+
val: i32,
50+
) -> *mut c_void {
51+
// REGPARM1-LABEL: non_builtin_entrypoint
52+
// REGPARM1: movl %e{{.*}}, %ecx
53+
// REGPARM1: pushl
54+
// REGPARM1: calll non_builtin_memset
55+
56+
// REGPARM2-LABEL: non_builtin_entrypoint
57+
// REGPARM2: movl 16(%esp), %edx
58+
// REGPARM2: movl %e{{.*}}, (%esp)
59+
// REGPARM2: movl %e{{.*}}, %eax
60+
// REGPARM2: calll non_builtin_memset
61+
62+
// REGPARM3-LABEL: non_builtin_entrypoint
63+
// REGPARM3: movl %e{{.*}}, %esi
64+
// REGPARM3: movl %e{{.*}}, %eax
65+
// REGPARM3: movl %e{{.*}}, %ecx
66+
// REGPARM3: jmp non_builtin_memset
67+
unsafe { non_builtin_memset(ptr, val, len) }
68+
}

tests/auxiliary/minicore.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,10 @@ pub mod mem {
225225
#[rustc_intrinsic]
226226
pub unsafe fn transmute<Src, Dst>(src: Src) -> Dst;
227227
}
228+
229+
#[lang = "c_void"]
230+
#[repr(u8)]
231+
pub enum c_void {
232+
__variant1,
233+
__variant2,
234+
}

0 commit comments

Comments
 (0)