[llvm] [SjLjEHPrepare] Configure call sites correctly (PR #117656)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 25 17:14:24 PST 2024


https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/117656

>From a89eed940058260cff1d18129e73b4aa78719a09 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 26 Nov 2024 04:04:43 +0300
Subject: [PATCH 1/2] [SjLjEHPrepare] Configure call sites correctly

After 9fe78db4, the pass inserts `store volatile i32 -1, ptr %call_site`
before all invoke instruction except the one in the entry block, which
has the effect of bypassing landing pads on exceptions.

When configuring the call site for a potentially throwing instruction
check that it is not `InvokeInst` -- they are handled by earlier code.
---
 llvm/lib/CodeGen/SjLjEHPrepare.cpp            | 11 +++--
 .../ARM/sjljehprepare-lower-empty-struct.ll   |  4 ++
 llvm/test/CodeGen/Generic/sjlj-eh-prepare.ll  | 40 +++++++++++++++++++
 .../X86/indirect-branch-tracking-eh2.ll       |  4 +-
 llvm/test/CodeGen/X86/sjlj-eh.ll              |  6 +--
 5 files changed, 53 insertions(+), 12 deletions(-)
 create mode 100644 llvm/test/CodeGen/Generic/sjlj-eh-prepare.ll

diff --git a/llvm/lib/CodeGen/SjLjEHPrepare.cpp b/llvm/lib/CodeGen/SjLjEHPrepare.cpp
index c10c74011955a1..9630ba4307cd21 100644
--- a/llvm/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/llvm/lib/CodeGen/SjLjEHPrepare.cpp
@@ -435,6 +435,10 @@ bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) {
   // where to look for it.
   Builder.CreateCall(FuncCtxFn, FuncCtx);
 
+  // Register the function context and make sure it's known to not throw.
+  CallInst *Register = Builder.CreateCall(RegisterFn, FuncCtx, "");
+  Register->setDoesNotThrow();
+
   // At this point, we are all set up, update the invoke instructions to mark
   // their call_site values.
   for (unsigned I = 0, E = Invokes.size(); I != E; ++I) {
@@ -457,15 +461,10 @@ bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) {
     if (&BB == &F.front())
       continue;
     for (Instruction &I : BB)
-      if (I.mayThrow())
+      if (!isa<InvokeInst>(I) && I.mayThrow())
         insertCallSiteStore(&I, -1);
   }
 
-  // Register the function context and make sure it's known to not throw
-  CallInst *Register = CallInst::Create(
-      RegisterFn, FuncCtx, "", EntryBB->getTerminator()->getIterator());
-  Register->setDoesNotThrow();
-
   // Following any allocas not in the entry block, update the saved SP in the
   // jmpbuf to the new value.
   for (BasicBlock &BB : F) {
diff --git a/llvm/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll b/llvm/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll
index d691a7891e97ca..5b6dd39df0db2d 100644
--- a/llvm/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll
+++ b/llvm/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll
@@ -16,11 +16,15 @@
 define ptr @foo(i8 %a, {} %c) personality ptr @baz {
 entry:
 ; CHECK: bl __Unwind_SjLj_Register
+; CHECK-NEXT: mov r0, #1
+; CHECK-NEXT: str r0, [sp, #{{[0-9]+}}]
 ; CHECK-NEXT: {{[A-Z][a-zA-Z0-9]*}}:
 ; CHECK-NEXT: bl _bar
 ; CHECK: bl __Unwind_SjLj_Resume
 
 ; CHECK-LINUX: bl _Unwind_SjLj_Register
+; CHECK-LINUX-NEXT: mov r0, #1
+; CHECK-LINUX-NEXT: str r0, [sp, #{{[0-9]+}}]
 ; CHECK-LINUX-NEXT: .{{[A-Z][a-zA-Z0-9]*}}:
 ; CHECK-LINUX-NEXT: bl bar
 ; CHECK-LINUX: bl _Unwind_SjLj_Resume
diff --git a/llvm/test/CodeGen/Generic/sjlj-eh-prepare.ll b/llvm/test/CodeGen/Generic/sjlj-eh-prepare.ll
new file mode 100644
index 00000000000000..6efed09ea520b6
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/sjlj-eh-prepare.ll
@@ -0,0 +1,40 @@
+; RUN: opt -p sjlj-eh-prepare %s -S -o - | FileCheck %s
+
+; Check that callsites are set up correctly:
+; 1. Throwing call in the entry block does not set call_site
+;    (function context hasn't been configured yet).
+; 2. Throwing call not in the entry block sets call_site to -1
+;    (reset to the initial state).
+; 3. Invoke instructions set call_site to the correct call site number.
+; 4. Resume instruction sets call_site to -1 (reset to the initial state).
+
+define void @test_call_sites() personality ptr @__gxx_personality_sj0 {
+entry:
+  ; CHECK-NOT: store volatile
+  ; CHECK:     call void @may_throw()
+  call void @may_throw()
+
+  ; CHECK:      store volatile i32 1
+  ; CHECK-NEXT: call void @llvm.eh.sjlj.callsite(i32 1)
+  ; CHECK-NEXT: invoke void @may_throw()
+  invoke void @may_throw() to label %invoke.cont unwind label %lpad
+
+invoke.cont:
+  ; CHECK:      store volatile i32 2
+  ; CHECK-NEXT: call void @llvm.eh.sjlj.callsite(i32 2)
+  ; CHECK-NEXT: invoke void @may_throw()
+  invoke void @may_throw() to label %try.cont unwind label %lpad
+
+lpad:
+  ; CHECK:      store volatile i32 -1
+  ; CHECK-NEXT: resume
+  %lp = landingpad { ptr, i32 } cleanup
+  resume { ptr, i32 } %lp
+
+try.cont:
+  call void @may_throw()
+  ret void
+}
+
+declare void @may_throw()
+declare i32 @__gxx_personality_sj0(...)
diff --git a/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
index 01234317ce834b..1c48e8c5814464 100644
--- a/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
+++ b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
@@ -24,9 +24,9 @@ define dso_local i32 @main() #0 personality ptr @__gxx_personality_sj0 {
 ; NUM-NEXT:    movq %rbp, -104(%rbp)
 ; NUM-NEXT:    movq %rsp, -88(%rbp)
 ; NUM-NEXT:    movq $.LBB0_9, -96(%rbp)
-; NUM-NEXT:    movl $1, -144(%rbp)
 ; NUM-NEXT:    leaq -152(%rbp), %rdi
 ; NUM-NEXT:    callq _Unwind_SjLj_Register at PLT
+; NUM-NEXT:    movl $1, -144(%rbp)
 ; NUM-NEXT:  .Ltmp0:
 ; NUM-NEXT:    callq _Z3foov
 ; NUM-NEXT:  .Ltmp1:
@@ -110,9 +110,9 @@ define dso_local i32 @main() #0 personality ptr @__gxx_personality_sj0 {
 ; SJLJ-NEXT:    movq %rbp, -104(%rbp)
 ; SJLJ-NEXT:    movq %rsp, -88(%rbp)
 ; SJLJ-NEXT:    movq $.LBB0_9, -96(%rbp)
-; SJLJ-NEXT:    movl $1, -144(%rbp)
 ; SJLJ-NEXT:    leaq -152(%rbp), %rdi
 ; SJLJ-NEXT:    callq _Unwind_SjLj_Register at PLT
+; SJLJ-NEXT:    movl $1, -144(%rbp)
 ; SJLJ-NEXT:  .Ltmp0:
 ; SJLJ-NEXT:    callq _Z3foov
 ; SJLJ-NEXT:  .Ltmp1:
diff --git a/llvm/test/CodeGen/X86/sjlj-eh.ll b/llvm/test/CodeGen/X86/sjlj-eh.ll
index 84f0088fa71eec..d2dcb35a4908ef 100644
--- a/llvm/test/CodeGen/X86/sjlj-eh.ll
+++ b/llvm/test/CodeGen/X86/sjlj-eh.ll
@@ -48,14 +48,13 @@ try.cont:
 ; CHECK: movl %esp, -24(%ebp)
 ;     UFC.__jbuf[1] = $EIP
 ; CHECK: movl $[[RESUME:LBB[0-9]+_[0-9]+]], -28(%ebp)
-;     UFC.__callsite = 1
-; CHECK: movl $1, -60(%ebp)
 ;     _Unwind_SjLj_Register(&UFC);
 ; CHECK: leal -64(%ebp), %eax
 ; CHECK: pushl %eax
 ; CHECK: calll __Unwind_SjLj_Register
 ; CHECK: addl $4, %esp
 ;     function_that_throws();
+; CHECK: movl $1, -60(%ebp)
 ; CHECK: calll __Z20function_that_throwsv
 ;     _Unwind_SjLj_Unregister(&UFC);
 ; CHECK: leal -64(%ebp), %eax
@@ -99,12 +98,11 @@ try.cont:
 ;     UFC.__jbuf[1] = $RIP
 ; CHECK-X64: leaq .[[RESUME:LBB[0-9]+_[0-9]+]](%rip), %rax
 ; CHECK-X64: movq %rax, -256(%rbp)
-;     UFC.__callsite = 1
-; CHECK-X64: movl $1, -304(%rbp)
 ;     _Unwind_SjLj_Register(&UFC);
 ; CHECK-X64: leaq -312(%rbp), %rcx
 ; CHECK-X64: callq _Unwind_SjLj_Register
 ;     function_that_throws();
+; CHECK-X64: movl $1, -304(%rbp)
 ; CHECK-X64: callq _Z20function_that_throwsv
 ;     _Unwind_SjLj_Unregister(&UFC);
 ; CHECK-X64: leaq -312(%rbp), %rcx

>From 3c823a230f06daa1b12703a849e4cfcc7e3b8c92 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 26 Nov 2024 04:14:12 +0300
Subject: [PATCH 2/2] Update VE tests

---
 llvm/test/CodeGen/VE/Scalar/builtin_sjlj_callsite.ll   | 8 ++++----
 llvm/test/CodeGen/VE/Scalar/builtin_sjlj_landingpad.ll | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_callsite.ll b/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_callsite.ll
index 67237625ad2071..190d9af3fe0db2 100644
--- a/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_callsite.ll
+++ b/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_callsite.ll
@@ -52,13 +52,13 @@ define void @test_callsite() personality ptr @__gxx_personality_sj0 {
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lea.sl %s0, .LBB0_3 at hi(, %s0)
 ; CHECK-NEXT:    st %s0, -32(, %s9)
-; CHECK-NEXT:    or %s0, 1, (0)1
-; CHECK-NEXT:    st %s0, -96(, %s9)
 ; CHECK-NEXT:    lea %s0, _Unwind_SjLj_Register at lo
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lea.sl %s12, _Unwind_SjLj_Register at hi(, %s0)
 ; CHECK-NEXT:    lea %s0, -104(, %s9)
 ; CHECK-NEXT:    bsic %s10, (, %s12)
+; CHECK-NEXT:    or %s0, 1, (0)1
+; CHECK-NEXT:    st %s0, -96(, %s9)
 ; CHECK-NEXT:  .Ltmp0:
 ; CHECK-NEXT:    lea %s0, f at lo
 ; CHECK-NEXT:    and %s0, %s0, (32)0
@@ -172,14 +172,14 @@ define void @test_callsite() personality ptr @__gxx_personality_sj0 {
 ; PIC-NEXT:    and %s0, %s0, (32)0
 ; PIC-NEXT:    lea.sl %s0, .LBB0_3 at gotoff_hi(%s0, %s15)
 ; PIC-NEXT:    st %s0, -32(, %s9)
-; PIC-NEXT:    or %s0, 1, (0)1
-; PIC-NEXT:    st %s0, -96(, %s9)
 ; PIC-NEXT:    lea %s12, _Unwind_SjLj_Register at plt_lo(-24)
 ; PIC-NEXT:    and %s12, %s12, (32)0
 ; PIC-NEXT:    sic %s16
 ; PIC-NEXT:    lea.sl %s12, _Unwind_SjLj_Register at plt_hi(%s16, %s12)
 ; PIC-NEXT:    lea %s0, -104(, %s9)
 ; PIC-NEXT:    bsic %s10, (, %s12)
+; PIC-NEXT:    or %s0, 1, (0)1
+; PIC-NEXT:    st %s0, -96(, %s9)
 ; PIC-NEXT:  .Ltmp0:
 ; PIC-NEXT:    lea %s12, f at plt_lo(-24)
 ; PIC-NEXT:    and %s12, %s12, (32)0
diff --git a/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_landingpad.ll b/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_landingpad.ll
index 7de0dfd68d6179..f255be5eecb990 100644
--- a/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_landingpad.ll
+++ b/llvm/test/CodeGen/VE/Scalar/builtin_sjlj_landingpad.ll
@@ -53,13 +53,13 @@ define dso_local i32 @foo(i32 %arg) local_unnamed_addr personality ptr @__gxx_pe
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lea.sl %s0, .LBB0_3 at hi(, %s0)
 ; CHECK-NEXT:    st %s0, -32(, %s9)
-; CHECK-NEXT:    or %s0, 1, (0)1
-; CHECK-NEXT:    st %s0, -96(, %s9)
 ; CHECK-NEXT:    lea %s0, _Unwind_SjLj_Register at lo
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lea.sl %s12, _Unwind_SjLj_Register at hi(, %s0)
 ; CHECK-NEXT:    lea %s0, -104(, %s9)
 ; CHECK-NEXT:    bsic %s10, (, %s12)
+; CHECK-NEXT:    or %s0, 1, (0)1
+; CHECK-NEXT:    st %s0, -96(, %s9)
 ; CHECK-NEXT:  .Ltmp0:
 ; CHECK-NEXT:    lea %s0, errorbar at lo
 ; CHECK-NEXT:    and %s0, %s0, (32)0
@@ -175,14 +175,14 @@ define dso_local i32 @foo(i32 %arg) local_unnamed_addr personality ptr @__gxx_pe
 ; PIC-NEXT:    and %s0, %s0, (32)0
 ; PIC-NEXT:    lea.sl %s0, .LBB0_3 at gotoff_hi(%s0, %s15)
 ; PIC-NEXT:    st %s0, -32(, %s9)
-; PIC-NEXT:    or %s0, 1, (0)1
-; PIC-NEXT:    st %s0, -96(, %s9)
 ; PIC-NEXT:    lea %s12, _Unwind_SjLj_Register at plt_lo(-24)
 ; PIC-NEXT:    and %s12, %s12, (32)0
 ; PIC-NEXT:    sic %s16
 ; PIC-NEXT:    lea.sl %s12, _Unwind_SjLj_Register at plt_hi(%s16, %s12)
 ; PIC-NEXT:    lea %s0, -104(, %s9)
 ; PIC-NEXT:    bsic %s10, (, %s12)
+; PIC-NEXT:    or %s0, 1, (0)1
+; PIC-NEXT:    st %s0, -96(, %s9)
 ; PIC-NEXT:  .Ltmp0:
 ; PIC-NEXT:    lea %s12, errorbar at plt_lo(-24)
 ; PIC-NEXT:    and %s12, %s12, (32)0



More information about the llvm-commits mailing list