Skip to content

Commit

Permalink
[interp] Don't cprop between vt vars of different sizes (dotnet#54734)
Browse files Browse the repository at this point in the history
Via unsafe code, getting the lower Vector128 from a Vector256 ends up as a move of `sizeof (Vector128)` from a Vector256 var. However, the destination var is not a valid copy of the source var, having a different type
  • Loading branch information
BrzVlad authored Jun 26, 2021
1 parent db143a0 commit 11967d4
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -8508,17 +8508,30 @@ interp_cprop (TransformData *td)
} else if (opcode == MINT_LDOBJ_VT) {
InterpInst *ldloca = local_defs [sregs [0]].ins;
if (ldloca != NULL && ldloca->opcode == MINT_LDLOCA_S) {
int ldsize = ins->data [0];
int local = ldloca->sregs [0];
// Replace LDLOCA + LDOBJ_VT with MOV_VT
ins->opcode = MINT_MOV_VT;
local_ref_count [sregs [0]]--;
sregs [0] = local;

if (ldsize == td->locals [local].size) {
// Replace LDLOCA + LDOBJ_VT with MOV_VT
ins->opcode = MINT_MOV_VT;
sregs [0] = local;
needs_retry = TRUE;
} else {
// This loads just a part of the local valuetype
ins = interp_insert_ins (td, ins, MINT_MOV_OFF);
interp_ins_set_dreg (ins, ins->prev->dreg);
interp_ins_set_sreg (ins, local);
ins->data [0] = 0;
ins->data [1] = MINT_TYPE_VT;
ins->data [2] = ldsize;

interp_clear_ins (ins->prev);
}
if (td->verbose_level) {
g_print ("Replace ldloca/ldobj_vt pair :\n\t");
dump_interp_inst (ins);
}
needs_retry = TRUE;
}
} else if (MINT_IS_STFLD (opcode) && ins->data [0] == 0) {
InterpInst *ldloca = local_defs [sregs [0]].ins;
Expand Down

0 comments on commit 11967d4

Please sign in to comment.