s390x: Fix handling of sret arguments (#5116)

Skip synthetic StructReturn entries in the return value list.
Fixes https://github.com/bytecodealliance/wasmtime/issues/5089
This commit is contained in:
Ulrich Weigand
2022-10-25 19:40:10 +02:00
committed by GitHub
parent 441401f9d6
commit 39b3b1d772
4 changed files with 34 additions and 3 deletions

View File

@@ -3511,6 +3511,9 @@
(decl abi_sig (SigRef) Sig) (decl abi_sig (SigRef) Sig)
(extern constructor abi_sig abi_sig) (extern constructor abi_sig abi_sig)
(decl abi_first_ret (SigRef Sig) usize)
(extern constructor abi_first_ret abi_first_ret)
(decl abi_call_info (Sig ExternalName CallArgList CallRetList Opcode) BoxCallInfo) (decl abi_call_info (Sig ExternalName CallArgList CallRetList Opcode) BoxCallInfo)
(extern constructor abi_call_info abi_call_info) (extern constructor abi_call_info abi_call_info)

View File

@@ -3892,7 +3892,8 @@
(uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args)) (uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
(defs CallRetList (defs_init abi)) (defs CallRetList (defs_init abi))
(_ InstOutput (side_effect (abi_call abi name uses defs (Opcode.Call))))) (_ InstOutput (side_effect (abi_call abi name uses defs (Opcode.Call)))))
(lower_call_rets abi defs (range 0 (abi_num_rets abi)) (output_builder_new)))) (lower_call_rets abi defs (range (abi_first_ret sig_ref abi)
(abi_num_rets abi)) (output_builder_new))))
;; Direct call to an out-of-range function (implicitly via pointer). ;; Direct call to an out-of-range function (implicitly via pointer).
(rule (lower (call (func_ref_data sig_ref name _) args)) (rule (lower (call (func_ref_data sig_ref name _) args))
@@ -3902,7 +3903,8 @@
(defs CallRetList (defs_init abi)) (defs CallRetList (defs_init abi))
(target Reg (load_symbol_reloc (SymbolReloc.Absolute name 0))) (target Reg (load_symbol_reloc (SymbolReloc.Absolute name 0)))
(_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.Call))))) (_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.Call)))))
(lower_call_rets abi defs (range 0 (abi_num_rets abi)) (output_builder_new)))) (lower_call_rets abi defs (range (abi_first_ret sig_ref abi)
(abi_num_rets abi)) (output_builder_new))))
;; Indirect call. ;; Indirect call.
(rule (lower (call_indirect sig_ref ptr args)) (rule (lower (call_indirect sig_ref ptr args))
@@ -3912,7 +3914,8 @@
(uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args)) (uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
(defs CallRetList (defs_init abi)) (defs CallRetList (defs_init abi))
(_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.CallIndirect))))) (_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.CallIndirect)))))
(lower_call_rets abi defs (range 0 (abi_num_rets abi)) (output_builder_new)))) (lower_call_rets abi defs (range (abi_first_ret sig_ref abi)
(abi_num_rets abi)) (output_builder_new))))
;; Lower function arguments. ;; Lower function arguments.
(decl lower_call_args (Sig Range ValueSlice) CallArgList) (decl lower_call_args (Sig Range ValueSlice) CallArgList)

View File

@@ -165,6 +165,13 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6>
self.lower_ctx.sigs().abi_sig_for_sig_ref(sig_ref) self.lower_ctx.sigs().abi_sig_for_sig_ref(sig_ref)
} }
fn abi_first_ret(&mut self, sig_ref: SigRef, abi: &Sig) -> usize {
// Return the index of the first actual return value, excluding
// any StructReturn that might have been added to Sig.
let sig = &self.lower_ctx.dfg().signatures[sig_ref];
self.lower_ctx.sigs()[*abi].num_rets() - sig.returns.len()
}
fn abi_lane_order(&mut self, abi: &Sig) -> LaneOrder { fn abi_lane_order(&mut self, abi: &Sig) -> LaneOrder {
lane_order_for_call_conv(self.lower_ctx.sigs()[*abi].call_conv()) lane_order_for_call_conv(self.lower_ctx.sigs()[*abi].call_conv())
} }

View File

@@ -220,3 +220,21 @@ block0(v0: i128, v1: i128, v2: i128, v3: i128, v4: i128, v5: i128, v6: i128, v7:
; vst %v17, 0(%r2) ; vst %v17, 0(%r2)
; br %r14 ; br %r14
function %call_sret() -> i64 {
fn0 = colocated %g(i64 sret)
block0:
v1 = iconst.i64 0
call fn0(v1)
trap user0
}
; stmg %r14, %r15, 112(%r15)
; aghi %r15, -160
; virtual_sp_offset_adjust 160
; block0:
; lghi %r2, 0
; brasl %r14, %g
; trap