-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Closed
Copy link
Labels
backend:WebAssemblyclang:codegenIR generation bugs: mangling, exceptions, etc.IR generation bugs: mangling, exceptions, etc.miscompilation
Description
- Miscompiled:
void loud();
void throw_and_catch(void *ex) {
try {
__builtin_wasm_throw(0, ex);
} catch (...) {
loud();
}
}
The generated IR is
define hidden void @throw_and_catch(void*)(ptr noundef %ex) {
entry:
%ex.addr = alloca ptr, align 4
store ptr %ex, ptr %ex.addr, align 4
%0 = load ptr, ptr %ex.addr, align 4
call void @llvm.wasm.throw(i32 0, ptr %0)
ret void
}
without a catchpad.
https://godbolt.org/z/Po668Yxaz
- Broken IR:
void loud();
void my_throw(void *ex) {
__builtin_wasm_throw(0, ex);
}
void throw_and_catch(void *ex) {
try {
my_throw(ex);
} catch (...) {
loud();
}
}
InlinerPass replaces
invoke void @my_throw(void*)(ptr noundef %ex)
to label %try.cont unwind label %catch.dispatch
(correct, working) with
invoke void @llvm.wasm.throw(i32 0, ptr %ex)
to label %.noexc unwind label %catch.dispatch
(broken, llvm.wasm.throw
cannot be invoked), which halts the backend.
https://godbolt.org/z/rMEd1x79z
As far as I'm aware, llvm.wasm.throw
is the only function that can unwind but cannot be invoked, making this troublesome for external frontends like rustc, not just for optimization passes. Ideally it would become invocable.
Metadata
Metadata
Assignees
Labels
backend:WebAssemblyclang:codegenIR generation bugs: mangling, exceptions, etc.IR generation bugs: mangling, exceptions, etc.miscompilation