[llvm] [WinEH] Take musttail calls into account when unlinking eh records (PR #119702)

via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 12 10:24:51 PST 2024


https://github.com/zmodem updated https://github.com/llvm/llvm-project/pull/119702

>From 718acd5cded2acd10e55107bda084ff12e01611e Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Thu, 12 Dec 2024 14:09:58 +0100
Subject: [PATCH 1/2] [WinEH] Take musttail calls into account when unlinking
 eh records

Exception handling records are unlinked on function return. However, if
there is a musttail call before the return, that's the de-facto point of
termination and the unlinking instructions must be inserted *before*
that.

Fixes #119255
---
 llvm/lib/Target/X86/X86WinEHState.cpp         | 10 ++++++
 .../test/CodeGen/WinEH/wineh-musttail-call.ll | 32 +++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 llvm/test/CodeGen/WinEH/wineh-musttail-call.ll

diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp
index b3e4c70eb57f30..fcbce15564ae37 100644
--- a/llvm/lib/Target/X86/X86WinEHState.cpp
+++ b/llvm/lib/Target/X86/X86WinEHState.cpp
@@ -363,6 +363,16 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
     Instruction *T = BB.getTerminator();
     if (!isa<ReturnInst>(T))
       continue;
+
+    // Back up to any preceding musttail call, the de-facto terminator.
+    Instruction *Prev = T->getPrevNonDebugInstruction();
+    if (isa_and_present<BitCastInst>(Prev))
+      Prev = T->getPrevNonDebugInstruction();
+    if (CallInst *CI = dyn_cast_or_null<CallInst>(Prev)) {
+      if (CI->isMustTailCall())
+        T = CI;
+    }
+
     Builder.SetInsertPoint(T);
     unlinkExceptionRegistration(Builder);
   }
diff --git a/llvm/test/CodeGen/WinEH/wineh-musttail-call.ll b/llvm/test/CodeGen/WinEH/wineh-musttail-call.ll
new file mode 100644
index 00000000000000..7f508090a1bc78
--- /dev/null
+++ b/llvm/test/CodeGen/WinEH/wineh-musttail-call.ll
@@ -0,0 +1,32 @@
+; RUN: llc < %s | FileCheck %s
+
+target triple = "i386-pc-windows-msvc"
+
+; Check that codegen doesn't fail due to wineh inserting instructions between
+; the musttail call and return instruction.
+
+
+define void @test() personality ptr @__CxxFrameHandler3 {
+; CHECK-LABEL: test:
+
+entry:
+  invoke void @foo() to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch:
+  %0 = catchswitch within none [label %catch] unwind to caller
+
+catch:
+  %1 = catchpad within %0 [ptr null, i32 64, ptr null]
+  catchret from %1 to label %try.cont
+
+try.cont:
+; CHECK: movl %{{[a-z0-9]+}}, %fs:0
+; CHECK: jmp _bar
+
+  musttail call void @bar()
+  ret void
+}
+
+declare i32 @__CxxFrameHandler3(...)
+declare void @foo()
+declare void @bar()

>From 24568b055b82c9ac997864b1355580baaf8fb262 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Thu, 12 Dec 2024 19:24:02 +0100
Subject: [PATCH 2/2] use BB.getTerminatingMustTailCall()

---
 llvm/lib/Target/X86/X86WinEHState.cpp | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp
index fcbce15564ae37..35b7d7f508b02f 100644
--- a/llvm/lib/Target/X86/X86WinEHState.cpp
+++ b/llvm/lib/Target/X86/X86WinEHState.cpp
@@ -364,14 +364,9 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
     if (!isa<ReturnInst>(T))
       continue;
 
-    // Back up to any preceding musttail call, the de-facto terminator.
-    Instruction *Prev = T->getPrevNonDebugInstruction();
-    if (isa_and_present<BitCastInst>(Prev))
-      Prev = T->getPrevNonDebugInstruction();
-    if (CallInst *CI = dyn_cast_or_null<CallInst>(Prev)) {
-      if (CI->isMustTailCall())
-        T = CI;
-    }
+    // If there is a musttail call, that's the de-facto terminator.
+    if (CallInst *CI = BB.getTerminatingMustTailCall())
+      T = CI;
 
     Builder.SetInsertPoint(T);
     unlinkExceptionRegistration(Builder);



More information about the llvm-commits mailing list