This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Prevent inline assembly from being mangled by SjLj
ClosedPublic

Authored by quantum on Jul 2 2019, 5:23 PM.

Details

Summary

Before, inline assembly gets mangled by the SjLj transformation.

For example, in a function with setjmp/longjmp, this LLVM IR code

call void asm sideeffect "", ""()

would be transformed into

call void @__invoke_void(void ()* asm sideeffect "", "")

This is invalid, and results in the error:

Cannot take the address of an inline asm!

In this diff, we skip the transformation for inline assembly.

Event Timeline

quantum created this revision.Jul 2 2019, 5:23 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 2 2019, 5:23 PM
tlively accepted this revision.Jul 2 2019, 5:29 PM

LGTM with a quick explanatory comment!

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

Please add a comment about why InlineAsm needs to be skipped.

This revision is now accepted and ready to land.Jul 2 2019, 5:29 PM
sbc100 accepted this revision.Jul 2 2019, 5:29 PM
sbc100 added inline comments.
llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
971

Why move this into calLongjmp?

tlively added inline comments.Jul 2 2019, 5:32 PM
llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
971

That seems like a good idea.

quantum updated this revision to Diff 207669.Jul 2 2019, 5:36 PM
quantum marked 3 inline comments as done.

Moved into canLongjmp and added comments.

Applied suggestions.

This revision was automatically updated to reflect the committed changes.
aheejin added a comment.EditedJul 2 2019, 5:39 PM

Doesn't this only prevent longjmp from generated? Shouldn't we also prevent exception-related invokes from generated?

Thank you for fixing this. This pass does two things: exception handling and setjmp-longjmp handling. This CL only fixes setjmp-longjmp. Could you fix the exception case too if that's not too much of a burden? You can fix the NeedInvoke part as I told you before. This is basically my bug so I can do it too, in case it takes time though.

llvm/trunk/test/CodeGen/WebAssembly/lower-em-sjlj.ll
192 ↗(On Diff #207671)

Nit: please delete hidden and #0

210 ↗(On Diff #207671)

We can simplify this test case further: We don't need longjmp in the same function to test this. You can refer to setjmp_other function in this file; you can make this as a single BB function, replacing the call to foo with your inline asm call, because with a few exceptions, most function calls in the same function as setjmp are turned into invokes.

I don't think this is actually a problem in the exception case. To call something that throws, you'd use invoke instead of call, but inline assembly is generated with call and not invoke.

Hmm right, invokes don't seem to be generated from inline assembly except for handwritten test cases.