comparison clang/test/CodeGenObjC/arc-rv-attr.m @ 252:1f2b6ac9f198 llvm-original

LLVM16-1
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 18 Aug 2023 09:04:13 +0900
parents c4bab56944e8
children
comparison
equal deleted inserted replaced
237:c80f45b162ad 252:1f2b6ac9f198
1 // RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK 1 // RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
2 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK 2 // RUN: %clang_cc1 -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
3 3
4 @class A; 4 @class A;
5 5
6 A *makeA(void); 6 A *makeA(void);
7 7
8 void test_assign(void) { 8 void test_assign(void) {
9 __unsafe_unretained id x; 9 __unsafe_unretained id x;
10 x = makeA(); 10 x = makeA();
11 } 11 }
12 // CHECK-LABEL: define{{.*}} void @test_assign() 12 // CHECK-LABEL: define{{.*}} void @test_assign()
13 // CHECK: [[X:%.*]] = alloca i8* 13 // CHECK: [[X:%.*]] = alloca ptr
14 // CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 14 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
15 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 15 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
16 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 16 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
17 // CHECK-NEXT: store i8* [[T1]], i8** [[X]]
18 // CHECK-NEXT: bitcast
19 // CHECK-NEXT: lifetime.end 17 // CHECK-NEXT: lifetime.end
20 // CHECK-NEXT: ret void 18 // CHECK-NEXT: ret void
21 19
22 void test_assign_assign(void) { 20 void test_assign_assign(void) {
23 __unsafe_unretained id x, y; 21 __unsafe_unretained id x, y;
24 x = y = makeA(); 22 x = y = makeA();
25 } 23 }
26 // CHECK-LABEL: define{{.*}} void @test_assign_assign() 24 // CHECK-LABEL: define{{.*}} void @test_assign_assign()
27 // CHECK: [[X:%.*]] = alloca i8* 25 // CHECK: [[X:%.*]] = alloca ptr
28 // CHECK: [[Y:%.*]] = alloca i8* 26 // CHECK: [[Y:%.*]] = alloca ptr
29 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 27 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
30 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 28 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
31 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 29 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]]
32 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] 30 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
33 // CHECK-NEXT: store i8* [[T1]], i8** [[X]]
34 // CHECK-NEXT: bitcast
35 // CHECK-NEXT: lifetime.end 31 // CHECK-NEXT: lifetime.end
36 // CHECK-NEXT: bitcast
37 // CHECK-NEXT: lifetime.end 32 // CHECK-NEXT: lifetime.end
38 // CHECK-NEXT: ret void 33 // CHECK-NEXT: ret void
39 34
40 void test_strong_assign_assign(void) { 35 void test_strong_assign_assign(void) {
41 __strong id x; 36 __strong id x;
42 __unsafe_unretained id y; 37 __unsafe_unretained id y;
43 x = y = makeA(); 38 x = y = makeA();
44 } 39 }
45 // CHECK-LABEL: define{{.*}} void @test_strong_assign_assign() 40 // CHECK-LABEL: define{{.*}} void @test_strong_assign_assign()
46 // CHECK: [[X:%.*]] = alloca i8* 41 // CHECK: [[X:%.*]] = alloca ptr
47 // CHECK: [[Y:%.*]] = alloca i8* 42 // CHECK: [[Y:%.*]] = alloca ptr
48 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] 43 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
49 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 44 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
50 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 45 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]]
51 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] 46 // CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]]
52 // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] 47 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
53 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] 48 // CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]]
54 // CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]]
55 // CHECK-NEXT: bitcast
56 // CHECK-NEXT: lifetime.end 49 // CHECK-NEXT: lifetime.end
57 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] 50 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
58 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 51 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
59 // CHECK-NEXT: bitcast
60 // CHECK-NEXT: lifetime.end 52 // CHECK-NEXT: lifetime.end
61 // CHECK-NEXT: ret void 53 // CHECK-NEXT: ret void
62 54
63 void test_assign_strong_assign(void) { 55 void test_assign_strong_assign(void) {
64 __unsafe_unretained id x; 56 __unsafe_unretained id x;
65 __strong id y; 57 __strong id y;
66 x = y = makeA(); 58 x = y = makeA();
67 } 59 }
68 // CHECK-LABEL: define{{.*}} void @test_assign_strong_assign() 60 // CHECK-LABEL: define{{.*}} void @test_assign_strong_assign()
69 // CHECK: [[X:%.*]] = alloca i8* 61 // CHECK: [[X:%.*]] = alloca ptr
70 // CHECK: [[Y:%.*]] = alloca i8* 62 // CHECK: [[Y:%.*]] = alloca ptr
71 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] 63 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
72 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 64 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
73 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 65 // CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[Y]]
74 // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]] 66 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]]
75 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] 67 // CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]]
76 // CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]] 68 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
77 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] 69 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
78 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] 70 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
79 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
80 // CHECK-NEXT: bitcast
81 // CHECK-NEXT: lifetime.end 71 // CHECK-NEXT: lifetime.end
82 // CHECK-NEXT: bitcast
83 // CHECK-NEXT: lifetime.end 72 // CHECK-NEXT: lifetime.end
84 // CHECK-NEXT: ret void 73 // CHECK-NEXT: ret void
85 74
86 void test_init(void) { 75 void test_init(void) {
87 __unsafe_unretained id x = makeA(); 76 __unsafe_unretained id x = makeA();
88 } 77 }
89 // CHECK-LABEL: define{{.*}} void @test_init() 78 // CHECK-LABEL: define{{.*}} void @test_init()
90 // CHECK: [[X:%.*]] = alloca i8* 79 // CHECK: [[X:%.*]] = alloca ptr
91 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 80 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
92 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 81 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
93 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 82 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
94 // CHECK-NEXT: store i8* [[T1]], i8** [[X]]
95 // CHECK-NEXT: bitcast
96 // CHECK-NEXT: lifetime.end 83 // CHECK-NEXT: lifetime.end
97 // CHECK-NEXT: ret void 84 // CHECK-NEXT: ret void
98 85
99 void test_init_assignment(void) { 86 void test_init_assignment(void) {
100 __unsafe_unretained id x; 87 __unsafe_unretained id x;
101 __unsafe_unretained id y = x = makeA(); 88 __unsafe_unretained id y = x = makeA();
102 } 89 }
103 // CHECK-LABEL: define{{.*}} void @test_init_assignment() 90 // CHECK-LABEL: define{{.*}} void @test_init_assignment()
104 // CHECK: [[X:%.*]] = alloca i8* 91 // CHECK: [[X:%.*]] = alloca ptr
105 // CHECK: [[Y:%.*]] = alloca i8* 92 // CHECK: [[Y:%.*]] = alloca ptr
106 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 93 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
107 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 94 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
108 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 95 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
109 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] 96 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]]
110 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
111 // CHECK-NEXT: bitcast
112 // CHECK-NEXT: lifetime.end 97 // CHECK-NEXT: lifetime.end
113 // CHECK-NEXT: bitcast
114 // CHECK-NEXT: lifetime.end 98 // CHECK-NEXT: lifetime.end
115 // CHECK-NEXT: ret void 99 // CHECK-NEXT: ret void
116 100
117 void test_strong_init_assignment(void) { 101 void test_strong_init_assignment(void) {
118 __unsafe_unretained id x; 102 __unsafe_unretained id x;
119 __strong id y = x = makeA(); 103 __strong id y = x = makeA();
120 } 104 }
121 // CHECK-LABEL: define{{.*}} void @test_strong_init_assignment() 105 // CHECK-LABEL: define{{.*}} void @test_strong_init_assignment()
122 // CHECK: [[X:%.*]] = alloca i8* 106 // CHECK: [[X:%.*]] = alloca ptr
123 // CHECK: [[Y:%.*]] = alloca i8* 107 // CHECK: [[Y:%.*]] = alloca ptr
124 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] 108 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
125 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 109 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
126 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 110 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
127 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] 111 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]]
128 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] 112 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
129 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] 113 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
130 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
131 // CHECK-NEXT: bitcast
132 // CHECK-NEXT: lifetime.end 114 // CHECK-NEXT: lifetime.end
133 // CHECK-NEXT: bitcast
134 // CHECK-NEXT: lifetime.end 115 // CHECK-NEXT: lifetime.end
135 // CHECK-NEXT: ret void 116 // CHECK-NEXT: ret void
136 117
137 void test_init_strong_assignment(void) { 118 void test_init_strong_assignment(void) {
138 __strong id x; 119 __strong id x;
139 __unsafe_unretained id y = x = makeA(); 120 __unsafe_unretained id y = x = makeA();
140 } 121 }
141 // CHECK-LABEL: define{{.*}} void @test_init_strong_assignment() 122 // CHECK-LABEL: define{{.*}} void @test_init_strong_assignment()
142 // CHECK: [[X:%.*]] = alloca i8* 123 // CHECK: [[X:%.*]] = alloca ptr
143 // CHECK: [[Y:%.*]] = alloca i8* 124 // CHECK: [[Y:%.*]] = alloca ptr
144 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] 125 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
145 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 126 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
146 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 127 // CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]]
147 // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] 128 // CHECK-NEXT: store ptr [[T0]], ptr [[X]]
148 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] 129 // CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]])
149 // CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]]) 130 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]]
150 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
151 // CHECK-NEXT: bitcast
152 // CHECK-NEXT: lifetime.end 131 // CHECK-NEXT: lifetime.end
153 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] 132 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
154 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 133 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
155 // CHECK-NEXT: bitcast
156 // CHECK-NEXT: lifetime.end 134 // CHECK-NEXT: lifetime.end
157 // CHECK-NEXT: ret void 135 // CHECK-NEXT: ret void
158 136
159 void test_ignored(void) { 137 void test_ignored(void) {
160 makeA(); 138 makeA();
161 } 139 }
162 // CHECK-LABEL: define{{.*}} void @test_ignored() 140 // CHECK-LABEL: define{{.*}} void @test_ignored()
163 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 141 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
164 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 142 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
165 // CHECK-NEXT: ret void 143 // CHECK-NEXT: ret void
166 144
167 void test_cast_to_void(void) { 145 void test_cast_to_void(void) {
168 (void) makeA(); 146 (void) makeA();
169 } 147 }
170 // CHECK-LABEL: define{{.*}} void @test_cast_to_void() 148 // CHECK-LABEL: define{{.*}} void @test_cast_to_void()
171 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 149 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
172 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) 150 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
173 // CHECK-NEXT: ret void 151 // CHECK-NEXT: ret void
174 152
175 // This is always at the end of the module. 153 // This is always at the end of the module.
176 154