emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.62k stars 3.28k forks source link

Splitting double to 2xint32 parts in asm.js compatibility causes a wasm trap #5574

Closed juj closed 4 years ago

juj commented 7 years ago

a.cpp:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void printU64(int64_t u64)
{
    printf("u64: %lld\n", u64);
}

void foo(double d)
{
    printU64(d);
}

int main()
{
    foo(rand() ? 1e14 : 1e13);
}

em++ a.cpp -o a.html -s WASM=1 works ok as expected.

However, building with

em++ a.cpp -o a.html -s WASM=1 -s OUTLINING_LIMIT=10000 or em++ a.cpp -o a.html -s WASM=1 -s BINARYEN_METHOD=\"native-wasm,asmjs\"

fails with exception thrown: RuntimeError: integer overflow.

kripken commented 7 years ago

This is a known issue: in asm.js compatibility mode, we add extra math operations for such casts, since they are hard to do in js. Here we have

 $2 = +Math_abs($0) >= 1.0 ? $0 > 0.0 ? (~~+Math_min(+Math_floor($0 / 4294967296.0), 4294967295.0)) >>> 0 : ~~+Math_ceil(($0 - +(~~$0 >>> 0)) / 4294967296.0) >>> 0 : 0; //@line 12 "a.cpp"

And some of those intermediate ops can trap in wasm. Setting the trap mode to clamp avoids it.

I admit this is confusing, but not sure what else we can do. It's a downside of setting the default trap mode to allow/fast.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because there has been no activity in the past 2 years. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.