[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