1 ; RUN: opt -mtriple x86_64-unknown-windows-msvc -objc-arc -S -o - %s | FileCheck %s 2 3 ; bool g(); 4 ; id h(); 5 ; 6 ; void f() { 7 ; id a = nullptr; 8 ; if (g()) 9 ; a = h(); 10 ; id b = nullptr; 11 ; g(); 12 ; } 13 14 declare zeroext i1 @"\01?g@@YA_NXZ"() local_unnamed_addr 15 declare i8* @"\01?h@@YAPEAUobjc_object@@XZ"() local_unnamed_addr 16 17 declare dllimport void @objc_release(i8*) local_unnamed_addr 18 declare dllimport i8* @objc_retainAutoreleasedReturnValue(i8* returned) local_unnamed_addr 19 20 declare i32 @__CxxFrameHandler3(...) 21 22 define void @"\01?f@@YAXXZ"() local_unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { 23 entry: 24 %call = invoke zeroext i1 @"\01?g@@YA_NXZ"() 25 to label %invoke.cont unwind label %ehcleanup6 26 27 invoke.cont: ; preds = %entry 28 br i1 %call, label %if.then, label %if.end 29 30 if.then: ; preds = %invoke.cont 31 %call2 = invoke i8* @"\01?h@@YAPEAUobjc_object@@XZ"() 32 to label %invoke.cont1 unwind label %ehcleanup6 33 34 invoke.cont1: ; preds = %if.then 35 %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call2) 36 tail call void @objc_release(i8* null), !clang.imprecise_release !1 37 br label %if.end 38 39 if.end: ; preds = %invoke.cont1, %invoke.cont 40 %a.0 = phi i8* [ %call2, %invoke.cont1 ], [ null, %invoke.cont ] 41 %call4 = invoke zeroext i1 @"\01?g@@YA_NXZ"() 42 to label %invoke.cont3 unwind label %ehcleanup 43 44 invoke.cont3: ; preds = %if.end 45 tail call void @objc_release(i8* null), !clang.imprecise_release !1 46 tail call void @objc_release(i8* %a.0), !clang.imprecise_release !1 47 ret void 48 49 ehcleanup: ; preds = %if.end 50 %1 = cleanuppad within none [] 51 call void @objc_release(i8* null) [ "funclet"(token %1) ], !clang.imprecise_release !1 52 cleanupret from %1 unwind label %ehcleanup6 53 54 ehcleanup6: ; preds = %ehcleanup, %if.then, %entry 55 %a.1 = phi i8* [ %a.0, %ehcleanup ], [ null, %if.then ], [ null, %entry ] 56 %2 = cleanuppad within none [] 57 call void @objc_release(i8* %a.1) [ "funclet"(token %2) ], !clang.imprecise_release !1 58 cleanupret from %2 unwind to caller 59 } 60 61 ; CHECK-LABEL: ?f@@YAXXZ 62 ; CHECK: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %1) ] 63 ; CHECK-NOT: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %2) ] 64 65 define void @"\01?i@@YAXXZ"() local_unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { 66 entry: 67 %call = invoke zeroext i1 @"\01?g@@YA_NXZ"() 68 to label %invoke.cont unwind label %ehcleanup6 69 70 invoke.cont: ; preds = %entry 71 br i1 %call, label %if.then, label %if.end 72 73 if.then: ; preds = %invoke.cont 74 %call2 = invoke i8* @"\01?h@@YAPEAUobjc_object@@XZ"() 75 to label %invoke.cont1 unwind label %ehcleanup6 76 77 invoke.cont1: ; preds = %if.then 78 %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call2) 79 tail call void @objc_release(i8* null), !clang.imprecise_release !1 80 br label %if.end 81 82 if.end: ; preds = %invoke.cont1, %invoke.cont 83 %a.0 = phi i8* [ %call2, %invoke.cont1 ], [ null, %invoke.cont ] 84 %call4 = invoke zeroext i1 @"\01?g@@YA_NXZ"() 85 to label %invoke.cont3 unwind label %ehcleanup 86 87 invoke.cont3: ; preds = %if.end 88 tail call void @objc_release(i8* null), !clang.imprecise_release !1 89 tail call void @objc_release(i8* %a.0), !clang.imprecise_release !1 90 ret void 91 92 ehcleanup: ; preds = %if.end 93 %1 = cleanuppad within none [] 94 call void @objc_release(i8* null) [ "funclet"(token %1) ], !clang.imprecise_release !1 95 br label %ehcleanup.1 96 97 ehcleanup.1: 98 cleanupret from %1 unwind label %ehcleanup6 99 100 ehcleanup6: ; preds = %ehcleanup, %if.then, %entry 101 %a.1 = phi i8* [ %a.0, %ehcleanup.1 ], [ null, %if.then ], [ null, %entry ] 102 %2 = cleanuppad within none [] 103 call void @objc_release(i8* %a.1) [ "funclet"(token %2) ], !clang.imprecise_release !1 104 cleanupret from %2 unwind to caller 105 } 106 107 ; CHECK-LABEL: ?i@@YAXXZ 108 ; CHECK: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %1) ] 109 ; CHECK-NOT: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %2) ] 110 111 !1 = !{} 112 113