1; RUN: opt -basic-aa -objc-arc -S < %s | FileCheck %s 2 3target datalayout = "e-p:64:64:64" 4 5declare i8* @llvm.objc.retain(i8*) 6declare i8* @llvm.objc.retainAutorelease(i8*) 7declare void @llvm.objc.release(i8*) 8declare i8* @llvm.objc.autorelease(i8*) 9 10declare void @llvm.objc.clang.arc.use(...) 11 12declare void @test0_helper(i8*, i8**) 13 14; Ensure that we honor clang.arc.use as a use and don't miscompile 15; the reduced test case from <rdar://13195034>. 16; 17; CHECK-LABEL: define void @test0( 18; CHECK: @llvm.objc.retain(i8* %x) 19; CHECK-NEXT: store i8* %y, i8** %temp0 20; CHECK-NEXT: @llvm.objc.retain(i8* %y) 21; CHECK-NEXT: call void @test0_helper 22; CHECK-NEXT: [[VAL1:%.*]] = load i8*, i8** %temp0 23; CHECK-NEXT: @llvm.objc.retain(i8* [[VAL1]]) 24; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* %y) 25; CHECK-NEXT: @llvm.objc.release(i8* %y) 26; CHECK-NEXT: store i8* [[VAL1]], i8** %temp1 27; CHECK-NEXT: call void @test0_helper 28; CHECK-NEXT: [[VAL2:%.*]] = load i8*, i8** %temp1 29; CHECK-NEXT: @llvm.objc.retain(i8* [[VAL2]]) 30; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[VAL1]]) 31; CHECK-NEXT: @llvm.objc.release(i8* [[VAL1]]) 32; CHECK-NEXT: @llvm.objc.autorelease(i8* %x) 33; CHECK-NEXT: store i8* %x, i8** %out 34; CHECK-NEXT: @llvm.objc.retain(i8* %x) 35; CHECK-NEXT: @llvm.objc.release(i8* [[VAL2]]) 36; CHECK-NEXT: @llvm.objc.release(i8* %x) 37; CHECK-NEXT: ret void 38; CHECK-NEXT: } 39define void @test0(i8** %out, i8* %x, i8* %y) { 40entry: 41 %temp0 = alloca i8*, align 8 42 %temp1 = alloca i8*, align 8 43 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind 44 %1 = call i8* @llvm.objc.retain(i8* %y) nounwind 45 store i8* %y, i8** %temp0 46 call void @test0_helper(i8* %x, i8** %temp0) 47 %val1 = load i8*, i8** %temp0 48 %2 = call i8* @llvm.objc.retain(i8* %val1) nounwind 49 call void (...) @llvm.objc.clang.arc.use(i8* %y) nounwind 50 call void @llvm.objc.release(i8* %y) nounwind 51 store i8* %val1, i8** %temp1 52 call void @test0_helper(i8* %x, i8** %temp1) 53 %val2 = load i8*, i8** %temp1 54 %3 = call i8* @llvm.objc.retain(i8* %val2) nounwind 55 call void (...) @llvm.objc.clang.arc.use(i8* %val1) nounwind 56 call void @llvm.objc.release(i8* %val1) nounwind 57 %4 = call i8* @llvm.objc.retain(i8* %x) nounwind 58 %5 = call i8* @llvm.objc.autorelease(i8* %x) nounwind 59 store i8* %x, i8** %out 60 call void @llvm.objc.release(i8* %val2) nounwind 61 call void @llvm.objc.release(i8* %x) nounwind 62 ret void 63} 64 65; CHECK-LABEL: define void @test0a( 66; CHECK: @llvm.objc.retain(i8* %x) 67; CHECK-NEXT: store i8* %y, i8** %temp0 68; CHECK-NEXT: @llvm.objc.retain(i8* %y) 69; CHECK-NEXT: call void @test0_helper 70; CHECK-NEXT: [[VAL1:%.*]] = load i8*, i8** %temp0 71; CHECK-NEXT: @llvm.objc.retain(i8* [[VAL1]]) 72; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* %y) 73; CHECK-NEXT: @llvm.objc.release(i8* %y) 74; CHECK-NEXT: store i8* [[VAL1]], i8** %temp1 75; CHECK-NEXT: call void @test0_helper 76; CHECK-NEXT: [[VAL2:%.*]] = load i8*, i8** %temp1 77; CHECK-NEXT: @llvm.objc.retain(i8* [[VAL2]]) 78; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[VAL1]]) 79; CHECK-NEXT: @llvm.objc.release(i8* [[VAL1]]) 80; CHECK-NEXT: @llvm.objc.autorelease(i8* %x) 81; CHECK-NEXT: @llvm.objc.release(i8* [[VAL2]]) 82; CHECK-NEXT: store i8* %x, i8** %out 83; CHECK-NEXT: ret void 84; CHECK-NEXT: } 85define void @test0a(i8** %out, i8* %x, i8* %y) { 86entry: 87 %temp0 = alloca i8*, align 8 88 %temp1 = alloca i8*, align 8 89 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind 90 %1 = call i8* @llvm.objc.retain(i8* %y) nounwind 91 store i8* %y, i8** %temp0 92 call void @test0_helper(i8* %x, i8** %temp0) 93 %val1 = load i8*, i8** %temp0 94 %2 = call i8* @llvm.objc.retain(i8* %val1) nounwind 95 call void (...) @llvm.objc.clang.arc.use(i8* %y) nounwind 96 call void @llvm.objc.release(i8* %y) nounwind, !clang.imprecise_release !0 97 store i8* %val1, i8** %temp1 98 call void @test0_helper(i8* %x, i8** %temp1) 99 %val2 = load i8*, i8** %temp1 100 %3 = call i8* @llvm.objc.retain(i8* %val2) nounwind 101 call void (...) @llvm.objc.clang.arc.use(i8* %val1) nounwind 102 call void @llvm.objc.release(i8* %val1) nounwind, !clang.imprecise_release !0 103 %4 = call i8* @llvm.objc.retain(i8* %x) nounwind 104 %5 = call i8* @llvm.objc.autorelease(i8* %x) nounwind 105 store i8* %x, i8** %out 106 call void @llvm.objc.release(i8* %val2) nounwind, !clang.imprecise_release !0 107 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0 108 ret void 109} 110 111 112!0 = !{} 113 114