1; RUN: opt -pre-isel-intrinsic-lowering -S -o - %s | FileCheck %s 2 3; Make sure calls to the objc intrinsics are translated to calls in to the 4; runtime 5 6declare i8* @foo() 7declare i32 @__gxx_personality_v0(...) 8 9define i8* @test_objc_autorelease(i8* %arg0) { 10; CHECK-LABEL: test_objc_autorelease 11; CHECK-NEXT: entry 12; CHECK-NEXT: %0 = notail call i8* @objc_autorelease(i8* %arg0) 13; CHECK-NEXT: ret i8* %0 14entry: 15 %0 = call i8* @llvm.objc.autorelease(i8* %arg0) 16 ret i8* %0 17} 18 19define void @test_objc_autoreleasePoolPop(i8* %arg0) { 20; CHECK-LABEL: test_objc_autoreleasePoolPop 21; CHECK-NEXT: entry 22; CHECK-NEXT: call void @objc_autoreleasePoolPop(i8* %arg0) 23; CHECK-NEXT: ret void 24entry: 25 call void @llvm.objc.autoreleasePoolPop(i8* %arg0) 26 ret void 27} 28 29define i8* @test_objc_autoreleasePoolPush() { 30; CHECK-LABEL: test_objc_autoreleasePoolPush 31; CHECK-NEXT: entry 32; CHECK-NEXT: %0 = call i8* @objc_autoreleasePoolPush() 33; CHECK-NEXT: ret i8* %0 34entry: 35 %0 = call i8* @llvm.objc.autoreleasePoolPush() 36 ret i8* %0 37} 38 39define i8* @test_objc_autoreleaseReturnValue(i8* %arg0) { 40; CHECK-LABEL: test_objc_autoreleaseReturnValue 41; CHECK-NEXT: entry 42; CHECK-NEXT: %0 = tail call i8* @objc_autoreleaseReturnValue(i8* %arg0) 43; CHECK-NEXT: ret i8* %0 44entry: 45 %0 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %arg0) 46 ret i8* %0 47} 48 49define void @test_objc_copyWeak(i8** %arg0, i8** %arg1) { 50; CHECK-LABEL: test_objc_copyWeak 51; CHECK-NEXT: entry 52; CHECK-NEXT: call void @objc_copyWeak(i8** %arg0, i8** %arg1) 53; CHECK-NEXT: ret void 54entry: 55 call void @llvm.objc.copyWeak(i8** %arg0, i8** %arg1) 56 ret void 57} 58 59define void @test_objc_destroyWeak(i8** %arg0) { 60; CHECK-LABEL: test_objc_destroyWeak 61; CHECK-NEXT: entry 62; CHECK-NEXT: call void @objc_destroyWeak(i8** %arg0) 63; CHECK-NEXT: ret void 64entry: 65 call void @llvm.objc.destroyWeak(i8** %arg0) 66 ret void 67} 68 69define i8* @test_objc_initWeak(i8** %arg0, i8* %arg1) { 70; CHECK-LABEL: test_objc_initWeak 71; CHECK-NEXT: entry 72; CHECK-NEXT: %0 = call i8* @objc_initWeak(i8** %arg0, i8* %arg1) 73; CHECK-NEXT: ret i8* %0 74entry: 75 %0 = call i8* @llvm.objc.initWeak(i8** %arg0, i8* %arg1) 76 ret i8* %0 77} 78 79define i8* @test_objc_loadWeak(i8** %arg0) { 80; CHECK-LABEL: test_objc_loadWeak 81; CHECK-NEXT: entry 82; CHECK-NEXT: %0 = call i8* @objc_loadWeak(i8** %arg0) 83; CHECK-NEXT: ret i8* %0 84entry: 85 %0 = call i8* @llvm.objc.loadWeak(i8** %arg0) 86 ret i8* %0 87} 88 89define i8* @test_objc_loadWeakRetained(i8** %arg0) { 90; CHECK-LABEL: test_objc_loadWeakRetained 91; CHECK-NEXT: entry 92; CHECK-NEXT: %0 = call i8* @objc_loadWeakRetained(i8** %arg0) 93; CHECK-NEXT: ret i8* %0 94entry: 95 %0 = call i8* @llvm.objc.loadWeakRetained(i8** %arg0) 96 ret i8* %0 97} 98 99define void @test_objc_moveWeak(i8** %arg0, i8** %arg1) { 100; CHECK-LABEL: test_objc_moveWeak 101; CHECK-NEXT: entry 102; CHECK-NEXT: call void @objc_moveWeak(i8** %arg0, i8** %arg1) 103; CHECK-NEXT: ret void 104entry: 105 call void @llvm.objc.moveWeak(i8** %arg0, i8** %arg1) 106 ret void 107} 108 109define void @test_objc_release(i8* %arg0) { 110; CHECK-LABEL: test_objc_release 111; CHECK-NEXT: entry 112; CHECK-NEXT: call void @objc_release(i8* %arg0) 113; CHECK-NEXT: ret void 114entry: 115 call void @llvm.objc.release(i8* %arg0) 116 ret void 117} 118 119define i8* @test_objc_retain(i8* %arg0) { 120; CHECK-LABEL: test_objc_retain 121; CHECK-NEXT: entry 122; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %arg0) 123; CHECK-NEXT: ret i8* %0 124entry: 125 %0 = call i8* @llvm.objc.retain(i8* %arg0) 126 ret i8* %0 127} 128 129define i8* @test_objc_retainAutorelease(i8* %arg0) { 130; CHECK-LABEL: test_objc_retainAutorelease 131; CHECK-NEXT: entry 132; CHECK-NEXT: %0 = call i8* @objc_retainAutorelease(i8* %arg0) 133; CHECK-NEXT: ret i8* %0 134entry: 135 %0 = call i8* @llvm.objc.retainAutorelease(i8* %arg0) 136 ret i8* %0 137} 138 139define i8* @test_objc_retainAutoreleaseReturnValue(i8* %arg0) { 140; CHECK-LABEL: test_objc_retainAutoreleaseReturnValue 141; CHECK-NEXT: entry 142; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %arg0) 143; CHECK-NEXT: ret i8* %0 144entry: 145 %0 = tail call i8* @llvm.objc.retainAutoreleaseReturnValue(i8* %arg0) 146 ret i8* %0 147} 148 149define i8* @test_objc_retainAutoreleasedReturnValue(i8* %arg0) { 150; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue 151; CHECK-NEXT: entry 152; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %arg0) 153; CHECK-NEXT: ret i8* %0 154entry: 155 %0 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %arg0) 156 ret i8* %0 157} 158 159define void @test_objc_retainAutoreleasedReturnValue_bundle() { 160; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue_bundle( 161; CHECK-NEXT: call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] 162 call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] 163 ret void 164} 165 166define void @test_objc_retainAutoreleasedReturnValue_bundle_invoke() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 167; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue_bundle_invoke( 168; CHECK-NEXT: entry 169; CHECK-NEXT: invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] 170entry: 171 invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] 172 to label %invoke.cont unwind label %lpad 173 174invoke.cont: 175 ret void 176 177lpad: 178 %1 = landingpad { i8*, i32 } 179 cleanup 180 resume { i8*, i32 } %1 181} 182 183define i8* @test_objc_retainBlock(i8* %arg0) { 184; CHECK-LABEL: test_objc_retainBlock 185; CHECK-NEXT: entry 186; CHECK-NEXT: %0 = call i8* @objc_retainBlock(i8* %arg0) 187; CHECK-NEXT: ret i8* %0 188entry: 189 %0 = call i8* @llvm.objc.retainBlock(i8* %arg0) 190 ret i8* %0 191} 192 193define void @test_objc_storeStrong(i8** %arg0, i8* %arg1) { 194; CHECK-LABEL: test_objc_storeStrong 195; CHECK-NEXT: entry 196; CHECK-NEXT: call void @objc_storeStrong(i8** %arg0, i8* %arg1) 197; CHECK-NEXT: ret void 198entry: 199 call void @llvm.objc.storeStrong(i8** %arg0, i8* %arg1) 200 ret void 201} 202 203define i8* @test_objc_storeWeak(i8** %arg0, i8* %arg1) { 204; CHECK-LABEL: test_objc_storeWeak 205; CHECK-NEXT: entry 206; CHECK-NEXT: %0 = call i8* @objc_storeWeak(i8** %arg0, i8* %arg1) 207; CHECK-NEXT: ret i8* %0 208entry: 209 %0 = call i8* @llvm.objc.storeWeak(i8** %arg0, i8* %arg1) 210 ret i8* %0 211} 212 213define i8* @test_objc_unsafeClaimAutoreleasedReturnValue(i8* %arg0) { 214; CHECK-LABEL: test_objc_unsafeClaimAutoreleasedReturnValue 215; CHECK-NEXT: entry 216; CHECK-NEXT: %0 = tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %arg0) 217; CHECK-NEXT: ret i8* %0 218entry: 219 %0 = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %arg0) 220 ret i8* %0 221} 222 223define void @test_objc_unsafeClaimAutoreleasedReturnValue_bundle() { 224; CHECK-LABEL: test_objc_unsafeClaimAutoreleasedReturnValue_bundle( 225; CHECK-NEXT: call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_unsafeClaimAutoreleasedReturnValue) ] 226 call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 227 ret void 228} 229 230define i8* @test_objc_retainedObject(i8* %arg0) { 231; CHECK-LABEL: test_objc_retainedObject 232; CHECK-NEXT: entry 233; CHECK-NEXT: %0 = call i8* @objc_retainedObject(i8* %arg0) 234; CHECK-NEXT: ret i8* %0 235entry: 236 %0 = call i8* @llvm.objc.retainedObject(i8* %arg0) 237 ret i8* %0 238} 239 240define i8* @test_objc_unretainedObject(i8* %arg0) { 241; CHECK-LABEL: test_objc_unretainedObject 242; CHECK-NEXT: entry 243; CHECK-NEXT: %0 = call i8* @objc_unretainedObject(i8* %arg0) 244; CHECK-NEXT: ret i8* %0 245entry: 246 %0 = call i8* @llvm.objc.unretainedObject(i8* %arg0) 247 ret i8* %0 248} 249 250define i8* @test_objc_unretainedPointer(i8* %arg0) { 251; CHECK-LABEL: test_objc_unretainedPointer 252; CHECK-NEXT: entry 253; CHECK-NEXT: %0 = call i8* @objc_unretainedPointer(i8* %arg0) 254; CHECK-NEXT: ret i8* %0 255entry: 256 %0 = call i8* @llvm.objc.unretainedPointer(i8* %arg0) 257 ret i8* %0 258} 259 260define i8* @test_objc_retain_autorelease(i8* %arg0) { 261; CHECK-LABEL: test_objc_retain_autorelease 262; CHECK-NEXT: entry 263; CHECK-NEXT: %0 = call i8* @objc_retain_autorelease(i8* %arg0) 264; CHECK-NEXT: ret i8* %0 265entry: 266 %0 = call i8* @llvm.objc.retain.autorelease(i8* %arg0) 267 ret i8* %0 268} 269 270define i32 @test_objc_sync_enter(i8* %arg0) { 271; CHECK-LABEL: test_objc_sync_enter 272; CHECK-NEXT: entry 273; CHECK-NEXT: %0 = call i32 @objc_sync_enter(i8* %arg0) 274; CHECK-NEXT: ret i32 %0 275entry: 276 %0 = call i32 @llvm.objc.sync.enter(i8* %arg0) 277 ret i32 %0 278} 279 280define i32 @test_objc_sync_exit(i8* %arg0) { 281; CHECK-LABEL: test_objc_sync_exit 282; CHECK-NEXT: entry 283; CHECK-NEXT: %0 = call i32 @objc_sync_exit(i8* %arg0) 284; CHECK-NEXT: ret i32 %0 285entry: 286 %0 = call i32 @llvm.objc.sync.exit(i8* %arg0) 287 ret i32 %0 288} 289 290declare i8* @llvm.objc.autorelease(i8*) 291declare void @llvm.objc.autoreleasePoolPop(i8*) 292declare i8* @llvm.objc.autoreleasePoolPush() 293declare i8* @llvm.objc.autoreleaseReturnValue(i8*) 294declare void @llvm.objc.copyWeak(i8**, i8**) 295declare void @llvm.objc.destroyWeak(i8**) 296declare extern_weak i8* @llvm.objc.initWeak(i8**, i8*) 297declare i8* @llvm.objc.loadWeak(i8**) 298declare i8* @llvm.objc.loadWeakRetained(i8**) 299declare void @llvm.objc.moveWeak(i8**, i8**) 300declare void @llvm.objc.release(i8*) 301declare i8* @llvm.objc.retain(i8*) 302declare i8* @llvm.objc.retainAutorelease(i8*) 303declare i8* @llvm.objc.retainAutoreleaseReturnValue(i8*) 304declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) 305declare i8* @llvm.objc.retainBlock(i8*) 306declare void @llvm.objc.storeStrong(i8**, i8*) 307declare i8* @llvm.objc.storeWeak(i8**, i8*) 308declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*) 309declare i8* @llvm.objc.retainedObject(i8*) 310declare i8* @llvm.objc.unretainedObject(i8*) 311declare i8* @llvm.objc.unretainedPointer(i8*) 312declare i8* @llvm.objc.retain.autorelease(i8*) 313declare i32 @llvm.objc.sync.enter(i8*) 314declare i32 @llvm.objc.sync.exit(i8*) 315 316attributes #0 = { nounwind } 317 318; CHECK: declare i8* @objc_autorelease(i8*) 319; CHECK: declare void @objc_autoreleasePoolPop(i8*) 320; CHECK: declare i8* @objc_autoreleasePoolPush() 321; CHECK: declare i8* @objc_autoreleaseReturnValue(i8*) 322; CHECK: declare void @objc_copyWeak(i8**, i8**) 323; CHECK: declare void @objc_destroyWeak(i8**) 324; CHECK: declare extern_weak i8* @objc_initWeak(i8**, i8*) 325; CHECK: declare i8* @objc_loadWeak(i8**) 326; CHECK: declare i8* @objc_loadWeakRetained(i8**) 327; CHECK: declare void @objc_moveWeak(i8**, i8**) 328; CHECK: declare void @objc_release(i8*) [[NLB:#[0-9]+]] 329; CHECK: declare i8* @objc_retain(i8*) [[NLB]] 330; CHECK: declare i8* @objc_retainAutorelease(i8*) 331; CHECK: declare i8* @objc_retainAutoreleaseReturnValue(i8*) 332; CHECK: declare i8* @objc_retainAutoreleasedReturnValue(i8*) 333; CHECK: declare i8* @objc_retainBlock(i8*) 334; CHECK: declare void @objc_storeStrong(i8**, i8*) 335; CHECK: declare i8* @objc_storeWeak(i8**, i8*) 336; CHECK: declare i8* @objc_unsafeClaimAutoreleasedReturnValue(i8*) 337; CHECK: declare i8* @objc_retainedObject(i8*) 338; CHECK: declare i8* @objc_unretainedObject(i8*) 339; CHECK: declare i8* @objc_unretainedPointer(i8*) 340; CHECK: declare i8* @objc_retain_autorelease(i8*) 341; CHECK: declare i32 @objc_sync_enter(i8*) 342; CHECK: declare i32 @objc_sync_exit(i8*) 343 344; CHECK: attributes #0 = { nounwind } 345; CHECK: attributes [[NLB]] = { nonlazybind } 346