1+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12; RUN: opt -passes=objc-arc -S < %s | FileCheck %s
23
34declare void @alterRefCount ()
@@ -9,10 +10,18 @@ declare void @readOnlyFunc(ptr, ptr)
910; Check that ARC optimizer doesn't reverse the order of the retain call and the
1011; release call when there are debug instructions.
1112
12- ; CHECK: call ptr @llvm.objc.retain(ptr %x)
13- ; CHECK: call void @llvm.objc.release(ptr %x)
1413
1514define i32 @test (ptr %x , ptr %y , i8 %z , i32 %i ) {
15+ ; CHECK-LABEL: define i32 @test(
16+ ; CHECK-SAME: ptr [[X:%.*]], ptr [[Y:%.*]], i8 [[Z:%.*]], i32 [[I:%.*]]) {
17+ ; CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4
18+ ; CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4
19+ ; CHECK-NEXT: store i8 [[Z]], ptr [[X]], align 1
20+ ; CHECK-NEXT: tail call void @llvm.objc.release(ptr [[X]]) #[[ATTR0:[0-9]+]]
21+ ; CHECK-NEXT: call void @alterRefCount()
22+ ; CHECK-NEXT: [[TMP1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[X]]) #[[ATTR0]]
23+ ; CHECK-NEXT: ret i32 [[I]]
24+ ;
1625 %i.addr = alloca i32 , align 4
1726 store i32 %i , ptr %i.addr , align 4
1827 %v1 = tail call ptr @llvm.objc.retain (ptr %x )
@@ -26,11 +35,16 @@ define i32 @test(ptr %x, ptr %y, i8 %z, i32 %i) {
2635; ARC optimizer shouldn't move the release call, which is a precise release call
2736; past the call to @alterRefCount.
2837
29- ; CHECK-LABEL: define void @test2(
30- ; CHECK: call void @alterRefCount(
31- ; CHECK: call void @llvm.objc.release(
3238
3339define void @test2 () {
40+ ; CHECK-LABEL: define void @test2() {
41+ ; CHECK-NEXT: [[V0:%.*]] = load ptr, ptr @g0, align 8
42+ ; CHECK-NEXT: tail call void @llvm.objc.release(ptr [[V0]]) #[[ATTR0]]
43+ ; CHECK-NEXT: tail call void @use(ptr [[V0]])
44+ ; CHECK-NEXT: tail call void @alterRefCount()
45+ ; CHECK-NEXT: [[TMP1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[V0]]) #[[ATTR0]]
46+ ; CHECK-NEXT: ret void
47+ ;
3448 %v0 = load ptr , ptr @g0 , align 8
3549 %v1 = tail call ptr @llvm.objc.retain (ptr %v0 )
3650 tail call void @use (ptr %v0 )
@@ -51,20 +65,21 @@ define void @test2() {
5165; Ideally, the retain/release pairs in BB if.then should be removed.
5266
5367define void @test3 (ptr %obj , i1 %cond ) {
54- ; CHECK-LABEL: @test3(
55- ; CHECK-NEXT: [[TMP2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ:%.*]])
56- ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
57- ; CHECK: if.then:
58- ; CHECK-NEXT: call void @readOnlyFunc(ptr [[OBJ]], ptr null)
68+ ; CHECK-LABEL: define void @test3(
69+ ; CHECK-SAME: ptr [[OBJ:%.*]], i1 [[COND:%.*]]) {
70+ ; CHECK-NEXT: [[V0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ]]) #[[ATTR0]]
71+ ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
72+ ; CHECK: [[IF_THEN]]:
73+ ; CHECK-NEXT: call void @readOnlyFunc(ptr [[OBJ]], ptr null) #[[ATTR1:[0-9]+]]
5974; CHECK-NEXT: [[TMP1:%.*]] = add i32 1, 2
6075; CHECK-NEXT: call void @alterRefCount()
61- ; CHECK-NEXT: br label [[JOIN:% .*]]
62- ; CHECK: if.else :
76+ ; CHECK-NEXT: br label % [[JOIN:.*]]
77+ ; CHECK: [[IF_ELSE]] :
6378; CHECK-NEXT: call void @alterRefCount()
6479; CHECK-NEXT: call void @use(ptr [[OBJ]])
65- ; CHECK-NEXT: br label [[JOIN]]
66- ; CHECK: join :
67- ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ]]) {{.*}} , !clang.imprecise_release !2
80+ ; CHECK-NEXT: br label % [[JOIN]]
81+ ; CHECK: [[JOIN]] :
82+ ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ]]) #[[ATTR0]] , !clang.imprecise_release [[META2:![0-9]+]]
6883; CHECK-NEXT: ret void
6984;
7085 %v0 = call ptr @llvm.objc.retain (ptr %obj )
@@ -87,23 +102,24 @@ join:
87102}
88103
89104define void @test4 (ptr %obj0 , ptr %obj1 , i1 %cond ) {
90- ; CHECK-LABEL: @test4(
91- ; CHECK-NEXT: [[TMP3:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ0:%.*]])
92- ; CHECK-NEXT: [[TMP2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ1:%.*]])
93- ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
94- ; CHECK: if.then:
95- ; CHECK-NEXT: call void @readOnlyFunc(ptr [[OBJ0]], ptr [[OBJ1]])
105+ ; CHECK-LABEL: define void @test4(
106+ ; CHECK-SAME: ptr [[OBJ0:%.*]], ptr [[OBJ1:%.*]], i1 [[COND:%.*]]) {
107+ ; CHECK-NEXT: [[V0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ0]]) #[[ATTR0]]
108+ ; CHECK-NEXT: [[V1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ1]]) #[[ATTR0]]
109+ ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
110+ ; CHECK: [[IF_THEN]]:
111+ ; CHECK-NEXT: call void @readOnlyFunc(ptr [[OBJ0]], ptr [[OBJ1]]) #[[ATTR1]]
96112; CHECK-NEXT: [[TMP1:%.*]] = add i32 1, 2
97113; CHECK-NEXT: call void @alterRefCount()
98- ; CHECK-NEXT: br label [[JOIN:% .*]]
99- ; CHECK: if.else :
114+ ; CHECK-NEXT: br label % [[JOIN:.*]]
115+ ; CHECK: [[IF_ELSE]] :
100116; CHECK-NEXT: call void @alterRefCount()
101117; CHECK-NEXT: call void @use(ptr [[OBJ0]])
102118; CHECK-NEXT: call void @use(ptr [[OBJ1]])
103- ; CHECK-NEXT: br label [[JOIN]]
104- ; CHECK: join :
105- ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ0]]) {{.*}} , !clang.imprecise_release !2
106- ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ1]]) {{.*}} , !clang.imprecise_release !2
119+ ; CHECK-NEXT: br label % [[JOIN]]
120+ ; CHECK: [[JOIN]] :
121+ ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ0]]) #[[ATTR0]] , !clang.imprecise_release [[META2]]
122+ ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ1]]) #[[ATTR0]] , !clang.imprecise_release [[META2]]
107123; CHECK-NEXT: ret void
108124;
109125 %v0 = call ptr @llvm.objc.retain (ptr %obj0 )
@@ -132,26 +148,27 @@ join:
132148; eliminated are in different blocks (bb1 and if.then).
133149
134150define void @test5 (ptr %obj , i1 %cond0 , i1 %cond1 ) {
135- ; CHECK-LABEL: @test5(
136- ; CHECK-NEXT: [[V0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ:%.*]])
137- ; CHECK-NEXT: br i1 [[COND0:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
138- ; CHECK: if.then:
139- ; CHECK-NEXT: call void @readOnlyFunc(ptr [[OBJ]], ptr null)
140- ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[IF_THEN2:%.*]], label [[IF_ELSE2:%.*]]
141- ; CHECK: if.then2:
142- ; CHECK-NEXT: br label [[BB1:%.*]]
143- ; CHECK: if.else2:
144- ; CHECK-NEXT: br label [[BB1]]
145- ; CHECK: bb1:
151+ ; CHECK-LABEL: define void @test5(
152+ ; CHECK-SAME: ptr [[OBJ:%.*]], i1 [[COND0:%.*]], i1 [[COND1:%.*]]) {
153+ ; CHECK-NEXT: [[V0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ]]) #[[ATTR0]]
154+ ; CHECK-NEXT: br i1 [[COND0]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
155+ ; CHECK: [[IF_THEN]]:
156+ ; CHECK-NEXT: call void @readOnlyFunc(ptr [[OBJ]], ptr null) #[[ATTR1]]
157+ ; CHECK-NEXT: br i1 [[COND1]], label %[[IF_THEN2:.*]], label %[[IF_ELSE2:.*]]
158+ ; CHECK: [[IF_THEN2]]:
159+ ; CHECK-NEXT: br label %[[BB1:.*]]
160+ ; CHECK: [[IF_ELSE2]]:
161+ ; CHECK-NEXT: br label %[[BB1]]
162+ ; CHECK: [[BB1]]:
146163; CHECK-NEXT: [[TMP1:%.*]] = add i32 1, 2
147164; CHECK-NEXT: call void @alterRefCount()
148- ; CHECK-NEXT: br label [[JOIN:% .*]]
149- ; CHECK: if.else :
165+ ; CHECK-NEXT: br label % [[JOIN:.*]]
166+ ; CHECK: [[IF_ELSE]] :
150167; CHECK-NEXT: call void @alterRefCount()
151168; CHECK-NEXT: call void @use(ptr [[OBJ]])
152- ; CHECK-NEXT: br label [[JOIN]]
153- ; CHECK: join :
154- ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ]])
169+ ; CHECK-NEXT: br label % [[JOIN]]
170+ ; CHECK: [[JOIN]] :
171+ ; CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ]]) #[[ATTR0]], !clang.imprecise_release [[META2]]
155172; CHECK-NEXT: ret void
156173;
157174 %v0 = call ptr @llvm.objc.retain (ptr %obj )
@@ -201,3 +218,6 @@ attributes #0 = { readonly }
201218!8 = distinct !DICompileUnit (language: DW_LANG_ObjC, file: !4 , isOptimized: false , runtimeVersion: 2 , emissionKind: FullDebug, enums: !9 , nameTableKind: None)
202219!9 = !{}
203220!10 = !DILocation (line: 1 , column: 14 , scope: !3 )
221+ ;.
222+ ; CHECK: [[META2]] = !{}
223+ ;.
0 commit comments