Skip to content

Commit 62623bd

Browse files
committed
OK
1 parent 8e01e91 commit 62623bd

File tree

9 files changed

+2758
-1052
lines changed

9 files changed

+2758
-1052
lines changed

llvm/test/Transforms/ObjCARC/allocas.ll

Lines changed: 288 additions & 115 deletions
Large diffs are not rendered by default.

llvm/test/Transforms/ObjCARC/basic.ll

Lines changed: 1530 additions & 704 deletions
Large diffs are not rendered by default.

llvm/test/Transforms/ObjCARC/clang-arc-use-barrier.ll

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
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

34
%0 = type opaque
45

56
; Make sure ARC optimizer doesn't sink @obj_retain past @llvm.objc.clang.arc.use.
67

7-
; CHECK: call ptr @llvm.objc.retain
8-
; CHECK: call void (...) @llvm.objc.clang.arc.use(
9-
; CHECK: call ptr @llvm.objc.retain
10-
; CHECK: call void (...) @llvm.objc.clang.arc.use(
118

129
define void @runTest() local_unnamed_addr {
10+
; CHECK-LABEL: define void @runTest() local_unnamed_addr {
11+
; CHECK-NEXT: [[TMP1:%.*]] = alloca ptr, align 8
12+
; CHECK-NEXT: [[TMP2:%.*]] = alloca ptr, align 8
13+
; CHECK-NEXT: [[TMP3:%.*]] = tail call ptr @foo0()
14+
; CHECK-NEXT: [[TMP4:%.*]] = tail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[TMP3]]) #[[ATTR0:[0-9]+]]
15+
; CHECK-NEXT: store ptr [[TMP3]], ptr [[TMP1]], align 8
16+
; CHECK-NEXT: call void @foo1(ptr nonnull [[TMP1]])
17+
; CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP1]], align 8
18+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP5]]) #[[ATTR0]]
19+
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[TMP3]])
20+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP3]]) #[[ATTR0]]
21+
; CHECK-NEXT: store ptr [[TMP5]], ptr [[TMP2]], align 8
22+
; CHECK-NEXT: call void @foo1(ptr nonnull [[TMP2]])
23+
; CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[TMP2]], align 8
24+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[TMP6]]) #[[ATTR0]]
25+
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[TMP5]])
26+
; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP2]], align 8
27+
; CHECK-NEXT: [[TMP7:%.*]] = tail call ptr @llvm.objc.retain(ptr [[TMP5]]) #[[ATTR0]]
28+
; CHECK-NEXT: call void @foo2(ptr [[TMP6]])
29+
; CHECK-NEXT: [[TMP8:%.*]] = tail call ptr @llvm.objc.retain(ptr [[TMP6]]) #[[ATTR0]]
30+
; CHECK-NEXT: ret void
31+
;
1332
%1 = alloca ptr, align 8
1433
%2 = alloca ptr, align 8
1534
%3 = tail call ptr @foo0()

llvm/test/Transforms/ObjCARC/code-motion.ll

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
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

34
declare 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

1514
define 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

3339
define 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

5367
define 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

89104
define 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

134150
define 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+
;.

llvm/test/Transforms/ObjCARC/funclet-catchpad.ll

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,31 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12
; RUN: opt -mtriple=x86_64-windows-msvc -passes=objc-arc -S < %s | FileCheck %s
23

34
; Check that funclet tokens are preserved
45
;
56
; CHECK-LABEL: catch:
67
; CHECK: %1 = catchpad within %0
7-
; CHECK: %2 = tail call ptr @llvm.objc.retain(ptr %exn) #0 [ "funclet"(token %1) ]
8-
; CHECK: call void @llvm.objc.release(ptr %exn) #0 [ "funclet"(token %1) ]
9-
; CHECK: catchret from %1 to label %eh.cont
108

119
define void @try_catch_with_objc_intrinsic() personality ptr @__CxxFrameHandler3 {
10+
; CHECK-LABEL: define void @try_catch_with_objc_intrinsic() personality ptr @__CxxFrameHandler3 {
11+
; CHECK-NEXT: [[ENTRY:.*:]]
12+
; CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8
13+
; CHECK-NEXT: invoke void @may_throw(ptr null)
14+
; CHECK-NEXT: to label %[[EH_CONT:.*]] unwind label %[[CATCH_DISPATCH:.*]]
15+
; CHECK: [[CATCH_DISPATCH]]:
16+
; CHECK-NEXT: [[TMP0:%.*]] = catchswitch within none [label %catch] unwind to caller
17+
; CHECK: [[EH_CONT]]:
18+
; CHECK-NEXT: ret void
19+
; CHECK: [[CATCH:.*:]]
20+
; CHECK-NEXT: [[TMP1:%.*]] = catchpad within [[TMP0]] [ptr null, i32 0, ptr %exn.slot]
21+
; CHECK-NEXT: br label %[[IF_THEN:.*]]
22+
; CHECK: [[IF_THEN]]:
23+
; CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr null, align 8
24+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[EXN]]) #[[ATTR0:[0-9]+]] [ "funclet"(token [[TMP1]]) ]
25+
; CHECK-NEXT: call void @may_throw(ptr [[EXN]])
26+
; CHECK-NEXT: [[TMP2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[EXN]]) #[[ATTR0]] [ "funclet"(token [[TMP1]]) ]
27+
; CHECK-NEXT: catchret from [[TMP1]] to label %[[EH_CONT]]
28+
;
1229
entry:
1330
%exn.slot = alloca ptr, align 8
1431
invoke void @may_throw(ptr null) to label %eh.cont unwind label %catch.dispatch

llvm/test/Transforms/ObjCARC/intrinsic-use.ll

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
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

34
target datalayout = "e-p:64:64:64"
@@ -16,29 +17,33 @@ declare void @can_release(ptr)
1617
; Ensure that we honor clang.arc.use as a use and don't miscompile
1718
; the reduced test case from <rdar://13195034>.
1819
;
19-
; CHECK-LABEL: define void @test0(
20-
; CHECK: @llvm.objc.retain(ptr %x)
21-
; CHECK-NEXT: store ptr %y, ptr %temp0
22-
; CHECK-NEXT: @llvm.objc.retain(ptr %y)
23-
; CHECK-NEXT: call void @test0_helper
24-
; CHECK-NEXT: [[VAL1:%.*]] = load ptr, ptr %temp0
25-
; CHECK-NEXT: @llvm.objc.retain(ptr [[VAL1]])
26-
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr %y)
27-
; CHECK-NEXT: @llvm.objc.release(ptr %y)
28-
; CHECK-NEXT: store ptr [[VAL1]], ptr %temp1
29-
; CHECK-NEXT: call void @test0_helper
30-
; CHECK-NEXT: [[VAL2:%.*]] = load ptr, ptr %temp1
31-
; CHECK-NEXT: @llvm.objc.retain(ptr [[VAL2]])
32-
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[VAL1]])
33-
; CHECK-NEXT: @llvm.objc.release(ptr [[VAL1]])
34-
; CHECK-NEXT: @llvm.objc.autorelease(ptr %x)
35-
; CHECK-NEXT: store ptr %x, ptr %out
36-
; CHECK-NEXT: @llvm.objc.retain(ptr %x)
37-
; CHECK-NEXT: @llvm.objc.release(ptr [[VAL2]])
38-
; CHECK-NEXT: @llvm.objc.release(ptr %x)
39-
; CHECK-NEXT: ret void
40-
; CHECK-NEXT: }
4120
define void @test0(ptr %out, ptr %x, ptr %y) {
21+
; CHECK-LABEL: define void @test0(
22+
; CHECK-SAME: ptr [[OUT:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]]) {
23+
; CHECK-NEXT: [[ENTRY:.*:]]
24+
; CHECK-NEXT: [[TEMP0:%.*]] = alloca ptr, align 8
25+
; CHECK-NEXT: [[TEMP1:%.*]] = alloca ptr, align 8
26+
; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[X]]) #[[ATTR0:[0-9]+]]
27+
; CHECK-NEXT: store ptr [[Y]], ptr [[TEMP0]], align 8
28+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[Y]]) #[[ATTR0]]
29+
; CHECK-NEXT: call void @test0_helper(ptr [[X]], ptr [[TEMP0]])
30+
; CHECK-NEXT: [[VAL1:%.*]] = load ptr, ptr [[TEMP0]], align 8
31+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[VAL1]]) #[[ATTR0]]
32+
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[Y]]) #[[ATTR0]]
33+
; CHECK-NEXT: [[TMP1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[Y]]) #[[ATTR0]]
34+
; CHECK-NEXT: store ptr [[VAL1]], ptr [[TEMP1]], align 8
35+
; CHECK-NEXT: call void @test0_helper(ptr [[X]], ptr [[TEMP1]])
36+
; CHECK-NEXT: [[VAL2:%.*]] = load ptr, ptr [[TEMP1]], align 8
37+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[VAL2]]) #[[ATTR0]]
38+
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[VAL1]]) #[[ATTR0]]
39+
; CHECK-NEXT: [[TMP2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[VAL1]]) #[[ATTR0]]
40+
; CHECK-NEXT: [[TMP3:%.*]] = call ptr @llvm.objc.autorelease(ptr [[X]]) #[[ATTR0]]
41+
; CHECK-NEXT: store ptr [[X]], ptr [[OUT]], align 8
42+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[X]]) #[[ATTR0]]
43+
; CHECK-NEXT: [[TMP4:%.*]] = tail call ptr @llvm.objc.retain(ptr [[VAL2]]) #[[ATTR0]]
44+
; CHECK-NEXT: [[TMP5:%.*]] = tail call ptr @llvm.objc.retain(ptr [[X]]) #[[ATTR0]]
45+
; CHECK-NEXT: ret void
46+
;
4247
entry:
4348
%temp0 = alloca ptr, align 8
4449
%temp1 = alloca ptr, align 8
@@ -64,27 +69,31 @@ entry:
6469
ret void
6570
}
6671

67-
; CHECK-LABEL: define void @test0a(
68-
; CHECK: @llvm.objc.retain(ptr %x)
69-
; CHECK-NEXT: store ptr %y, ptr %temp0
70-
; CHECK-NEXT: @llvm.objc.retain(ptr %y)
71-
; CHECK-NEXT: call void @test0_helper
72-
; CHECK-NEXT: [[VAL1:%.*]] = load ptr, ptr %temp0
73-
; CHECK-NEXT: @llvm.objc.retain(ptr [[VAL1]])
74-
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr %y)
75-
; CHECK-NEXT: @llvm.objc.release(ptr %y)
76-
; CHECK-NEXT: store ptr [[VAL1]], ptr %temp1
77-
; CHECK-NEXT: call void @test0_helper
78-
; CHECK-NEXT: [[VAL2:%.*]] = load ptr, ptr %temp1
79-
; CHECK-NEXT: @llvm.objc.retain(ptr [[VAL2]])
80-
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[VAL1]])
81-
; CHECK-NEXT: @llvm.objc.release(ptr [[VAL1]])
82-
; CHECK-NEXT: @llvm.objc.autorelease(ptr %x)
83-
; CHECK-NEXT: @llvm.objc.release(ptr [[VAL2]])
84-
; CHECK-NEXT: store ptr %x, ptr %out
85-
; CHECK-NEXT: ret void
86-
; CHECK-NEXT: }
8772
define void @test0a(ptr %out, ptr %x, ptr %y) {
73+
; CHECK-LABEL: define void @test0a(
74+
; CHECK-SAME: ptr [[OUT:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]]) {
75+
; CHECK-NEXT: [[ENTRY:.*:]]
76+
; CHECK-NEXT: [[TEMP0:%.*]] = alloca ptr, align 8
77+
; CHECK-NEXT: [[TEMP1:%.*]] = alloca ptr, align 8
78+
; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[X]]) #[[ATTR0]]
79+
; CHECK-NEXT: store ptr [[Y]], ptr [[TEMP0]], align 8
80+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[Y]]) #[[ATTR0]], !clang.imprecise_release [[META0:![0-9]+]]
81+
; CHECK-NEXT: call void @test0_helper(ptr [[X]], ptr [[TEMP0]])
82+
; CHECK-NEXT: [[VAL1:%.*]] = load ptr, ptr [[TEMP0]], align 8
83+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[VAL1]]) #[[ATTR0]], !clang.imprecise_release [[META0]]
84+
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[Y]]) #[[ATTR0]]
85+
; CHECK-NEXT: [[TMP1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[Y]]) #[[ATTR0]]
86+
; CHECK-NEXT: store ptr [[VAL1]], ptr [[TEMP1]], align 8
87+
; CHECK-NEXT: call void @test0_helper(ptr [[X]], ptr [[TEMP1]])
88+
; CHECK-NEXT: [[VAL2:%.*]] = load ptr, ptr [[TEMP1]], align 8
89+
; CHECK-NEXT: call void @llvm.objc.release(ptr [[VAL2]]) #[[ATTR0]], !clang.imprecise_release [[META0]]
90+
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[VAL1]]) #[[ATTR0]]
91+
; CHECK-NEXT: [[TMP2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[VAL1]]) #[[ATTR0]]
92+
; CHECK-NEXT: [[TMP3:%.*]] = call ptr @llvm.objc.autorelease(ptr [[X]]) #[[ATTR0]]
93+
; CHECK-NEXT: [[TMP4:%.*]] = tail call ptr @llvm.objc.retain(ptr [[VAL2]]) #[[ATTR0]]
94+
; CHECK-NEXT: store ptr [[X]], ptr [[OUT]], align 8
95+
; CHECK-NEXT: ret void
96+
;
8897
entry:
8998
%temp0 = alloca ptr, align 8
9099
%temp1 = alloca ptr, align 8
@@ -113,12 +122,14 @@ entry:
113122
; ARC optimizer should be able to safely remove the retain/release pair as the
114123
; call to @llvm.objc.clang.arc.noop.use is a no-op.
115124

116-
; CHECK-LABEL: define void @test_arc_noop_use(
117-
; CHECK-NEXT: call void @can_release(ptr %x)
118-
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
119-
; CHECK-NEXT: ret void
120125

121126
define void @test_arc_noop_use(ptr %out, ptr %x) {
127+
; CHECK-LABEL: define void @test_arc_noop_use(
128+
; CHECK-SAME: ptr [[OUT:%.*]], ptr [[X:%.*]]) {
129+
; CHECK-NEXT: call void @can_release(ptr [[X]])
130+
; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[X]])
131+
; CHECK-NEXT: ret void
132+
;
122133
call ptr @llvm.objc.retain(ptr %x)
123134
call void @can_release(ptr %x)
124135
call void (...) @llvm.objc.clang.arc.noop.use(ptr %x)
@@ -128,3 +139,6 @@ define void @test_arc_noop_use(ptr %out, ptr %x) {
128139

129140
!0 = !{}
130141

142+
;.
143+
; CHECK: [[META0]] = !{}
144+
;.

0 commit comments

Comments
 (0)