diff --git a/arm64-gen.c b/arm64-gen.c index d15446d3..ccb5a5c1 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -1101,6 +1101,9 @@ ST_FUNC void gfunc_call(int nb_args) // value in floating-point registers if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz); + // save regs because struct may overwrite previous func call result + save_regs(0); + vtop->type.t = VT_PTR; gaddrof(); gv(RC_R30); diff --git a/tests/tests2/137_funcall_struct_args.c b/tests/tests2/137_funcall_struct_args.c new file mode 100644 index 00000000..20768e34 --- /dev/null +++ b/tests/tests2/137_funcall_struct_args.c @@ -0,0 +1,23 @@ +#include + +// arm64-gen.c: gfunc_call() Second pass when struct args may overwrite previous func call result +struct vec { + float x; + float y; +}; + +void bug(float x, float y) { + printf("x=%f\ny=%f\n", x, y); +} + +float dot(struct vec v) { + return 999.5; +} + +void main(void) { + struct vec a; + a.x = 33.0f; + a.y = 77.0f; + bug(dot(a), dot(a)); +} + diff --git a/tests/tests2/137_funcall_struct_args.expect b/tests/tests2/137_funcall_struct_args.expect new file mode 100644 index 00000000..ea381eae --- /dev/null +++ b/tests/tests2/137_funcall_struct_args.expect @@ -0,0 +1,2 @@ +x=999.500000 +y=999.500000