1 ; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
3 ; WinEH requires funclet tokens on nounwind intrinsics if they can lower to
4 ; regular function calls in the course of IR transformations.
6 ; Test that the code generator will emit the function call and not consider it
7 ; an "implausible instruciton". In the past this silently truncated code on
8 ; exception paths and caused crashes at runtime.
10 ; Reduced IR generated from ObjC++ source:
14 ; void test_catch_with_objc_intrinsic(void) {
17 ; } @catch (Ety *ex) {
18 ; // Destroy ex when leaving catchpad. This would emit calls to two
19 ; // intrinsic functions: llvm.objc.retain and llvm.objc.storeStrong
23 ; llvm.objc.retain and llvm.objc.storeStrong both lower into regular function
24 ; calls before ISel. We only need one of them to trigger funclet truncation
27 define void @test_catch_with_objc_intrinsic() personality ptr @__CxxFrameHandler3 {
29 %exn.slot = alloca ptr, align 8
30 %ex2 = alloca ptr, align 8
31 invoke void @opaque() to label %invoke.cont unwind label %catch.dispatch
33 catch.dispatch: ; preds = %entry
34 %0 = catchswitch within none [label %catch] unwind to caller
36 invoke.cont: ; preds = %entry
39 catch: ; preds = %catch.dispatch
40 %1 = catchpad within %0 [ptr null, i32 64, ptr %exn.slot]
41 %exn = load ptr, ptr %exn.slot, align 8
42 %2 = call ptr @llvm.objc.retain(ptr %exn) [ "funclet"(token %1) ]
43 store ptr %2, ptr %ex2, align 8
44 catchret from %1 to label %catchret.dest
46 catchret.dest: ; preds = %catch
50 declare void @opaque()
51 declare ptr @llvm.objc.retain(ptr) #0
52 declare i32 @__CxxFrameHandler3(...)
54 attributes #0 = { nounwind }
56 ; EH catchpad with SEH prologue:
57 ; CHECK-LABEL: # %catch
59 ; CHECK: .seh_pushreg %rbp
61 ; CHECK: .seh_endprologue
63 ; At this point the code used to be truncated (and sometimes terminated with an
67 ; Instead, the runtime call to retain should be emitted:
68 ; CHECK: movq -8(%rbp), %rcx
69 ; CHECK: callq objc_retain
72 ; This is the end of the funclet:
74 ; CHECK: retq # CATCHRET
76 ; CHECK: .seh_handlerdata