Home | History | Annotate | Download | only in CodeGenObjC
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
      2 
      3 #define PRECISE_LIFETIME __attribute__((objc_precise_lifetime))
      4 
      5 id test0_helper(void) __attribute__((ns_returns_retained));
      6 void test0() {
      7   PRECISE_LIFETIME id x = test0_helper();
      8   x = 0;
      9   // CHECK:      [[X:%.*]] = alloca i8*
     10   // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
     11   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])
     12   // CHECK-NEXT: [[CALL:%.*]] = call i8* @test0_helper()
     13   // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
     14 
     15   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
     16   // CHECK-NEXT: store i8* null, i8** [[X]]
     17   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
     18   // CHECK-NOT:  clang.imprecise_release
     19 
     20   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
     21   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
     22   // CHECK-NOT:  clang.imprecise_release
     23 
     24   // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
     25   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])
     26   // CHECK-NEXT: ret void
     27 }
     28 
     29 // rdar://problem/9821110 - precise lifetime should suppress extension
     30 // rdar://problem/22172983 - should work for calls via property syntax, too
     31 @interface Test1
     32 - (char*) interior __attribute__((objc_returns_inner_pointer));
     33 // Should we allow this on properties? Yes! see // rdar://14990439
     34 @property (nonatomic, readonly) char * PropertyReturnsInnerPointer __attribute__((objc_returns_inner_pointer));
     35 @end
     36 extern Test1 *test1_helper(void);
     37 
     38 // CHECK-LABEL: define void @test1a_message()
     39 void test1a_message(void) {
     40   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
     41   // CHECK:      [[C:%.*]] = alloca i8*, align 8
     42   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
     43   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
     44   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
     45   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
     46   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
     47   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
     48   // CHECK-NEXT: store [[TEST1]]* [[T3]]
     49   // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
     50   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])
     51   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
     52   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
     53   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
     54   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
     55   // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
     56   // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
     57   // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
     58   // CHECK-NEXT: store i8* [[T6]], i8**
     59   // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
     60   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])
     61   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
     62   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
     63   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
     64   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
     65   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
     66   // CHECK-NEXT: ret void
     67   Test1 *ptr = test1_helper();
     68   char *c = [(ptr) interior];
     69 }
     70 
     71 
     72 // CHECK-LABEL: define void @test1a_property()
     73 void test1a_property(void) {
     74   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
     75   // CHECK:      [[C:%.*]] = alloca i8*, align 8
     76   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
     77   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
     78   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
     79   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
     80   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
     81   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
     82   // CHECK-NEXT: store [[TEST1]]* [[T3]]
     83   // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
     84   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])
     85   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
     86   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
     87   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
     88   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
     89   // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
     90   // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
     91   // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
     92   // CHECK-NEXT: store i8* [[T6]], i8**
     93   // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
     94   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])
     95   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
     96   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
     97   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
     98   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
     99   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
    100   // CHECK-NEXT: ret void
    101   Test1 *ptr = test1_helper();
    102   char *c = ptr.interior;
    103 }
    104 
    105 
    106 // CHECK-LABEL: define void @test1b_message()
    107 void test1b_message(void) {
    108   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
    109   // CHECK:      [[C:%.*]] = alloca i8*, align 8
    110   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    111   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
    112   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
    113   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    114   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    115   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    116   // CHECK-NEXT: store [[TEST1]]* [[T3]]
    117   // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
    118   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])
    119   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    120   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
    121   // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    122   // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
    123   // CHECK-NEXT: store i8* [[T3]], i8**
    124   // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
    125   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])
    126   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    127   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    128   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
    129   // CHECK-NOT:  clang.imprecise_release
    130   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    131   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
    132   // CHECK-NEXT: ret void
    133   PRECISE_LIFETIME Test1 *ptr = test1_helper();
    134   char *c = [ptr interior];
    135 }
    136 
    137 // CHECK-LABEL: define void @test1b_property()
    138 void test1b_property(void) {
    139   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
    140   // CHECK:      [[C:%.*]] = alloca i8*, align 8
    141   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    142   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
    143   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
    144   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    145   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    146   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    147   // CHECK-NEXT: store [[TEST1]]* [[T3]]
    148   // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
    149   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])
    150   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    151   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
    152   // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    153   // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
    154   // CHECK-NEXT: store i8* [[T3]], i8**
    155   // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
    156   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])
    157   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    158   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    159   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
    160   // CHECK-NOT:  clang.imprecise_release
    161   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    162   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
    163   // CHECK-NEXT: ret void
    164   PRECISE_LIFETIME Test1 *ptr = test1_helper();
    165   char *c = ptr.interior;
    166 }
    167 
    168 // CHECK-LABEL: define void @test1c_message()
    169 void test1c_message(void) {
    170   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
    171   // CHECK:      [[PC:%.*]] = alloca i8*, align 8
    172   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    173   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
    174   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
    175   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    176   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    177   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    178   // CHECK-NEXT: store [[TEST1]]* [[T3]]
    179   // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
    180   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])
    181   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    182   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    183   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
    184   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    185   // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
    186   // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
    187   // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
    188   // CHECK-NEXT: store i8* [[T6]], i8**
    189   // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
    190   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])
    191   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    192   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    193   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
    194   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    195   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
    196   // CHECK-NEXT: ret void
    197   Test1 *ptr = test1_helper();
    198   char *pc = [ptr PropertyReturnsInnerPointer];
    199 }
    200 
    201 // CHECK-LABEL: define void @test1c_property()
    202 void test1c_property(void) {
    203   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
    204   // CHECK:      [[PC:%.*]] = alloca i8*, align 8
    205   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    206   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
    207   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
    208   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    209   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    210   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    211   // CHECK-NEXT: store [[TEST1]]* [[T3]]
    212   // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
    213   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])
    214   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    215   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    216   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
    217   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    218   // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
    219   // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
    220   // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
    221   // CHECK-NEXT: store i8* [[T6]], i8**
    222   // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
    223   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])
    224   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    225   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    226   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
    227   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    228   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
    229   // CHECK-NEXT: ret void
    230   Test1 *ptr = test1_helper();
    231   char *pc = ptr.PropertyReturnsInnerPointer;
    232 }
    233 
    234 // CHECK-LABEL: define void @test1d_message()
    235 void test1d_message(void) {
    236   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
    237   // CHECK:      [[PC:%.*]] = alloca i8*, align 8
    238   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    239   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
    240   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
    241   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    242   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    243   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    244   // CHECK-NEXT: store [[TEST1]]* [[T3]]
    245   // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
    246   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])
    247   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    248   // CHECK-NEXT: [[SEVEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
    249   // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    250   // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[EIGHT]], i8* [[SEVEN]])
    251   // CHECK-NEXT: store i8* [[CALL1]], i8**
    252   // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
    253   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])
    254   // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]**
    255   // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8*
    256   // CHECK-NEXT: call void @objc_release(i8* [[TEN]])
    257   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    258   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
    259   // CHECK-NEXT: ret void
    260   PRECISE_LIFETIME Test1 *ptr = test1_helper();
    261   char *pc = [ptr PropertyReturnsInnerPointer];
    262 }
    263 
    264 // CHECK-LABEL: define void @test1d_property()
    265 void test1d_property(void) {
    266   // CHECK:      [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
    267   // CHECK:      [[PC:%.*]] = alloca i8*, align 8
    268   // CHECK:      [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    269   // CHECK:      call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
    270   // CHECK:      [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
    271   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    272   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    273   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
    274   // CHECK-NEXT: store [[TEST1]]* [[T3]]
    275   // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
    276   // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])
    277   // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
    278   // CHECK-NEXT: [[SEVEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
    279   // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
    280   // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[EIGHT]], i8* [[SEVEN]])
    281   // CHECK-NEXT: store i8* [[CALL1]], i8**
    282   // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
    283   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])
    284   // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]**
    285   // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8*
    286   // CHECK-NEXT: call void @objc_release(i8* [[TEN]])
    287   // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
    288   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
    289   // CHECK-NEXT: ret void
    290   PRECISE_LIFETIME Test1 *ptr = test1_helper();
    291   char *pc = ptr.PropertyReturnsInnerPointer;
    292 }
    293 
    294 @interface Test2 {
    295 @public
    296   id ivar;
    297 }
    298 @end
    299 // CHECK-LABEL:      define void @test2(
    300 void test2(Test2 *x) {
    301   x->ivar = 0;
    302   // CHECK:      [[X:%.*]] = alloca [[TEST2:%.*]]*
    303   // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8*
    304   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]]
    305   // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST2]]*
    306   // CHECK-NEXT: store [[TEST2]]* [[T2]], [[TEST2]]** [[X]],
    307 
    308   // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]],
    309   // CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test2.ivar"
    310   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
    311   // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 [[OFFSET]]
    312   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8**
    313   // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]],
    314   // CHECK-NEXT: store i8* null, i8** [[T3]],
    315   // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]]
    316   // CHECK-NOT:  imprecise
    317 
    318   // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]]
    319   // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
    320   // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
    321 
    322   // CHECK-NEXT: ret void
    323 }
    324 
    325 // CHECK-LABEL:      define void @test3(i8*
    326 void test3(PRECISE_LIFETIME id x) {
    327   // CHECK:      [[X:%.*]] = alloca i8*,
    328   // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) [[NUW]]
    329   // CHECK-NEXT: store i8* [[T0]], i8** [[X]],
    330 
    331   // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
    332   // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
    333   // CHECK-NOT:  imprecise_release
    334 
    335   // CHECK-NEXT: ret void  
    336 }
    337 
    338 // CHECK: attributes [[NUW]] = { nounwind }
    339