From ebc5730a46be377e8ee35703653c8961ebc61da3 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 9 Jul 2025 22:46:11 +0300 Subject: [PATCH] [mono][interp] Fix alignment for simd args For untiered code, we don't use the var offset allocator, the offset for vars is computed on the fly as we push and pop them from the execution stack during initial IL import compilation phase. These offsets (and their alignment) follow the same rules as if they would be passed as arguments to a method. When we initially push a var we don't know if this var will be an argument to a call, so it might not have the stack alignment of 16 bytes. In this case, at the moment of a call we add a MINT_MOV_STACK_UNOPT opcode which moves the entire var space so it has the right alignment. The problem is that all simd params (which need 16byte alignment) will now become unaligned. `interp_realign_simd_params` is called to resolve this problem by doing another mov, this time starting at the location of the first simd argument. This realignment is meant to be done only once, because once a simd argument is properly aligned, all following arguments are aligned as well, due to the way they are initially pushed on the execution stack. The issue was that we were not breaking the loop once we do the realignment starting at the first simd argument. --- src/mono/mono/mini/interp/transform.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 11912e096cdcbe..b45b82db4696dc 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -3394,6 +3394,12 @@ interp_realign_simd_params (TransformData *td, StackInfo *sp_params, int num_arg td->last_ins->data [0] = GINT_TO_UINT16 (sp_params [i].offset + prev_offset); td->last_ins->data [1] = offset_amount; td->last_ins->data [2] = GINT_TO_UINT16 (get_stack_size (td, sp_params + i, num_args - i)); + + // The stack move applies to all arguments starting at this one. Because we push + // simd valuetypes in aligned fashion on the execution stack, the offset between two + // simd values will be a multiple of simd alignment. This means that if this arg is + // correctly aligned, all following args will be aligned as well. + return; } } }