Stream: git-wasmtime

Topic: wasmtime / issue #3647 Cranelift: use spillslots only as ...


view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2022 at 19:54):

cfallin opened issue #3647:

In #3645, we switched the spillslot logic to use a spillslot as large as the full register to be spilled, rather than the type we think is stored in the register. This was due to some sloppiness in actually tracking the types; in at least one fuzzbug, a 128-bit-vector-sized value was stored into a 64-bit spillslot.

The root cause of this issue is that the register allocator creates equivalence classes of all vregs linked by move instructions (in order to perform move elision), and when allocating a spillslot for this equivalence class, asks for the size of an arbitrary vreg in the class. If we emit moves between vregs of different types (e.g., 128-bit to 32-bit, if we know we just want the lower bits), then this could return an incorrect type.

To solve this, we need to enforce type discipline in move instructions (and thus have special pseudo-moves that do not participate in move elision). Probably the best way of doing this would be to accept an arbitrary IR-level type in the regalloc interface for every virtual register, and check that moves do not occur between registers of different types. Once we do this, and are free of panics caused by violations of this invariant, then we can revert to the more efficient spillslot allocation scheme.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2022 at 19:41):

akirilov-arm labeled issue #3647:

In #3645, we switched the spillslot logic to use a spillslot as large as the full register to be spilled, rather than the type we think is stored in the register. This was due to some sloppiness in actually tracking the types; in at least one fuzzbug, a 128-bit-vector-sized value was stored into a 64-bit spillslot.

The root cause of this issue is that the register allocator creates equivalence classes of all vregs linked by move instructions (in order to perform move elision), and when allocating a spillslot for this equivalence class, asks for the size of an arbitrary vreg in the class. If we emit moves between vregs of different types (e.g., 128-bit to 32-bit, if we know we just want the lower bits), then this could return an incorrect type.

To solve this, we need to enforce type discipline in move instructions (and thus have special pseudo-moves that do not participate in move elision). Probably the best way of doing this would be to accept an arbitrary IR-level type in the regalloc interface for every virtual register, and check that moves do not occur between registers of different types. Once we do this, and are free of panics caused by violations of this invariant, then we can revert to the more efficient spillslot allocation scheme.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2022 at 19:41):

akirilov-arm labeled issue #3647:

In #3645, we switched the spillslot logic to use a spillslot as large as the full register to be spilled, rather than the type we think is stored in the register. This was due to some sloppiness in actually tracking the types; in at least one fuzzbug, a 128-bit-vector-sized value was stored into a 64-bit spillslot.

The root cause of this issue is that the register allocator creates equivalence classes of all vregs linked by move instructions (in order to perform move elision), and when allocating a spillslot for this equivalence class, asks for the size of an arbitrary vreg in the class. If we emit moves between vregs of different types (e.g., 128-bit to 32-bit, if we know we just want the lower bits), then this could return an incorrect type.

To solve this, we need to enforce type discipline in move instructions (and thus have special pseudo-moves that do not participate in move elision). Probably the best way of doing this would be to accept an arbitrary IR-level type in the regalloc interface for every virtual register, and check that moves do not occur between registers of different types. Once we do this, and are free of panics caused by violations of this invariant, then we can revert to the more efficient spillslot allocation scheme.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 26 2022 at 19:41):

akirilov-arm labeled issue #3647:

In #3645, we switched the spillslot logic to use a spillslot as large as the full register to be spilled, rather than the type we think is stored in the register. This was due to some sloppiness in actually tracking the types; in at least one fuzzbug, a 128-bit-vector-sized value was stored into a 64-bit spillslot.

The root cause of this issue is that the register allocator creates equivalence classes of all vregs linked by move instructions (in order to perform move elision), and when allocating a spillslot for this equivalence class, asks for the size of an arbitrary vreg in the class. If we emit moves between vregs of different types (e.g., 128-bit to 32-bit, if we know we just want the lower bits), then this could return an incorrect type.

To solve this, we need to enforce type discipline in move instructions (and thus have special pseudo-moves that do not participate in move elision). Probably the best way of doing this would be to accept an arbitrary IR-level type in the regalloc interface for every virtual register, and check that moves do not occur between registers of different types. Once we do this, and are free of panics caused by violations of this invariant, then we can revert to the more efficient spillslot allocation scheme.


Last updated: Oct 23 2024 at 20:03 UTC