From 2c8d543c149666b6a9c4d45b18a1879458fc7201 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 18 Apr 2017 23:59:25 +0300 Subject: [PATCH] rustc_trans: do not treat byval as using up registers. --- src/librustc_trans/cabi_x86_64.rs | 5 +---- .../run-make/extern-fn-struct-passing-abi/test.c | 15 +++++++++++++++ .../run-make/extern-fn-struct-passing-abi/test.rs | 8 ++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/cabi_x86_64.rs b/src/librustc_trans/cabi_x86_64.rs index 7f2fdbf000b65..7488885e7658f 100644 --- a/src/librustc_trans/cabi_x86_64.rs +++ b/src/librustc_trans/cabi_x86_64.rs @@ -375,10 +375,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { let in_mem = cls.is_pass_byval() || int_regs < needed_int || sse_regs < needed_sse; - if in_mem { - // `byval` parameter thus one less integer register available - int_regs -= 1; - } else { + if !in_mem { // split into sized chunks passed individually int_regs -= needed_int; sse_regs -= needed_sse; diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.c b/src/test/run-make/extern-fn-struct-passing-abi/test.c index 4253767ee76a9..872bafd24a40e 100644 --- a/src/test/run-make/extern-fn-struct-passing-abi/test.c +++ b/src/test/run-make/extern-fn-struct-passing-abi/test.c @@ -132,6 +132,21 @@ void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d, assert(s.d == 556); } +// System V x86_64 ABI: +// a, b, d, e, f should be byval pointer (on the stack) +// g passed via register (fixes #41375) +// +// Win64 ABI: +// a, b, d, e, f, g should be byval pointer +void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c, + struct Huge d, struct Huge e, struct Huge f, + struct Rect g) { + assert(g.a == 123); + assert(g.b == 456); + assert(g.c == 789); + assert(g.d == 420); +} + // System V x86_64 & Win64 ABI: // a, b should be in registers // s should be split across 2 integer registers diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.rs b/src/test/run-make/extern-fn-struct-passing-abi/test.rs index b91362b8edccb..fa57424f7f8c3 100644 --- a/src/test/run-make/extern-fn-struct-passing-abi/test.rs +++ b/src/test/run-make/extern-fn-struct-passing-abi/test.rs @@ -57,6 +57,8 @@ extern { fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect); + fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect); + fn split_rect(a: i32, b: i32, s: Rect); fn split_rect_floats(a: f32, b: f32, s: FloatRect); @@ -85,6 +87,12 @@ fn main() { byval_many_rect(1, 2, 3, 4, 5, 6, s); byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u); byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s); + byval_rect_with_many_huge(v, v, v, v, v, v, Rect { + a: 123, + b: 456, + c: 789, + d: 420 + }); split_rect(1, 2, s); split_rect_floats(1., 2., u); split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);