Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit a98729b

Browse files
committed
The promised test case for r175939.
This test makes sure that the ObjCARC escape analysis looks at the uses of instructions which copy the block pointer value by checking all four cases where that can occur. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177232 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3249729 commit a98729b

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
; RUN: opt -S -objc-arc < %s | FileCheck %s
2+
3+
declare i8* @objc_retain(i8*) nonlazybind
4+
declare void @objc_release(i8*) nonlazybind
5+
declare i8* @objc_retainBlock(i8*)
6+
7+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8+
; Use by an instruction which copies the value is an escape if the ;
9+
; result is an escape. The current instructions with this property are: ;
10+
; ;
11+
; 1. BitCast. ;
12+
; 2. GEP. ;
13+
; 3. PhiNode. ;
14+
; 4. SelectInst. ;
15+
; ;
16+
; Make sure that such instructions do not confuse the optimizer into removing ;
17+
; an objc_retainBlock that is needed. ;
18+
; ;
19+
; rdar://13273675. (With extra test cases to handle bitcast, phi, and select. ;
20+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21+
22+
define void @bitcasttest(i8* %storage, void (...)* %block) {
23+
; CHECK: define void @bitcasttest
24+
entry:
25+
%t1 = bitcast void (...)* %block to i8*
26+
; CHECK-NOT: tail call i8* @objc_retain
27+
%t2 = tail call i8* @objc_retain(i8* %t1)
28+
; CHECK: tail call i8* @objc_retainBlock
29+
%t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
30+
%t4 = bitcast i8* %storage to void (...)**
31+
%t5 = bitcast i8* %t3 to void (...)*
32+
store void (...)* %t5, void (...)** %t4, align 8
33+
; CHECK-NOT: call void @objc_release
34+
call void @objc_release(i8* %t1)
35+
ret void
36+
}
37+
38+
define void @geptest(void (...)** %storage_array, void (...)* %block) {
39+
; CHECK: define void @geptest
40+
entry:
41+
%t1 = bitcast void (...)* %block to i8*
42+
; CHECK-NOT: tail call i8* @objc_retain
43+
%t2 = tail call i8* @objc_retain(i8* %t1)
44+
; CHECK: tail call i8* @objc_retainBlock
45+
%t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
46+
%t4 = bitcast i8* %t3 to void (...)*
47+
48+
%storage = getelementptr inbounds void (...)** %storage_array, i64 0
49+
50+
store void (...)* %t4, void (...)** %storage, align 8
51+
; CHECK-NOT: call void @objc_release
52+
call void @objc_release(i8* %t1)
53+
ret void
54+
}
55+
56+
define void @selecttest(void (...)** %store1, void (...)** %store2,
57+
void (...)* %block) {
58+
; CHECK: define void @selecttest
59+
entry:
60+
%t1 = bitcast void (...)* %block to i8*
61+
; CHECK-NOT: tail call i8* @objc_retain
62+
%t2 = tail call i8* @objc_retain(i8* %t1)
63+
; CHECK: tail call i8* @objc_retainBlock
64+
%t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
65+
%t4 = bitcast i8* %t3 to void (...)*
66+
%store = select i1 undef, void (...)** %store1, void (...)** %store2
67+
store void (...)* %t4, void (...)** %store, align 8
68+
; CHECK-NOT: call void @objc_release
69+
call void @objc_release(i8* %t1)
70+
ret void
71+
}
72+
73+
define void @phinodetest(void (...)** %storage1,
74+
void (...)** %storage2,
75+
void (...)* %block) {
76+
; CHECK: define void @phinodetest
77+
entry:
78+
%t1 = bitcast void (...)* %block to i8*
79+
; CHECK-NOT: tail call i8* @objc_retain
80+
%t2 = tail call i8* @objc_retain(i8* %t1)
81+
; CHECK: tail call i8* @objc_retainBlock
82+
%t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
83+
%t4 = bitcast i8* %t3 to void (...)*
84+
br i1 undef, label %store1_set, label %store2_set
85+
86+
store1_set:
87+
br label %end
88+
89+
store2_set:
90+
br label %end
91+
92+
end:
93+
%storage = phi void (...)** [ %storage1, %store1_set ], [ %storage2, %store2_set]
94+
store void (...)* %t4, void (...)** %storage, align 8
95+
; CHECK-NOT: call void @objc_release
96+
call void @objc_release(i8* %t1)
97+
ret void
98+
}
99+
100+
!0 = metadata !{}

0 commit comments

Comments
 (0)