diff --git a/gnovm/pkg/gnolang/internal/softfloat/gen/main.go b/gnovm/pkg/gnolang/internal/softfloat/gen/main.go index a413255cc2e..9e4c1794d92 100644 --- a/gnovm/pkg/gnolang/internal/softfloat/gen/main.go +++ b/gnovm/pkg/gnolang/internal/softfloat/gen/main.go @@ -52,6 +52,9 @@ func processSoftFloat64File() { // Replace package name newContent = strings.Replace(newContent, "package runtime", "package softfloat", 1) + // Apply the gnolang/gno#5806 fix to the upstream sources. + newContent = patchSubnormalCancellation(newContent) + // Write to destination file err = os.WriteFile("runtime_softfloat64.go", []byte(newContent), 0o644) if err != nil { @@ -59,6 +62,65 @@ func processSoftFloat64File() { } } +// patchSubnormalCancellation fixes a latent bug in the upstream +// runtime/softfloat64.go: fpack64/fpack32 return a wrongly-scaled subnormal +// when fadd64/fsub64 produce a heavily-cancelled mantissa (two near-equal, +// opposite-sign normals summing to a subnormal). The denormal path resets to +// the un-normalized mant0/exp0 and only right-shifts, which is the wrong +// direction when mant0 < 1<>= 1 @@ -179,6 +187,11 @@ func fpack32(sign, mant uint32, exp int, trunc uint32) uint32 { } // repeat expecting denormal mant, exp, trunc = mant0, exp0, trunc0 + // gnolang/gno#5806: see fpack64 above. + for mant < 1<>= 1 diff --git a/gnovm/pkg/gnolang/internal/softfloat/runtime_softfloat64_test.go b/gnovm/pkg/gnolang/internal/softfloat/runtime_softfloat64_test.go index 70c76655a97..622616a011c 100644 --- a/gnovm/pkg/gnolang/internal/softfloat/runtime_softfloat64_test.go +++ b/gnovm/pkg/gnolang/internal/softfloat/runtime_softfloat64_test.go @@ -47,6 +47,10 @@ func TestFloat64(t *testing.T) { 1.3333333333333333, // 1.010101010101... 1.1428571428571428, // 1.001001001001... 1.112536929253601e-308, // first normal + // gnolang/gno#5806: two near-equal opposite-sign normals whose sum + // cancels into a subnormal; exercises the fpack64 denormal path. + math.Float64frombits(9333378022939403091), + math.Float64frombits(110005986185704326), 2, 4, 8,