1// Make sure it works on x86-64. 2// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=NOTAIL-CALL 3 4// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s -check-prefix=ATTACHED-CALL 5 6// Make sure it works on x86-32. 7// RUN: %clang_cc1 -triple i386-apple-darwin11 -fobjc-runtime=macosx-fragile-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL 8 9// Make sure it works on ARM64. 10// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL 11 12// Make sure it works on ARM. 13// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL 14// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED -check-prefix=CALL 15 16// Make sure that it's implicitly disabled if the runtime version isn't high enough. 17// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED 18// RUN: %clang_cc1 -triple arm64-apple-ios8 -fobjc-runtime=ios-8 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED -check-prefix=DISABLED-MARKED 19 20@class A; 21 22A *makeA(void); 23 24void test_assign(void) { 25 __unsafe_unretained id x; 26 x = makeA(); 27} 28// CHECK-LABEL: define{{.*}} void @test_assign() 29// CHECK: [[X:%.*]] = alloca ptr 30// CHECK: [[T0:%.*]] = call ptr @makeA() 31// CHECK-MARKED-NEXT: call void asm sideeffect 32// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 33// CALL-NEXT: [[T2:%.*]] = call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 34// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 35// CHECK-OPTIMIZED-NEXT: lifetime.end 36// CHECK-NEXT: ret void 37 38// DISABLED-LABEL: define{{.*}} void @test_assign() 39// DISABLED: [[T0:%.*]] = call ptr @makeA() 40// DISABLED-MARKED-NEXT: call void asm sideeffect 41// DISABLED-NEXT: [[T2:%.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]]) 42 43// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign() 44// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], 45// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 46 47void test_assign_assign(void) { 48 __unsafe_unretained id x, y; 49 x = y = makeA(); 50} 51// CHECK-LABEL: define{{.*}} void @test_assign_assign() 52// CHECK: [[X:%.*]] = alloca ptr 53// CHECK: [[Y:%.*]] = alloca ptr 54// CHECK: [[T0:%.*]] = call ptr @makeA() 55// CHECK-MARKED-NEXT: call void asm sideeffect 56// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 57// CALL-NEXT: [[T2:%.*]] = call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 58// CHECK-NEXT: store ptr [[T2]], ptr [[Y]] 59// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 60// CHECK-OPTIMIZED-NEXT: lifetime.end 61// CHECK-OPTIMIZED-NEXT: lifetime.end 62// CHECK-NEXT: ret void 63 64// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_assign() 65// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], 66// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 67 68void test_strong_assign_assign(void) { 69 __strong id x; 70 __unsafe_unretained id y; 71 x = y = makeA(); 72} 73// CHECK-LABEL: define{{.*}} void @test_strong_assign_assign() 74// CHECK: [[X:%.*]] = alloca ptr 75// CHECK: [[Y:%.*]] = alloca ptr 76// CHECK: [[T0:%.*]] = call ptr @makeA() 77// CHECK-MARKED-NEXT: call void asm sideeffect 78// CHECK-NEXT: [[T2:%.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]]) 79// CHECK-NEXT: store ptr [[T2]], ptr [[Y]] 80// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]] 81// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 82// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]] 83// CHECK-OPTIMIZED-NEXT: lifetime.end 84// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null) 85// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] 86// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(ptr [[T0]]) 87// CHECK-OPTIMIZED-NEXT: lifetime.end 88// CHECK-NEXT: ret void 89 90// ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_assign_assign() 91// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], 92// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 93 94void test_assign_strong_assign(void) { 95 __unsafe_unretained id x; 96 __strong id y; 97 x = y = makeA(); 98} 99// CHECK-LABEL: define{{.*}} void @test_assign_strong_assign() 100// CHECK: [[X:%.*]] = alloca ptr 101// CHECK: [[Y:%.*]] = alloca ptr 102// CHECK: [[T0:%.*]] = call ptr @makeA() 103// CHECK-MARKED-NEXT: call void asm sideeffect 104// CHECK-NEXT: [[T2:%.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]]) 105// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[Y]] 106// CHECK-NEXT: store ptr [[T2]], ptr [[Y]] 107// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]] 108// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 109// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(ptr [[Y]], ptr null) 110// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]] 111// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(ptr [[T0]]) 112// CHECK-OPTIMIZED-NEXT: lifetime.end 113// CHECK-OPTIMIZED-NEXT: lifetime.end 114// CHECK-NEXT: ret void 115 116// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_strong_assign() 117// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], 118// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 119 120void test_init(void) { 121 __unsafe_unretained id x = makeA(); 122} 123// CHECK-LABEL: define{{.*}} void @test_init() 124// CHECK: [[X:%.*]] = alloca ptr 125// CHECK: [[T0:%.*]] = call ptr @makeA() 126// CHECK-MARKED-NEXT: call void asm sideeffect 127// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 128// CALL-NEXT: [[T2:%.*]] = call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 129// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 130// CHECK-OPTIMIZED-NEXT: lifetime.end 131// CHECK-NEXT: ret void 132 133// ATTACHED-CALL-LABEL: define{{.*}} void @test_init() 134// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], 135// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 136 137void test_init_assignment(void) { 138 __unsafe_unretained id x; 139 __unsafe_unretained id y = x = makeA(); 140} 141// CHECK-LABEL: define{{.*}} void @test_init_assignment() 142// CHECK: [[X:%.*]] = alloca ptr 143// CHECK: [[Y:%.*]] = alloca ptr 144// CHECK: [[T0:%.*]] = call ptr @makeA() 145// CHECK-MARKED-NEXT: call void asm sideeffect 146// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 147// CALL-NEXT: [[T2:%.*]] = call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 148// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 149// CHECK-NEXT: store ptr [[T2]], ptr [[Y]] 150// CHECK-OPTIMIZED-NEXT: lifetime.end 151// CHECK-OPTIMIZED-NEXT: lifetime.end 152// CHECK-NEXT: ret void 153 154// ATTACHED-CALL-LABEL: define{{.*}} void @test_init_assignment() 155// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], 156// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 157 158void test_strong_init_assignment(void) { 159 __unsafe_unretained id x; 160 __strong id y = x = makeA(); 161} 162// CHECK-LABEL: define{{.*}} void @test_strong_init_assignment() 163// CHECK: [[X:%.*]] = alloca ptr 164// CHECK: [[Y:%.*]] = alloca ptr 165// CHECK: [[T0:%.*]] = call ptr @makeA() 166// CHECK-MARKED-NEXT: call void asm sideeffect 167// CHECK-NEXT: [[T2:%.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]]) 168// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 169// CHECK-NEXT: store ptr [[T2]], ptr [[Y]] 170// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(ptr [[Y]], ptr null) 171// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]] 172// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(ptr [[T0]]) 173// CHECK-OPTIMIZED-NEXT: lifetime.end 174// CHECK-OPTIMIZED-NEXT: lifetime.end 175// CHECK-NEXT: ret void 176 177// ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_init_assignment() 178// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], 179// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 180 181void test_init_strong_assignment(void) { 182 __strong id x; 183 __unsafe_unretained id y = x = makeA(); 184} 185// CHECK-LABEL: define{{.*}} void @test_init_strong_assignment() 186// CHECK: [[X:%.*]] = alloca ptr 187// CHECK: [[Y:%.*]] = alloca ptr 188// CHECK: [[T0:%.*]] = call ptr @makeA() 189// CHECK-MARKED-NEXT: call void asm sideeffect 190// CHECK-NEXT: [[T2:%.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]]) 191// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]] 192// CHECK-NEXT: store ptr [[T2]], ptr [[X]] 193// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]]) 194// CHECK-NEXT: store ptr [[T2]], ptr [[Y]] 195// CHECK-OPTIMIZED-NEXT: lifetime.end 196// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null) 197// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] 198// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(ptr [[T0]]) 199// CHECK-OPTIMIZED-NEXT: lifetime.end 200// CHECK-NEXT: ret void 201 202// ATTACHED-CALL-LABEL: define{{.*}} void @test_init_strong_assignment() 203// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], 204// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 205 206void test_ignored(void) { 207 makeA(); 208} 209// CHECK-LABEL: define{{.*}} void @test_ignored() 210// CHECK: [[T0:%.*]] = call ptr @makeA() 211// CHECK-MARKED-NEXT: call void asm sideeffect 212// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 213// CALL-NEXT: [[T2:%.*]] = call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 214// CHECK-NEXT: ret void 215 216// ATTACHED-CALL-LABEL: define{{.*}} void @test_ignored() 217// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], 218// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 219 220void test_cast_to_void(void) { 221 (void) makeA(); 222} 223// CHECK-LABEL: define{{.*}} void @test_cast_to_void() 224// CHECK: [[T0:%.*]] = call ptr @makeA() 225// CHECK-MARKED-NEXT: call void asm sideeffect 226// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 227// CALL-NEXT: [[T2:%.*]] = call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr [[T0]]) 228// CHECK-NEXT: ret void 229 230// ATTACHED-CALL-LABEL: define{{.*}} void @test_cast_to_void() 231// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], 232// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) 233 234 235// This is always at the end of the module. 236 237// CHECK-OPTIMIZED: !llvm.module.flags = !{!0, 238// CHECK-OPTIMIZED: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov{{.*}}marker for objc_retainAutoreleaseReturnValue"} 239