forked from OSchip/llvm-project
[WebAssembly] Prevent inline assembly from being mangled by SjLj
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. Reviewers: aheejin, tlively Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64115 llvm-svn: 364985
This commit is contained in:
parent
4f3472deb2
commit
b88ebe8cc9
|
@ -485,6 +485,13 @@ bool WebAssemblyLowerEmscriptenEHSjLj::canLongjmp(Module &M,
|
|||
if (CalleeF->isIntrinsic())
|
||||
return false;
|
||||
|
||||
// Attempting to transform inline assembly will result in something like:
|
||||
// call void @__invoke_void(void ()* asm ...)
|
||||
// which is invalid because inline assembly blocks do not have addresses
|
||||
// and can't be passed by pointer. The result is a crash with illegal IR.
|
||||
if (isa<InlineAsm>(Callee))
|
||||
return false;
|
||||
|
||||
// The reason we include malloc/free here is to exclude the malloc/free
|
||||
// calls generated in setjmp prep / cleanup routines.
|
||||
Function *SetjmpF = M.getFunction("setjmp");
|
||||
|
|
|
@ -188,6 +188,27 @@ entry:
|
|||
; CHECK-NEXT: call void @emscripten_longjmp_jmpbuf(%struct.__jmp_buf_tag* %[[ARRAYDECAY]], i32 5) #1
|
||||
}
|
||||
|
||||
; Test inline asm handling
|
||||
define hidden void @inline_asm() #0 {
|
||||
; CHECK-LABEL: @inline_asm
|
||||
entry:
|
||||
%env = alloca [1 x %struct.__jmp_buf_tag], align 16
|
||||
%arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %env, i32 0, i32 0
|
||||
%call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #4
|
||||
%cmp = icmp eq i32 %call, 0
|
||||
br i1 %cmp, label %if.then, label %if.else
|
||||
|
||||
if.then: ; preds = %entry
|
||||
; CHECK: call void asm sideeffect "", ""()
|
||||
call void asm sideeffect "", ""()
|
||||
%arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %env, i32 0, i32 0
|
||||
call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #5
|
||||
unreachable
|
||||
|
||||
if.else: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @foo()
|
||||
; Function Attrs: returns_twice
|
||||
declare i32 @setjmp(%struct.__jmp_buf_tag*) #0
|
||||
|
|
Loading…
Reference in New Issue