[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