This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Make Emscripten EH work with Emscripten SjLj
ClosedPublic

Authored by aheejin on Jul 21 2021, 10:53 PM.

Details

Summary

When Emscripten EH mixes with Emscripten SjLj, we are not currently
handling some of them correctly. There are three cases:

  1. The current function calls setjmp and there is an invoke to a function that can either throw or longjmp. In this case, we have to check both for exception and longjmp. We are currently handling this case correctly: https://github.com/llvm/llvm-project/blob/0c0eb76782d5224b8d81a5afbb9a152bcf7c94c7/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp#L1058-L1090 When inserting routines for functions that can longjmp, which we do only for setjmp-calling functions, we check if the function was previously an invoke and handle it correctly.
  1. The current function does NOT call setjmp and there is an invoke to a function that can either throw or longjmp. Because there is no setjmp call, we haven't been doing any check for functions that can longjmp. But in that case, for invoke, we only check for an exception and if it is not an exception we reset __THREW__ to 0, which can silently swallow the longjmp: https://github.com/llvm/llvm-project/blob/0c0eb76782d5224b8d81a5afbb9a152bcf7c94c7/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp#L70-L80 This CL fixes this.
  1. The current function calls setjmp and there is no invoke. Because it is not an invoke, we haven't been doing any check for functions that can throw, and only insert longjmp-checking routines for functions that can longjmp. But in that case, if a longjmpable function throws, we only check for a longjmp so if it is not a longjmp we reset __THREW__ to 0, which can silently swallow the exception: https://github.com/llvm/llvm-project/blob/0c0eb76782d5224b8d81a5afbb9a152bcf7c94c7/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp#L156-L169 This CL fixes this.

To do that, this moves around some code, so we register necessary
functions for both EH and SjLj and precompute some data (the set of
functions that contains setjmp) before doing actual EH or SjLj
transformation.

Diff Detail

Event Timeline

aheejin created this revision.Jul 21 2021, 10:53 PM
aheejin requested review of this revision.Jul 21 2021, 10:53 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 21 2021, 10:53 PM
aheejin added inline comments.Jul 21 2021, 10:59 PM
llvm/lib/Target/WebAssembly/WebAssembly.h
28–30

We are using DoSjLj and EnableSjLj for different meanings in the pass. EnableSjLj is true by default in Emscripten setting, but DoSjLj is true only when setjmp or longjmp is really used. This was confusing so I changed it to Enable.

llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
219

This was a local variable; I needed to access this from multiple functions so I hoisted it here.

238–239

This was a local variable too. It was computed right before we run runSjLjOnFunction, but now we precompute this because we need to access this also within runEHOnFunction.

aheejin updated this revision to Diff 360708.Jul 21 2021, 11:00 PM

Remove a newline

llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
104

This test has been moved to lower-em-ehsjlj.ll

aheejin planned changes to this revision.Jul 22 2021, 1:11 AM

Some more tests need fixing.

aheejin updated this revision to Diff 360906.Jul 22 2021, 11:35 AM

Tests fix

aheejin added inline comments.Jul 22 2021, 11:37 AM
llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
248–250

This file is only for testing sjlj, so I made this nounwind. Mixed exceptions and sjlj cases are tested in lower-em-ehsjlj.ll.

dschuff accepted this revision.Jul 23 2021, 3:27 PM
dschuff added inline comments.
llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
238
786
834

I think this first sentence would be clearer as "the thrown value can be either an exception or a longjmp", or "could be a longjmp instead of an exception". Likewise in the comment below.

This revision is now accepted and ready to land.Jul 23 2021, 3:27 PM
This revision was landed with ongoing or failed builds.Jul 26 2021, 1:50 PM
This revision was automatically updated to reflect the committed changes.