Closed
Description
While trying to compile mono, emscripten + binaryen miscompiles the following function:
static inline void
sgen_dummy_use (gpointer v)
{
#if defined(__GNUC__)
__asm__ volatile ("" : "=r"(v) : "r"(v));
#elif defined(_MSC_VER)
static volatile gpointer ptr;
ptr = v;
#else
#error "Implement sgen_dummy_use for your compiler"
#endif
}
I'm using emsdk with the following installed:
emscripten-1.37.22
clang-e1.37.22-64bit
node-4.1.1-64bit
I'm running the compiler this way:
$(EMCC) -g4 -Os -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s "BINARYEN_TRAP_MODE='clamp'" -s TOTAL_MEMORY=134217728 -s ALIASING_FUNCTION_POINTERS=0 --js-library library_mono.js driver.o $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a -o mono.js
It crashes when linking in asm2wasm with this assert:
$3
Assertion failed: (mappedGlobals.find(name) != mappedGlobals.end() ? true : (std::cerr << name.str << '\n', false)), function operator(), file /Users/kumpera/src/wasm/mono/sdks/builds/toolchains/emsdk/binaryen/master/src/asm2wasm.h, line 1544.
I dug into binaryen and this was the backtrace:
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x000000010c329246 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007fb0e7d2f028, ast=Ref @ 0x00007ffee3950418)::$_3::operator()(cashew::Ref) const at asm2wasm.h:1546
frame #1: 0x000000010c328a68 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) [inlined] decltype(__f=0x00007fb0e7d2f028, __args=0x00007ffee3952430)::$_3&>(fp)(std::__1::forward<cashew::Ref>(fp0))) std::__1::__invoke<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at type_traits:4291
frame #2: 0x000000010c328a40 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(__args=0x00007fb0e7d2f028, __args=0x00007ffee3952430)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at __functional_base:328
frame #3: 0x000000010c328909 asm2wasm`std::__1::__function::__func<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3, std::__1::allocator<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3>, wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=0x00007ffee3952430)(cashew::Ref&&) at functional:1552
frame #4: 0x000000010c33c0d9 asm2wasm`std::__1::function<wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=Ref @ 0x00007ffee3952430)(cashew::Ref) const at functional:1911
frame #5: 0x000000010c3304b5 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007fb0e7d2f028, ast=Ref @ 0x00007ffee3955d08)::$_3::operator()(cashew::Ref) const at asm2wasm.h:1945
frame #6: 0x000000010c328a68 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) [inlined] decltype(__f=0x00007fb0e7d2f028, __args=0x00007ffee3957d20)::$_3&>(fp)(std::__1::forward<cashew::Ref>(fp0))) std::__1::__invoke<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at type_traits:4291
frame #7: 0x000000010c328a40 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(__args=0x00007fb0e7d2f028, __args=0x00007ffee3957d20)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at __functional_base:328
frame #8: 0x000000010c328909 asm2wasm`std::__1::__function::__func<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3, std::__1::allocator<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3>, wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=0x00007ffee3957d20)(cashew::Ref&&) at functional:1552
frame #9: 0x000000010c33c0d9 asm2wasm`std::__1::function<wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=Ref @ 0x00007ffee3957d20)(cashew::Ref) const at functional:1911
frame #10: 0x000000010c3518e8 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007ffee3959508, ast=Ref @ 0x00007ffee3957da0, from=2)::$_5::operator()(cashew::Ref, unsigned int) const at asm2wasm.h:2612
frame #11: 0x000000010c3517ca asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&, cashew::Ref, unsigned int>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&&&, cashew::Ref&&, unsigned int&&) [inlined] decltype(__f=0x00007ffee3959508, __args=0x00007ffee3957ec8, __args=0x00007ffee3957ebc)::$_5&>(fp)(std::__1::forward<cashew::Ref, unsigned int>(fp0))) std::__1::__invoke<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&, cashew::Ref, unsigned int>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&&&, cashew::Ref&&, unsigned int&&) at type_traits:4291
frame #12: 0x000000010c351794 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(__args=0x00007ffee3959508, __args=0x00007ffee3957ec8, __args=0x00007ffee3957ebc)::$_5&, cashew::Ref, unsigned int>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&&&, cashew::Ref&&, unsigned int&&) at __functional_base:328
frame #13: 0x000000010c351699 asm2wasm`std::__1::__function::__func<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5, std::__1::allocator<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5>, wasm::Expression* (cashew::Ref, unsigned int)>::operator(this=0x00007ffee3959500, __arg=0x00007ffee3957ec8, __arg=0x00007ffee3957ebc)(cashew::Ref&&, unsigned int&&) at functional:1552
frame #14: 0x000000010c2b07e8 asm2wasm`std::__1::function<wasm::Expression* (cashew::Ref, unsigned int)>::operator(this=0x00007ffee3959500, __arg=Ref @ 0x00007ffee3957ec8, __arg=2)(cashew::Ref, unsigned int) const at functional:1911
* frame #15: 0x000000010c2adae7 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007ffee395bb20, ast=Ref @ 0x00007ffee39585d8) at asm2wasm.h:2618
frame #16: 0x000000010c2a4aaa asm2wasm`wasm::Asm2WasmBuilder::processAsm(this=0x00007ffee395bb20, ast=Ref @ 0x00007ffee395a1a0) at asm2wasm.h:1032
frame #17: 0x000000010c2b55af asm2wasm`main(argc=12, argv=0x00007ffee395e5b0) at asm2wasm.cpp:164
I inspected the bottom processFunction frame, which is how I found out what was the offending function and took the change to call dump on the body. I got this:
foo: [
["$0", [
"binary",
"|",
"$0",
0
]],
[
"var",
[
[
"$1",
0
],
[
"$2",
0
],
[
"label",
0
],
[
"sp",
0
]
]
],
["sp", "STACKTOP"],
["STACKTOP", [
"binary",
"|",
[
"binary",
"+",
"STACKTOP",
16
],
0
]],
["$1", "sp"],
[
"call",
"store4",
[
"$1",
"$0"
]
],
["$2", [
"call",
"load4",
[
"$1"
]
]],
[
"call",
"emscripten_debuginfo",
[
88,
1142
]
],
[
"call",
"emscripten_debuginfo",
[
88,
1142
]
],
[
"call",
"store4",
[
"$1",
"$3"
]
],
[
"call",
"emscripten_debuginfo",
[
88,
1142
]
],
["STACKTOP", "sp"],
[
"return",
null
],
[
"call",
"emscripten_debuginfo",
[
88,
1149
]
]
]
Metadata
Metadata
Assignees
Labels
No labels