Stream: git-wasmtime

Topic: wasmtime / issue #10920 Cranelift: Mismatch in NaN sign b...


view this post on Zulip Wasmtime GitHub notifications bot (Jun 04 2025 at 08:56):

akldc opened issue #10920:

.clif Test Case

test optimize
    set opt_level=none
    set preserve_frame_pointers=true
    set enable_multi_ret_implicit_sret=true

function %main() -> f64, f64, f64x2 fast {
    const0 = 0xa10eeae6031066b4994dac7a4d95f48a

block0:
    v1 = f64const 0x1.a07b57b0c0570p-3
    v2 = fsub.f64 v1, v1
    v3 = fdiv.f64 v2, v2

    v4 = vconst.f64x2 const0
    v5 = sqrt.f64x2 v4  ; v15 = const0
    return v2,v3,v5
}

; print: %main()

Run this IR on three architectures: x86, aarch64 and s390x.

[x86    ] %main() -> [0.0, -NaN, 0xfff8000000000000fff8000000000000]
[aarch64] %main() -> [0.0, +NaN, 0x7ff80000000000007ff8000000000000]
[s390x  ] %main() -> [0.0, +NaN, 0x7ff80000000000007ff8000000000000]

For v3, there’s a difference in the sign of NaN across architectures.
For v5, the sqrt.f64x2 instruction on x86 also shows a sign bit that differs from the other two.

Extra Info

The following example also shows some inconsistent results.

test optimize
    set opt_level=none
    set preserve_frame_pointers=true
    set enable_multi_ret_implicit_sret=true

function %main() -> f64 fast {

block0:
    v7 = f64const 0x1.11044b092d153p-1
    v8 = bxor_not v7, v7
    v12 = fsub.f64 v8, v7
    return v12
}

; print: %main()
[x86    ] %main() -> -NaN:0x7ffffffffffff
[riscv64] %main() -> +NaN

view this post on Zulip Wasmtime GitHub notifications bot (Jun 04 2025 at 08:56):

akldc added the bug label to Issue #10920.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 04 2025 at 08:56):

akldc added the cranelift label to Issue #10920.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 04 2025 at 09:17):

bjorn3 commented on issue #10920:

This is expected. Architectures handle NaN differently. Wasm even chose to make the NaN representation non-deterministic for this reason. If you want deterministic NaN you can enable the enable_nan_canonicalization flag.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 04 2025 at 09:17):

bjorn3 edited a comment on issue #10920:

This is expected. Architectures handle NaN differently. Wasm even chose to make the NaN representation non-deterministic for this reason. If you want deterministic NaN you can enable the enable_nan_canonicalization flag to insert extra canonicalization operations.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 04 2025 at 14:28):

akldc commented on issue #10920:

@bjorn3
Thanks for your detailed reply. I'll close this issue.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 04 2025 at 14:28):

akldc closed issue #10920:

.clif Test Case

test optimize
    set opt_level=none
    set preserve_frame_pointers=true
    set enable_multi_ret_implicit_sret=true

function %main() -> f64, f64, f64x2 fast {
    const0 = 0xa10eeae6031066b4994dac7a4d95f48a

block0:
    v1 = f64const 0x1.a07b57b0c0570p-3
    v2 = fsub.f64 v1, v1
    v3 = fdiv.f64 v2, v2

    v4 = vconst.f64x2 const0
    v5 = sqrt.f64x2 v4  ; v15 = const0
    return v2,v3,v5
}

; print: %main()

Run this IR on three architectures: x86, aarch64 and s390x.

[x86    ] %main() -> [0.0, -NaN, 0xfff8000000000000fff8000000000000]
[aarch64] %main() -> [0.0, +NaN, 0x7ff80000000000007ff8000000000000]
[s390x  ] %main() -> [0.0, +NaN, 0x7ff80000000000007ff8000000000000]

For v3, there’s a difference in the sign of NaN across architectures.
For v5, the sqrt.f64x2 instruction on x86 also shows a sign bit that differs from the other two.

Extra Info

The following example also shows some inconsistent results.

test optimize
    set opt_level=none
    set preserve_frame_pointers=true
    set enable_multi_ret_implicit_sret=true

function %main() -> f64 fast {

block0:
    v7 = f64const 0x1.11044b092d153p-1
    v8 = bxor_not v7, v7
    v12 = fsub.f64 v8, v7
    return v12
}

; print: %main()
[x86    ] %main() -> -NaN:0x7ffffffffffff
[riscv64] %main() -> +NaN

Last updated: Dec 06 2025 at 06:05 UTC