Skip to content

Commit 718acd5

Browse files
committed
[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
1 parent f85579f commit 718acd5

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

llvm/lib/Target/X86/X86WinEHState.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,16 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
363363
Instruction *T = BB.getTerminator();
364364
if (!isa<ReturnInst>(T))
365365
continue;
366+
367+
// Back up to any preceding musttail call, the de-facto terminator.
368+
Instruction *Prev = T->getPrevNonDebugInstruction();
369+
if (isa_and_present<BitCastInst>(Prev))
370+
Prev = T->getPrevNonDebugInstruction();
371+
if (CallInst *CI = dyn_cast_or_null<CallInst>(Prev)) {
372+
if (CI->isMustTailCall())
373+
T = CI;
374+
}
375+
366376
Builder.SetInsertPoint(T);
367377
unlinkExceptionRegistration(Builder);
368378
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: llc < %s | FileCheck %s
2+
3+
target triple = "i386-pc-windows-msvc"
4+
5+
; Check that codegen doesn't fail due to wineh inserting instructions between
6+
; the musttail call and return instruction.
7+
8+
9+
define void @test() personality ptr @__CxxFrameHandler3 {
10+
; CHECK-LABEL: test:
11+
12+
entry:
13+
invoke void @foo() to label %try.cont unwind label %catch.dispatch
14+
15+
catch.dispatch:
16+
%0 = catchswitch within none [label %catch] unwind to caller
17+
18+
catch:
19+
%1 = catchpad within %0 [ptr null, i32 64, ptr null]
20+
catchret from %1 to label %try.cont
21+
22+
try.cont:
23+
; CHECK: movl %{{[a-z0-9]+}}, %fs:0
24+
; CHECK: jmp _bar
25+
26+
musttail call void @bar()
27+
ret void
28+
}
29+
30+
declare i32 @__CxxFrameHandler3(...)
31+
declare void @foo()
32+
declare void @bar()

0 commit comments

Comments
 (0)