1*9466b491SNikita Popov// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK 2*9466b491SNikita Popov// RUN: %clang_cc1 -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK 319005035SAkira Hatanaka 419005035SAkira Hatanaka@class A; 519005035SAkira Hatanaka 619005035SAkira HatanakaA *makeA(void); 719005035SAkira Hatanaka 846b0d0eeSAaron Ballmanvoid test_assign(void) { 919005035SAkira Hatanaka __unsafe_unretained id x; 1019005035SAkira Hatanaka x = makeA(); 1119005035SAkira Hatanaka} 1219005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_assign() 13*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 14*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 1519005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 16*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 1719005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 1819005035SAkira Hatanaka// CHECK-NEXT: ret void 1919005035SAkira Hatanaka 2046b0d0eeSAaron Ballmanvoid test_assign_assign(void) { 2119005035SAkira Hatanaka __unsafe_unretained id x, y; 2219005035SAkira Hatanaka x = y = makeA(); 2319005035SAkira Hatanaka} 2419005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_assign_assign() 25*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 26*9466b491SNikita Popov// CHECK: [[Y:%.*]] = alloca ptr 27*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 2819005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 29*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[Y]] 30*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 3119005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 3219005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 3319005035SAkira Hatanaka// CHECK-NEXT: ret void 3419005035SAkira Hatanaka 3546b0d0eeSAaron Ballmanvoid test_strong_assign_assign(void) { 3619005035SAkira Hatanaka __strong id x; 3719005035SAkira Hatanaka __unsafe_unretained id y; 3819005035SAkira Hatanaka x = y = makeA(); 3919005035SAkira Hatanaka} 4019005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_strong_assign_assign() 41*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 42*9466b491SNikita Popov// CHECK: [[Y:%.*]] = alloca ptr 43*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 4419005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 45*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[Y]] 46*9466b491SNikita Popov// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]] 47*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 48*9466b491SNikita Popov// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]] 4919005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 50*9466b491SNikita Popov// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] 51*9466b491SNikita Popov// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) 5219005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 5319005035SAkira Hatanaka// CHECK-NEXT: ret void 5419005035SAkira Hatanaka 5546b0d0eeSAaron Ballmanvoid test_assign_strong_assign(void) { 5619005035SAkira Hatanaka __unsafe_unretained id x; 5719005035SAkira Hatanaka __strong id y; 5819005035SAkira Hatanaka x = y = makeA(); 5919005035SAkira Hatanaka} 6019005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_assign_strong_assign() 61*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 62*9466b491SNikita Popov// CHECK: [[Y:%.*]] = alloca ptr 63*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 6419005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 65*9466b491SNikita Popov// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[Y]] 66*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[Y]] 67*9466b491SNikita Popov// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]] 68*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 69*9466b491SNikita Popov// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]] 70*9466b491SNikita Popov// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) 7119005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 7219005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 7319005035SAkira Hatanaka// CHECK-NEXT: ret void 7419005035SAkira Hatanaka 7546b0d0eeSAaron Ballmanvoid test_init(void) { 7619005035SAkira Hatanaka __unsafe_unretained id x = makeA(); 7719005035SAkira Hatanaka} 7819005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_init() 79*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 80*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 8119005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 82*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 8319005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 8419005035SAkira Hatanaka// CHECK-NEXT: ret void 8519005035SAkira Hatanaka 8646b0d0eeSAaron Ballmanvoid test_init_assignment(void) { 8719005035SAkira Hatanaka __unsafe_unretained id x; 8819005035SAkira Hatanaka __unsafe_unretained id y = x = makeA(); 8919005035SAkira Hatanaka} 9019005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_init_assignment() 91*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 92*9466b491SNikita Popov// CHECK: [[Y:%.*]] = alloca ptr 93*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 9419005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 95*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 96*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[Y]] 9719005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 9819005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 9919005035SAkira Hatanaka// CHECK-NEXT: ret void 10019005035SAkira Hatanaka 10146b0d0eeSAaron Ballmanvoid test_strong_init_assignment(void) { 10219005035SAkira Hatanaka __unsafe_unretained id x; 10319005035SAkira Hatanaka __strong id y = x = makeA(); 10419005035SAkira Hatanaka} 10519005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_strong_init_assignment() 106*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 107*9466b491SNikita Popov// CHECK: [[Y:%.*]] = alloca ptr 108*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 10919005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 110*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 111*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[Y]] 112*9466b491SNikita Popov// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]] 113*9466b491SNikita Popov// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) 11419005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 11519005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 11619005035SAkira Hatanaka// CHECK-NEXT: ret void 11719005035SAkira Hatanaka 11846b0d0eeSAaron Ballmanvoid test_init_strong_assignment(void) { 11919005035SAkira Hatanaka __strong id x; 12019005035SAkira Hatanaka __unsafe_unretained id y = x = makeA(); 12119005035SAkira Hatanaka} 12219005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_init_strong_assignment() 123*9466b491SNikita Popov// CHECK: [[X:%.*]] = alloca ptr 124*9466b491SNikita Popov// CHECK: [[Y:%.*]] = alloca ptr 125*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 12619005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 127*9466b491SNikita Popov// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]] 128*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[X]] 129*9466b491SNikita Popov// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]]) 130*9466b491SNikita Popov// CHECK-NEXT: store ptr [[T0]], ptr [[Y]] 13119005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 132*9466b491SNikita Popov// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] 133*9466b491SNikita Popov// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) 13419005035SAkira Hatanaka// CHECK-NEXT: lifetime.end 13519005035SAkira Hatanaka// CHECK-NEXT: ret void 13619005035SAkira Hatanaka 13746b0d0eeSAaron Ballmanvoid test_ignored(void) { 13819005035SAkira Hatanaka makeA(); 13919005035SAkira Hatanaka} 14019005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_ignored() 141*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 14219005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 14319005035SAkira Hatanaka// CHECK-NEXT: ret void 14419005035SAkira Hatanaka 14546b0d0eeSAaron Ballmanvoid test_cast_to_void(void) { 14619005035SAkira Hatanaka (void) makeA(); 14719005035SAkira Hatanaka} 14819005035SAkira Hatanaka// CHECK-LABEL: define{{.*}} void @test_cast_to_void() 149*9466b491SNikita Popov// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 15019005035SAkira Hatanaka// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 15119005035SAkira Hatanaka// CHECK-NEXT: ret void 15219005035SAkira Hatanaka 15319005035SAkira Hatanaka// This is always at the end of the module. 15419005035SAkira Hatanaka 15519005035SAkira Hatanaka// CHECK-OPTIMIZED: !llvm.module.flags = !{!0, 15619005035SAkira Hatanaka// CHECK-OPTIMIZED: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov{{.*}}marker for objc_retainAutoreleaseReturnValue"} 157