[PATCH] D118274: [WebAssembly] Don't copy noreturn attr to invokes

Heejin Ahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 26 12:14:54 PST 2022


aheejin updated this revision to Diff 403368.
aheejin added a comment.

Remove a blank line


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118274/new/

https://reviews.llvm.org/D118274

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


Index: llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll
+++ llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll
@@ -7,6 +7,7 @@
 target triple = "wasm32-unknown-unknown"
 
 %struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] }
+ at _ZTIi = external constant i8*
 
 ; There is a function call (@foo) that can either throw an exception or longjmp
 ; and there is also a setjmp call. When @foo throws, we have to check both for
@@ -218,6 +219,54 @@
 ; CHECK-NEXT: unreachable
 }
 
+; int jmpval = setjmp(buf);
+; if (jmpval != 0)
+;   return;
+; try {
+;   throw 3;
+; } catch (...) {
+; }
+define void @setjmp_with_throw_try_catch() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; CHECK-LABEL: @setjmp_with_throw_try_catch
+entry:
+  %buf = alloca [1 x %struct.__jmp_buf_tag], align 16
+  %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
+  %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0
+  %cmp = icmp ne i32 %call, 0
+  br i1 %cmp, label %try.cont, label %if.end
+
+if.end:                                           ; preds = %entry
+  %exception = call i8* @__cxa_allocate_exception(i32 4) #2
+  %0 = bitcast i8* %exception to i32*
+  store i32 3, i32* %0, align 16
+  invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #1
+          to label %unreachable unwind label %lpad
+; When invoke @__cxa_throw is converted to a call to the invoke wrapper,
+; "noreturn" attribute should be removed, and there should be no 'free' call
+; before the call. We insert a 'free' call that frees 'setjmpTable' before every
+; function-exiting instruction. And invoke wrapper calls shouldn't be treated as
+; noreturn instructions, because they are supposed to return.
+; CHECK:   if.end:
+; CHECK-NOT: tail call void @free
+; CHECK-NOT: call cc99 void @"__invoke_void_i8*_i8*_i8*"(void (i8*, i8*, i8*)* @__cxa_throw, i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #
+; CHECK:     call cc99 void @"__invoke_void_i8*_i8*_i8*"(void (i8*, i8*, i8*)* @__cxa_throw, i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+
+lpad:                                             ; preds = %if.end
+  %1 = landingpad { i8*, i32 }
+          catch i8* null
+  %2 = extractvalue { i8*, i32 } %1, 0
+  %3 = extractvalue { i8*, i32 } %1, 1
+  %4 = call i8* @__cxa_begin_catch(i8* %2) #2
+  call void @__cxa_end_catch()
+  br label %try.cont
+
+try.cont:                                         ; preds = %entry, %lpad
+  ret void
+
+unreachable:                                      ; preds = %if.end
+  unreachable
+}
+
 declare void @foo()
 ; Function Attrs: returns_twice
 declare i32 @setjmp(%struct.__jmp_buf_tag*)
@@ -227,6 +276,8 @@
 declare i8* @__cxa_begin_catch(i8*)
 declare void @__cxa_end_catch()
 declare void @__cxa_throw(i8*, i8*, i8*)
+declare i8* @__cxa_allocate_exception(i32)
 
 attributes #0 = { returns_twice }
 attributes #1 = { noreturn }
+attributes #2 = { nounwind }
Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -560,6 +560,9 @@
       NEltArg = NEltArg.getValue() + 1;
     FnAttrs.addAllocSizeAttr(SizeArg, NEltArg);
   }
+  // In case the callee has 'noreturn' attribute, We need to remove it, because
+  // we expect invoke wrappers to return.
+  FnAttrs.removeAttribute(Attribute::NoReturn);
 
   // Reconstruct the AttributesList based on the vector we constructed.
   AttributeList NewCallAL = AttributeList::get(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D118274.403368.patch
Type: text/x-patch
Size: 3832 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220126/b6169299/attachment.bin>


More information about the llvm-commits mailing list