Merge pull request #1510 from teapotd/abi-i128-fix

Always check if struct-return parameter is needed
This commit is contained in:
Nick Fitzgerald
2020-05-29 10:02:16 -07:00
committed by GitHub
6 changed files with 60 additions and 41 deletions

View File

@@ -245,24 +245,17 @@ pub fn legalize_signature(
isa_flags,
);
let sig_is_multi_return = sig.is_multi_return();
// 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
// If 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
// do that, we need a copy of the original assigner for the returns.
let backup_rets_for_struct_return = if sig_is_multi_return {
Some(rets.clone())
} else {
None
};
let mut backup_rets = rets.clone();
if let Some(new_returns) = legalize_args(&sig.returns, &mut rets) {
if sig.is_multi_return()
&& new_returns
.iter()
.filter(|r| r.purpose == ArgumentPurpose::Normal)
.any(|r| !r.location.is_reg())
if new_returns
.iter()
.filter(|r| r.purpose == ArgumentPurpose::Normal)
.any(|r| !r.location.is_reg())
{
// The return values couldn't all fit into available return
// 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"),
}
let mut backup_rets = backup_rets_for_struct_return.unwrap();
// We're using the first return register for the return pointer (like
// sys v does).
let mut ret_ptr_return = AbiParam {

View File

@@ -757,12 +757,6 @@ pub fn handle_call_abi(
{
legalize_sret_call(isa, pos, sig_ref, inst);
} else {
// OK, we need to fix the call arguments to match the ABI signature.
let abi_args = pos.func.dfg.signatures[sig_ref].params.len();
legalize_inst_arguments(pos, cfg, abi_args, |func, abi_arg| {
func.dfg.signatures[sig_ref].params[abi_arg]
});
if !pos.func.dfg.signatures[sig_ref].returns.is_empty() {
inst = legalize_inst_results(pos, |func, abi_res| {
func.dfg.signatures[sig_ref].returns[abi_res]
@@ -770,6 +764,13 @@ pub fn handle_call_abi(
}
}
// Go back and fix the call arguments to match the ABI signature.
pos.goto_inst(inst);
let abi_args = pos.func.dfg.signatures[sig_ref].params.len();
legalize_inst_arguments(pos, cfg, abi_args, |func, abi_arg| {
func.dfg.signatures[sig_ref].params[abi_arg]
});
debug_assert!(
check_call_signature(&pos.func.dfg, inst).is_ok(),
"Signature still wrong: {}, {}{}",