Home | History | Annotate | Download | only in ObjCARC
      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