Always check if struct-return parameter is needed

This commit is contained in:
teapotd
2020-04-15 12:21:05 +02:00
parent 51f9ac2150
commit 0f55bb4b8d
2 changed files with 14 additions and 16 deletions

View File

@@ -245,24 +245,17 @@ pub fn legalize_signature(
isa_flags, isa_flags,
); );
let sig_is_multi_return = sig.is_multi_return(); // If we don't have enough available return registers
// to fit all of the return values, we need to backtrack and start
// If this is a multi-value return and we don't have enough available return
// registers to fit all of the return values, we need to backtrack and start
// assigning locations all over again with a different strategy. In order to // assigning locations all over again with a different strategy. In order to
// do that, we need a copy of the original assigner for the returns. // do that, we need a copy of the original assigner for the returns.
let backup_rets_for_struct_return = if sig_is_multi_return { let mut backup_rets = rets.clone();
Some(rets.clone())
} else {
None
};
if let Some(new_returns) = legalize_args(&sig.returns, &mut rets) { if let Some(new_returns) = legalize_args(&sig.returns, &mut rets) {
if sig.is_multi_return() if new_returns
&& new_returns .iter()
.iter() .filter(|r| r.purpose == ArgumentPurpose::Normal)
.filter(|r| r.purpose == ArgumentPurpose::Normal) .any(|r| !r.location.is_reg())
.any(|r| !r.location.is_reg())
{ {
// The return values couldn't all fit into available return // The return values couldn't all fit into available return
// registers. Introduce the use of a struct-return parameter. // registers. Introduce the use of a struct-return parameter.
@@ -283,8 +276,6 @@ pub fn legalize_signature(
_ => unreachable!("return pointer should always get a register assignment"), _ => unreachable!("return pointer should always get a register assignment"),
} }
let mut backup_rets = backup_rets_for_struct_return.unwrap();
// We're using the first return register for the return pointer (like // We're using the first return register for the return pointer (like
// sys v does). // sys v does).
let mut ret_ptr_return = AbiParam { let mut ret_ptr_return = AbiParam {

View File

@@ -110,6 +110,13 @@ block0(v0: f32, v1: f64, v2: i64, v3: i64):
; nextln: return v1, v5 ; nextln: return v1, v5
; nextln: } ; nextln: }
function %ret_val_i128(i64, i64) -> i128 windows_fastcall {
block0(v0: i64, v1: i64):
v2 = iconcat v0, v1
return v2
}
; check: function %ret_val_i128(i64 [%rdx], i64 [%r8], i64 sret [%rcx], i64 fp [%rbp]) -> i64 sret [%rax], i64 fp [%rbp] windows_fastcall {
function %internal_stack_arg_function_call(i64) -> i64 windows_fastcall { function %internal_stack_arg_function_call(i64) -> i64 windows_fastcall {
fn0 = %foo(i64, i64, i64, i64) -> i64 windows_fastcall fn0 = %foo(i64, i64, i64, i64) -> i64 windows_fastcall
fn1 = %foo2(i64, i64, i64, i64) -> i64 windows_fastcall fn1 = %foo2(i64, i64, i64, i64) -> i64 windows_fastcall