1 ; RUN: opt -basicaa -objc-arc -S < %s | FileCheck %s 2 3 target datalayout = "e-p:64:64:64" 4 5 declare i8* @objc_retain(i8*) 6 declare i8* @objc_retainAutorelease(i8*) 7 declare void @objc_release(i8*) 8 declare i8* @objc_autorelease(i8*) 9 10 declare void @clang.arc.use(...) 11 12 declare 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: @objc_retain(i8* %x) 19 ; CHECK-NEXT: store i8* %y, i8** %temp0 20 ; CHECK-NEXT: @objc_retain(i8* %y) 21 ; CHECK-NEXT: call void @test0_helper 22 ; CHECK-NEXT: [[VAL1:%.*]] = load i8*, i8** %temp0 23 ; CHECK-NEXT: @objc_retain(i8* [[VAL1]]) 24 ; CHECK-NEXT: call void (...) @clang.arc.use(i8* %y) 25 ; CHECK-NEXT: @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: @objc_retain(i8* [[VAL2]]) 30 ; CHECK-NEXT: call void (...) @clang.arc.use(i8* [[VAL1]]) 31 ; CHECK-NEXT: @objc_release(i8* [[VAL1]]) 32 ; CHECK-NEXT: @objc_autorelease(i8* %x) 33 ; CHECK-NEXT: store i8* %x, i8** %out 34 ; CHECK-NEXT: @objc_retain(i8* %x) 35 ; CHECK-NEXT: @objc_release(i8* [[VAL2]]) 36 ; CHECK-NEXT: @objc_release(i8* %x) 37 ; CHECK-NEXT: ret void 38 ; CHECK-NEXT: } 39 define void @test0(i8** %out, i8* %x, i8* %y) { 40 entry: 41 %temp0 = alloca i8*, align 8 42 %temp1 = alloca i8*, align 8 43 %0 = call i8* @objc_retain(i8* %x) nounwind 44 %1 = call i8* @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* @objc_retain(i8* %val1) nounwind 49 call void (...) @clang.arc.use(i8* %y) nounwind 50 call void @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* @objc_retain(i8* %val2) nounwind 55 call void (...) @clang.arc.use(i8* %val1) nounwind 56 call void @objc_release(i8* %val1) nounwind 57 %4 = call i8* @objc_retain(i8* %x) nounwind 58 %5 = call i8* @objc_autorelease(i8* %x) nounwind 59 store i8* %x, i8** %out 60 call void @objc_release(i8* %val2) nounwind 61 call void @objc_release(i8* %x) nounwind 62 ret void 63 } 64 65 ; CHECK-LABEL: define void @test0a( 66 ; CHECK: @objc_retain(i8* %x) 67 ; CHECK-NEXT: store i8* %y, i8** %temp0 68 ; CHECK-NEXT: @objc_retain(i8* %y) 69 ; CHECK-NEXT: call void @test0_helper 70 ; CHECK-NEXT: [[VAL1:%.*]] = load i8*, i8** %temp0 71 ; CHECK-NEXT: @objc_retain(i8* [[VAL1]]) 72 ; CHECK-NEXT: call void (...) @clang.arc.use(i8* %y) 73 ; CHECK-NEXT: @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: @objc_retain(i8* [[VAL2]]) 78 ; CHECK-NEXT: call void (...) @clang.arc.use(i8* [[VAL1]]) 79 ; CHECK-NEXT: @objc_release(i8* [[VAL1]]) 80 ; CHECK-NEXT: @objc_autorelease(i8* %x) 81 ; CHECK-NEXT: @objc_release(i8* [[VAL2]]) 82 ; CHECK-NEXT: store i8* %x, i8** %out 83 ; CHECK-NEXT: ret void 84 ; CHECK-NEXT: } 85 define void @test0a(i8** %out, i8* %x, i8* %y) { 86 entry: 87 %temp0 = alloca i8*, align 8 88 %temp1 = alloca i8*, align 8 89 %0 = call i8* @objc_retain(i8* %x) nounwind 90 %1 = call i8* @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* @objc_retain(i8* %val1) nounwind 95 call void (...) @clang.arc.use(i8* %y) nounwind 96 call void @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* @objc_retain(i8* %val2) nounwind 101 call void (...) @clang.arc.use(i8* %val1) nounwind 102 call void @objc_release(i8* %val1) nounwind, !clang.imprecise_release !0 103 %4 = call i8* @objc_retain(i8* %x) nounwind 104 %5 = call i8* @objc_autorelease(i8* %x) nounwind 105 store i8* %x, i8** %out 106 call void @objc_release(i8* %val2) nounwind, !clang.imprecise_release !0 107 call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 108 ret void 109 } 110 111 112 !0 = !{} 113 114