[PATCH] D134866: [WinEH] Fix PreISel intrinsics in funclet catchret.dest blocks
Stefan Gränitz via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 29 03:09:49 PDT 2022
sgraenitz updated this revision to Diff 463820.
sgraenitz added a comment.
Herald added a subscriber: hiraditya.
TL;DR: Appling this extra funclet pad condition fixes the issue
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D134866/new/
https://reviews.llvm.org/D134866
Files:
llvm/lib/CodeGen/WinEHPrepare.cpp
llvm/test/CodeGen/X86/win64-funclet-preisel-intrinsics.ll
Index: llvm/test/CodeGen/X86/win64-funclet-preisel-intrinsics.ll
===================================================================
--- llvm/test/CodeGen/X86/win64-funclet-preisel-intrinsics.ll
+++ llvm/test/CodeGen/X86/win64-funclet-preisel-intrinsics.ll
@@ -11,18 +11,25 @@
;
; @class Ety;
; void opaque(void);
-; void test_catch_with_objc_intrinsic(void) {
+; void nested() {
; @try {
; opaque();
; } @catch (Ety *ex) {
-; // Destroy ex when leaving catchpad. This would emit calls to two
+; @throw ex;
+; }
+; }
+; void test_catch_with_objc_intrinsic(void) {
+; @try {
+; nested();
+; } @catch (Ety *ex2) {
+; // Destroy ex2 when leaving catchpad. It involves calls to two
; // intrinsic functions: llvm.objc.retain and llvm.objc.storeStrong
; }
; }
;
; llvm.objc.retain and llvm.objc.storeStrong both lower into regular function
-; calls before ISel. We only need one of them to trigger funclet truncation
-; during codegen:
+; calls before ISel. They are emitted in different funclet blocks and thus
+; caused slightly different truncations.
define void @test_catch_with_objc_intrinsic() personality ptr @__CxxFrameHandler3 {
entry:
@@ -34,7 +41,10 @@
%0 = catchswitch within none [label %catch] unwind to caller
invoke.cont: ; preds = %entry
- unreachable
+ br label %eh.cont
+
+eh.cont: ; preds = %invoke.cont, %catchret.dest
+ ret void
catch: ; preds = %catch.dispatch
%1 = catchpad within %0 [ptr null, i32 64, ptr %exn.slot]
@@ -44,16 +54,28 @@
catchret from %1 to label %catchret.dest
catchret.dest: ; preds = %catch
- ret void
+ call void @llvm.objc.storeStrong(ptr %ex2, ptr null) [ "funclet"(token %1) ]
+ br label %eh.cont
}
declare void @opaque()
declare ptr @llvm.objc.retain(ptr) #0
+declare void @llvm.objc.storeStrong(ptr, ptr) #0
declare i32 @__CxxFrameHandler3(...)
attributes #0 = { nounwind }
-; EH catchpad with SEH prologue:
+; Nested try-catch causes emission of a catchret.dest block, which used to be
+; truncated. Instead, the runtime call to storeStrong should be emitted:
+; # %catchret.dest
+; CHECK-LABEL: $ehgcr
+; CHECK-NEXT: leaq -24(%rbp), %rcx
+; CHECK-NEXT: xorl %edx, %edx
+; CHECK-NEXT: callq objc_storeStrong
+; CHECK-NEXT: jmp .LBB0_1
+; CHECK-NEXT: .seh_handlerdata
+
+; Top-level EH catchpad with SEH prologue:
; CHECK-LABEL: # %catch
; CHECK: pushq %rbp
; CHECK: .seh_pushreg %rbp
Index: llvm/lib/CodeGen/WinEHPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/WinEHPrepare.cpp
+++ llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -960,7 +960,7 @@
if (auto BU = CB->getOperandBundle(LLVMContext::OB_funclet))
FuncletBundleOperand = BU->Inputs.front();
- if (FuncletBundleOperand == FuncletPad)
+ if (!FuncletPad || FuncletBundleOperand == FuncletPad)
continue;
// Skip call sites which are nounwind intrinsics or inline asm.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134866.463820.patch
Type: text/x-patch
Size: 3299 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220929/b2605040/attachment.bin>
More information about the llvm-commits
mailing list