1*67e74705SXin Li// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=UNOPT 2*67e74705SXin Li// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -O -disable-llvm-optzns | FileCheck %s -check-prefix=CHECK -check-prefix=OPT 3*67e74705SXin Li 4*67e74705SXin Litypedef __strong id strong_id; 5*67e74705SXin Litypedef __weak id weak_id; 6*67e74705SXin Li 7*67e74705SXin Li// CHECK-LABEL: define void @_Z8test_newP11objc_object 8*67e74705SXin Livoid test_new(id invalue) { 9*67e74705SXin Li // CHECK: [[INVALUEADDR:%.*]] = alloca i8* 10*67e74705SXin Li // UNOPT-NEXT: store i8* null, i8** [[INVALUEADDR]] 11*67e74705SXin Li // UNOPT-NEXT: call void @objc_storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]]) 12*67e74705SXin Li // OPT-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[INVALUE:%.*]]) 13*67e74705SXin Li // OPT-NEXT: store i8* [[T0]], i8** [[INVALUEADDR]] 14*67e74705SXin Li 15*67e74705SXin Li // CHECK: call i8* @_Znwm 16*67e74705SXin Li // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 17*67e74705SXin Li // CHECK-NEXT: store i8* null, i8** 18*67e74705SXin Li new strong_id; 19*67e74705SXin Li // CHECK: call i8* @_Znwm 20*67e74705SXin Li // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 21*67e74705SXin Li // UNOPT-NEXT: store i8* null, i8** 22*67e74705SXin Li // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null) 23*67e74705SXin Li new weak_id; 24*67e74705SXin Li 25*67e74705SXin Li // CHECK: call i8* @_Znwm 26*67e74705SXin Li // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 27*67e74705SXin Li // CHECK-NEXT: store i8* null, i8** 28*67e74705SXin Li new __strong id; 29*67e74705SXin Li // CHECK: call i8* @_Znwm 30*67e74705SXin Li // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 31*67e74705SXin Li // UNOPT-NEXT: store i8* null, i8** 32*67e74705SXin Li // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null) 33*67e74705SXin Li new __weak id; 34*67e74705SXin Li 35*67e74705SXin Li // CHECK: call i8* @_Znwm 36*67e74705SXin Li // CHECK: call i8* @objc_retain 37*67e74705SXin Li // CHECK: store i8* 38*67e74705SXin Li new __strong id(invalue); 39*67e74705SXin Li 40*67e74705SXin Li // CHECK: call i8* @_Znwm 41*67e74705SXin Li // CHECK: call i8* @objc_initWeak 42*67e74705SXin Li new __weak id(invalue); 43*67e74705SXin Li 44*67e74705SXin Li // UNOPT: call void @objc_storeStrong 45*67e74705SXin Li // OPT: call void @objc_release 46*67e74705SXin Li // CHECK: ret void 47*67e74705SXin Li} 48*67e74705SXin Li 49*67e74705SXin Li// CHECK-LABEL: define void @_Z14test_array_new 50*67e74705SXin Livoid test_array_new() { 51*67e74705SXin Li // CHECK: call i8* @_Znam 52*67e74705SXin Li // CHECK: store i64 17, i64* 53*67e74705SXin Li // CHECK: call void @llvm.memset.p0i8.i64 54*67e74705SXin Li new strong_id[17]; 55*67e74705SXin Li 56*67e74705SXin Li // CHECK: call i8* @_Znam 57*67e74705SXin Li // CHECK: store i64 17, i64* 58*67e74705SXin Li // CHECK: call void @llvm.memset.p0i8.i64 59*67e74705SXin Li new weak_id[17]; 60*67e74705SXin Li // CHECK: ret void 61*67e74705SXin Li} 62*67e74705SXin Li 63*67e74705SXin Li// CHECK-LABEL: define void @_Z11test_deletePU8__strongP11objc_objectPU6__weakS0_ 64*67e74705SXin Livoid test_delete(__strong id *sptr, __weak id *wptr) { 65*67e74705SXin Li // CHECK: br i1 66*67e74705SXin Li // UNOPT: call void @objc_storeStrong(i8** {{.*}}, i8* null) 67*67e74705SXin Li // OPT: load i8*, i8** 68*67e74705SXin Li // OPT-NEXT: call void @objc_release 69*67e74705SXin Li // CHECK: call void @_ZdlPv 70*67e74705SXin Li delete sptr; 71*67e74705SXin Li 72*67e74705SXin Li // CHECK: call void @objc_destroyWeak 73*67e74705SXin Li // CHECK: call void @_ZdlPv 74*67e74705SXin Li delete wptr; 75*67e74705SXin Li 76*67e74705SXin Li // CHECK: ret void 77*67e74705SXin Li} 78*67e74705SXin Li 79*67e74705SXin Li// CHECK-LABEL: define void @_Z17test_array_deletePU8__strongP11objc_objectPU6__weakS0_ 80*67e74705SXin Livoid test_array_delete(__strong id *sptr, __weak id *wptr) { 81*67e74705SXin Li // CHECK: icmp eq i8** [[BEGIN:%.*]], null 82*67e74705SXin Li // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}} 83*67e74705SXin Li // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]] 84*67e74705SXin Li // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]] 85*67e74705SXin Li // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], 86*67e74705SXin Li // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 87*67e74705SXin Li // UNOPT-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null) 88*67e74705SXin Li // OPT-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]] 89*67e74705SXin Li // OPT-NEXT: objc_release(i8* [[T0]]) 90*67e74705SXin Li // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]] 91*67e74705SXin Li // CHECK: call void @_ZdaPv 92*67e74705SXin Li delete [] sptr; 93*67e74705SXin Li 94*67e74705SXin Li // CHECK: icmp eq i8** [[BEGIN:%.*]], null 95*67e74705SXin Li // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}} 96*67e74705SXin Li // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]] 97*67e74705SXin Li // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]] 98*67e74705SXin Li // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], 99*67e74705SXin Li // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 100*67e74705SXin Li // CHECK-NEXT: call void @objc_destroyWeak(i8** [[CUR]]) 101*67e74705SXin Li // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]] 102*67e74705SXin Li // CHECK: call void @_ZdaPv 103*67e74705SXin Li delete [] wptr; 104*67e74705SXin Li} 105