Skip to content

Commit 135a4af

Browse files
authored
[mono][interp] Fix alignment for simd args (#117476)
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.
1 parent 8aaf1be commit 135a4af

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

src/mono/mono/mini/interp/transform.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3394,6 +3394,12 @@ interp_realign_simd_params (TransformData *td, StackInfo *sp_params, int num_arg
33943394
td->last_ins->data [0] = GINT_TO_UINT16 (sp_params [i].offset + prev_offset);
33953395
td->last_ins->data [1] = offset_amount;
33963396
td->last_ins->data [2] = GINT_TO_UINT16 (get_stack_size (td, sp_params + i, num_args - i));
3397+
3398+
// The stack move applies to all arguments starting at this one. Because we push
3399+
// simd valuetypes in aligned fashion on the execution stack, the offset between two
3400+
// simd values will be a multiple of simd alignment. This means that if this arg is
3401+
// correctly aligned, all following args will be aligned as well.
3402+
return;
33973403
}
33983404
}
33993405
}

0 commit comments

Comments
 (0)