Skip to content

Commit 1ffbf9b

Browse files
authored
Rollup merge of #41378 - eddyb:byval-is-not-like-sret, r=arielb1
rustc_trans: do not treat byval as using up registers. Perhaps not that well-documented, `byval` pointer arguments *are not* the same as pointer arguments used by pass-by-ref, but rather the pointer is only used by LLVM to pass the *contents* on the stack. Fixes #41375.
2 parents 90e2ffb + 0b35af9 commit 1ffbf9b

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

src/librustc_trans/cabi_x86_64.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,12 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType
229229
};
230230

231231
if in_mem {
232-
// `sret` / `byval` parameter thus one less integer register available
233-
int_regs -= 1;
234-
235232
arg.make_indirect(ccx);
236233
if is_arg {
237234
arg.attrs.set(ArgAttribute::ByVal);
235+
} else {
236+
// `sret` parameter thus one less integer register available
237+
int_regs -= 1;
238238
}
239239
} else {
240240
// split into sized chunks passed individually

src/test/run-make/extern-fn-struct-passing-abi/test.c

+15
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d,
137137
assert(s.d == 556);
138138
}
139139

140+
// System V x86_64 ABI:
141+
// a, b, d, e, f should be byval pointer (on the stack)
142+
// g passed via register (fixes #41375)
143+
//
144+
// Win64 ABI:
145+
// a, b, d, e, f, g should be byval pointer
146+
void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
147+
struct Huge d, struct Huge e, struct Huge f,
148+
struct Rect g) {
149+
assert(g.a == 123);
150+
assert(g.b == 456);
151+
assert(g.c == 789);
152+
assert(g.d == 420);
153+
}
154+
140155
// System V x86_64 & Win64 ABI:
141156
// a, b should be in registers
142157
// s should be split across 2 integer registers

src/test/run-make/extern-fn-struct-passing-abi/test.rs

+8
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ extern {
6464

6565
fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect);
6666

67+
fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);
68+
6769
fn split_rect(a: i32, b: i32, s: Rect);
6870

6971
fn split_rect_floats(a: f32, b: f32, s: FloatRect);
@@ -95,6 +97,12 @@ fn main() {
9597
byval_many_rect(1, 2, 3, 4, 5, 6, s);
9698
byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
9799
byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
100+
byval_rect_with_many_huge(v, v, v, v, v v, Rect {
101+
a: 123,
102+
b: 456,
103+
c: 789,
104+
d: 420
105+
});
98106
split_rect(1, 2, s);
99107
split_rect_floats(1., 2., u);
100108
split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);

0 commit comments

Comments
 (0)