diff --git a/src/engine/compiler/SinglePassCompiler.v3 b/src/engine/compiler/SinglePassCompiler.v3 index 0a45c4c13..66d6e0c64 100644 --- a/src/engine/compiler/SinglePassCompiler.v3 +++ b/src/engine/compiler/SinglePassCompiler.v3 @@ -2713,6 +2713,7 @@ class SinglePassCompiler(xenv: SpcExecEnv, masm: MacroAssembler, regAlloc: RegAl masm.emit_mov_r_k(kind, reg, sv.const); } else if (sv.reg != NO_REG) { masm.emit_mov_r_r(kind, reg, sv.reg); + regAlloc.unassign(sv.reg, int.!(state.sp)); } else { masm.emit_mov_r_s(kind, reg, state.sp); } diff --git a/test/unittest/x86-64-linux/X86_64LinuxExeTest.v3 b/test/unittest/x86-64-linux/X86_64LinuxExeTest.v3 index 259c4002d..25befaa1f 100644 --- a/test/unittest/x86-64-linux/X86_64LinuxExeTest.v3 +++ b/test/unittest/x86-64-linux/X86_64LinuxExeTest.v3 @@ -16,7 +16,8 @@ component X86_64LinuxExeTest { ("load_oob0", test_load_oob0), ("call1005", test_call1005), // intended to trigger OSR ("osr_accessor", test_osr_accessor), - ("recompile_after_probe", test_recompile_after_probe) + ("recompile_after_probe", test_recompile_after_probe), + ("shared_reg_merge", test_shared_reg_merge) ]) { // register strategy/test pair UnitTests.registerT(strategy.0, test.0, newTester, test.1); @@ -61,6 +62,16 @@ def test_load_oob0(i: ExeTester) { i.args_i(0).assert2_trap(TrapReason.MEMORY_OOB); } +def test_shared_reg_merge(i: ExeTester) { + i.sig(SigCache.i_d).codev([ + u8.!(Opcode.BLOCK.code), BpTypeCode.F64.code, + u8.!(Opcode.LOCAL_GET.code), 0, + u8.!(Opcode.F64_CONVERT_I32_S.code), // pops a register the local still shares + u8.!(Opcode.END.code) + ]); + i.args_i(7).assert2_d(0x401C000000000000); // 7.0 +} + def test_call1005(i: ExeTester) { var f17 = byte.!(i.newFunction(SigCache.v_i, [u8.!(Opcode.I32_CONST.code), 17]).func_index); i.sig(SigCache.i_i);