[PATCH] D109669: [WebAssembly] Handle _setjmp and _longjmp in SjLj

Heejin Ahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 13 14:20:30 PDT 2021


aheejin updated this revision to Diff 372344.
aheejin marked an inline comment as done.
aheejin added a comment.

Change to `report_fatal_error`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109669

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
@@ -282,12 +282,30 @@
   ret void
 }
 
+; Test if _setjmp and _longjmp calls are treated in the same way as setjmp and
+; longjmp
+define void @_setjmp__longjmp() {
+; CHECK-LABEL: @_setjmp__longjmp
+; These calls should have been transformed away
+; CHECK-NOT: call i32 @_setjmp
+; CHECK-NOT: call void @_longjmp
+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
+  %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
+  call void @_longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1
+  unreachable
+}
+
 ; Function Attrs: nounwind
 declare void @foo() #2
 ; Function Attrs: returns_twice
 declare i32 @setjmp(%struct.__jmp_buf_tag*) #0
+declare i32 @_setjmp(%struct.__jmp_buf_tag*) #0
 ; Function Attrs: noreturn
 declare void @longjmp(%struct.__jmp_buf_tag*, i32) #1
+declare void @_longjmp(%struct.__jmp_buf_tag*, i32) #1
 declare i32 @__gxx_personality_v0(...)
 declare i8* @__cxa_begin_catch(i8*)
 declare void @__cxa_end_catch()
Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -831,6 +831,33 @@
   Function *SetjmpF = M.getFunction("setjmp");
   Function *LongjmpF = M.getFunction("longjmp");
 
+  // In some platforms _setjmp and _longjmp are used instead. Change these to
+  // use setjmp/longjmp instead, because we laster detect these functions by
+  // their names.
+  Function *SetjmpF2 = M.getFunction("_setjmp");
+  Function *LongjmpF2 = M.getFunction("_longjmp");
+  if (SetjmpF2) {
+    if (SetjmpF) {
+      if (SetjmpF->getFunctionType() != SetjmpF2->getFunctionType())
+        report_fatal_error("setjmp and _setjmp have different function types");
+    } else {
+      SetjmpF = Function::Create(SetjmpF2->getFunctionType(),
+                                 GlobalValue::ExternalLinkage, "setjmp", M);
+    }
+    SetjmpF2->replaceAllUsesWith(SetjmpF);
+  }
+  if (LongjmpF2) {
+    if (LongjmpF) {
+      if (LongjmpF->getFunctionType() != LongjmpF2->getFunctionType())
+        report_fatal_error(
+            "longjmp and _longjmp have different function types");
+    } else {
+      LongjmpF = Function::Create(LongjmpF2->getFunctionType(),
+                                  GlobalValue::ExternalLinkage, "setjmp", M);
+    }
+    LongjmpF2->replaceAllUsesWith(LongjmpF);
+  }
+
   auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
   assert(TPC && "Expected a TargetPassConfig");
   auto &TM = TPC->getTM<WebAssemblyTargetMachine>();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109669.372344.patch
Type: text/x-patch
Size: 3093 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210913/ebb10aa2/attachment.bin>


More information about the llvm-commits mailing list