[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:01:01 PDT 2022
sgraenitz created this revision.
sgraenitz added reviewers: theraven, rnk, fhahn.
Herald added a subscriber: pengfei.
Herald added a project: All.
sgraenitz requested review of this revision.
Herald added a project: LLVM.
Extending the ObjC++ test-case from D128190 <https://reviews.llvm.org/D128190> to a nested try-catch scenario, Clang emits an ObjC
ARC runtime-call in the funclet's `catchret.dest` block. This causes another binary truncation.
One of my changes from the original review prevents this successfully:
https://reviews.llvm.org/D124762#diff-change-MYHXIwRDUe3r
In the last round I discarded it as seemingly unnecessary, because back then my test didn't reproduce
it. Revisiting the affected test in libobjc2, however, revealed the missing piece:
https://github.com/gnustep/libobjc2/issues/222#issuecomment-1262047638
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D134866
Files:
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134866.463817.patch
Type: text/x-patch
Size: 2759 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220929/f2f6efd8/attachment.bin>
More information about the llvm-commits
mailing list