[PATCH] D64115: [WebAssembly] Prevent inline assembly from being mangled by SjLj

Guanzhong Chen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 2 17:23:24 PDT 2019


quantum created this revision.
quantum added reviewers: aheejin, tlively.
Herald added subscribers: llvm-commits, sunfish, hiraditya, jgravelle-google, sbc100, dschuff.
Herald added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64115

Files:
  llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
  llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll


Index: llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
+++ llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
@@ -188,6 +188,27 @@
 ; 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
Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -961,7 +961,7 @@
         continue;
 
       const Value *Callee = CI->getCalledValue();
-      if (!canLongjmp(M, Callee))
+      if (!canLongjmp(M, Callee) || isa<InlineAsm>(Callee))
         continue;
 
       Value *Threw = nullptr;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D64115.207667.patch
Type: text/x-patch
Size: 1831 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190703/35448f86/attachment-0001.bin>


More information about the llvm-commits mailing list