diff --git a/internal/engine/wazevo/backend/regalloc/regalloc.go b/internal/engine/wazevo/backend/regalloc/regalloc.go index 8f1e30cd..205e6554 100644 --- a/internal/engine/wazevo/backend/regalloc/regalloc.go +++ b/internal/engine/wazevo/backend/regalloc/regalloc.go @@ -246,7 +246,8 @@ func (s *state) findOrSpillAllocatable(a *Allocator, allocatable []RealReg, forb continue } - if last := s.getVRegState(using.ID()).lastUse; r == RealRegInvalid || last > lastUseAt { + // last == -1 means the value won't be used anymore. + if last := s.getVRegState(using.ID()).lastUse; r == RealRegInvalid || last == -1 || (lastUseAt != -1 && last > lastUseAt) { lastUseAt = last r = candidateReal spillVReg = using @@ -258,7 +259,7 @@ func (s *state) findOrSpillAllocatable(a *Allocator, allocatable []RealReg, forb } if wazevoapi.RegAllocLoggingEnabled { - fmt.Printf("\tspilling v%d when: %s\n", spillVReg.ID(), forbiddenMask.format(a.regInfo)) + fmt.Printf("\tspilling v%d when lastUseAt=%d and regsInUse=%s\n", spillVReg.ID(), lastUseAt, s.regsInUse.format(a.regInfo)) } s.releaseRealReg(r) return r diff --git a/internal/integration_test/fuzzcases/fuzzcases_test.go b/internal/integration_test/fuzzcases/fuzzcases_test.go index 39925dad..8bd981d4 100644 --- a/internal/integration_test/fuzzcases/fuzzcases_test.go +++ b/internal/integration_test/fuzzcases/fuzzcases_test.go @@ -1011,3 +1011,10 @@ func Test2078(t *testing.T) { } nodiff.RequireNoDiffT(t, getWasmBinary(t, "2078"), true, true) } + +func Test2082(t *testing.T) { + if !platform.CompilerSupported() { + return + } + nodiff.RequireNoDiffT(t, getWasmBinary(t, "2082"), true, true) +} diff --git a/internal/integration_test/fuzzcases/testdata/2082.wasm b/internal/integration_test/fuzzcases/testdata/2082.wasm new file mode 100644 index 00000000..f0d21e89 Binary files /dev/null and b/internal/integration_test/fuzzcases/testdata/2082.wasm differ diff --git a/internal/integration_test/fuzzcases/testdata/2082.wat b/internal/integration_test/fuzzcases/testdata/2082.wat new file mode 100644 index 00000000..55b2a759 --- /dev/null +++ b/internal/integration_test/fuzzcases/testdata/2082.wat @@ -0,0 +1,30 @@ +(module + (type (;0;) (func (param i32 i32 i32 i32 i32 i32 i32 i32))) + (func (;0;) (type 0) (param i32 i32 i32 i32 i32 i32 i32 i32) + call 1 + i64.const -1 + f64.convert_i64_u + i32.trunc_f64_s + unreachable + ) + (func (result i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + ) + (export "" (func 0)) +) diff --git a/internal/testing/nodiff/nodiff.go b/internal/testing/nodiff/nodiff.go index 5f65fad9..4491196a 100644 --- a/internal/testing/nodiff/nodiff.go +++ b/internal/testing/nodiff/nodiff.go @@ -303,7 +303,8 @@ outer: intRes, intErr := intF.Call(interpreterCtx, params...) errorDuringInvocation = errorDuringInvocation || cmpErr != nil || intErr != nil if errMismatch := ensureInvocationError(cmpErr, intErr); errMismatch != nil { - panic(fmt.Sprintf("error mismatch on invoking %s: %v", name, errMismatch)) + err = errors.Join(err, fmt.Errorf("error mismatch on invoking %s: %v", name, errMismatch)) + continue } matched := true