[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / DeadStoreElimination / trivial-dse-calls.ll
blobd581782884442015d621a6c064e39f5a92b59ba1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -dse -S < %s | FileCheck %s
4 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
5 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
7 declare void @unknown()
8 declare void @f(i8*)
9 declare void @f2(i8*, i8*)
10 declare i8* @f3(i8*, i8*)
12 ; Basic case for DSEing a trivially dead writing call
13 define void @test_dead() {
14 ; CHECK-LABEL: @test_dead(
15 ; CHECK-NEXT:    ret void
17   %a = alloca i32, align 4
18   %bitcast = bitcast i32* %a to i8*
19   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
20   ret void
23 ; Add in canonical lifetime intrinsics
24 define void @test_lifetime() {
25 ; CHECK-LABEL: @test_lifetime(
26 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
27 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
28 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[BITCAST]])
29 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[BITCAST]])
30 ; CHECK-NEXT:    ret void
32   %a = alloca i32, align 4
33   %bitcast = bitcast i32* %a to i8*
34   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
35   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
36   call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
37   ret void
40 ; Add some unknown calls just to point out that this is use based, not
41 ; instruction order sensitive
42 define void @test_lifetime2() {
43 ; CHECK-LABEL: @test_lifetime2(
44 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
45 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
46 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* [[BITCAST]])
47 ; CHECK-NEXT:    call void @unknown()
48 ; CHECK-NEXT:    call void @unknown()
49 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[BITCAST]])
50 ; CHECK-NEXT:    ret void
52   %a = alloca i32, align 4
53   %bitcast = bitcast i32* %a to i8*
54   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
55   call void @unknown()
56   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
57   call void @unknown()
58   call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
59   ret void
62 ; As long as the result is unused, we can even remove reads of the alloca
63 ; itself since the write will be dropped.
64 define void @test_dead_readwrite() {
65 ; CHECK-LABEL: @test_dead_readwrite(
66 ; CHECK-NEXT:    ret void
68   %a = alloca i32, align 4
69   %bitcast = bitcast i32* %a to i8*
70   call void @f(i8* nocapture %bitcast) argmemonly nounwind willreturn
71   ret void
74 define i32 @test_neg_read_after() {
75 ; CHECK-LABEL: @test_neg_read_after(
76 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
77 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
78 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1:[0-9]+]]
79 ; CHECK-NEXT:    [[RES:%.*]] = load i32, i32* [[A]], align 4
80 ; CHECK-NEXT:    ret i32 [[RES]]
82   %a = alloca i32, align 4
83   %bitcast = bitcast i32* %a to i8*
84   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
85   %res = load i32, i32* %a
86   ret i32 %res
90 define void @test_neg_infinite_loop() {
91 ; CHECK-LABEL: @test_neg_infinite_loop(
92 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
93 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
94 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR2:[0-9]+]]
95 ; CHECK-NEXT:    ret void
97   %a = alloca i32, align 4
98   %bitcast = bitcast i32* %a to i8*
99   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind
100   ret void
103 define void @test_neg_throw() {
104 ; CHECK-LABEL: @test_neg_throw(
105 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
106 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
107 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR3:[0-9]+]]
108 ; CHECK-NEXT:    ret void
110   %a = alloca i32, align 4
111   %bitcast = bitcast i32* %a to i8*
112   call void @f(i8* writeonly nocapture %bitcast) argmemonly willreturn
113   ret void
116 define void @test_neg_extra_write() {
117 ; CHECK-LABEL: @test_neg_extra_write(
118 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
119 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
120 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR4:[0-9]+]]
121 ; CHECK-NEXT:    ret void
123   %a = alloca i32, align 4
124   %bitcast = bitcast i32* %a to i8*
125   call void @f(i8* writeonly nocapture %bitcast) nounwind willreturn
126   ret void
129 ; In this case, we can't remove a1 because we need to preserve the write to
130 ; a2, and if we leave the call around, we need memory to pass to the first arg.
131 define void @test_neg_unmodeled_write() {
132 ; CHECK-LABEL: @test_neg_unmodeled_write(
133 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
134 ; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
135 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
136 ; CHECK-NEXT:    [[BITCAST2:%.*]] = bitcast i32* [[A2]] to i8*
137 ; CHECK-NEXT:    call void @f2(i8* nocapture writeonly [[BITCAST]], i8* [[BITCAST2]]) #[[ATTR1]]
138 ; CHECK-NEXT:    ret void
140   %a = alloca i32, align 4
141   %a2 = alloca i32, align 4
142   %bitcast = bitcast i32* %a to i8*
143   %bitcast2 = bitcast i32* %a2 to i8*
144   call void @f2(i8* nocapture writeonly %bitcast, i8* %bitcast2) argmemonly nounwind willreturn
145   ret void
148 define i32 @test_neg_captured_by_call() {
149 ; CHECK-LABEL: @test_neg_captured_by_call(
150 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
151 ; CHECK-NEXT:    [[A2:%.*]] = alloca i8*, align 4
152 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
153 ; CHECK-NEXT:    [[BITCAST2:%.*]] = bitcast i8** [[A2]] to i8*
154 ; CHECK-NEXT:    call void @f2(i8* writeonly [[BITCAST]], i8* [[BITCAST2]]) #[[ATTR1]]
155 ; CHECK-NEXT:    [[A_COPY_CAST:%.*]] = load i8*, i8** [[A2]], align 8
156 ; CHECK-NEXT:    [[A_COPY:%.*]] = bitcast i8* [[A_COPY_CAST]] to i32*
157 ; CHECK-NEXT:    [[RES:%.*]] = load i32, i32* [[A_COPY]], align 4
158 ; CHECK-NEXT:    ret i32 [[RES]]
160   %a = alloca i32, align 4
161   %a2 = alloca i8*, align 4
162   %bitcast = bitcast i32* %a to i8*
163   %bitcast2 = bitcast i8** %a2 to i8*
164   call void @f2(i8* writeonly %bitcast, i8* %bitcast2) argmemonly nounwind willreturn
165   %a_copy_cast = load i8*, i8** %a2
166   %a_copy = bitcast i8* %a_copy_cast to i32*
167   %res = load i32, i32* %a_copy
168   ret i32 %res
171 define i32 @test_neg_captured_before() {
172 ; CHECK-LABEL: @test_neg_captured_before(
173 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
174 ; CHECK-NEXT:    [[A2:%.*]] = alloca i8*, align 4
175 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
176 ; CHECK-NEXT:    [[BITCAST2:%.*]] = bitcast i8** [[A2]] to i8*
177 ; CHECK-NEXT:    store i8* [[BITCAST]], i8** [[A2]], align 8
178 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]]
179 ; CHECK-NEXT:    [[A_COPY_CAST:%.*]] = load i8*, i8** [[A2]], align 8
180 ; CHECK-NEXT:    [[A_COPY:%.*]] = bitcast i8* [[A_COPY_CAST]] to i32*
181 ; CHECK-NEXT:    [[RES:%.*]] = load i32, i32* [[A_COPY]], align 4
182 ; CHECK-NEXT:    ret i32 [[RES]]
184   %a = alloca i32, align 4
185   %a2 = alloca i8*, align 4
186   %bitcast = bitcast i32* %a to i8*
187   %bitcast2 = bitcast i8** %a2 to i8*
188   store i8* %bitcast, i8** %a2
189   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
190   %a_copy_cast = load i8*, i8** %a2
191   %a_copy = bitcast i8* %a_copy_cast to i32*
192   %res = load i32, i32* %a_copy
193   ret i32 %res
196 ; Callee might be dead, but op bundle has unknown semantics and thus isn't.
197 define void @test_new_op_bundle() {
198 ; CHECK-LABEL: @test_new_op_bundle(
199 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
200 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
201 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]] [ "unknown"(i8* [[BITCAST]]) ]
202 ; CHECK-NEXT:    ret void
204   %a = alloca i32, align 4
205   %bitcast = bitcast i32* %a to i8*
206   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn ["unknown" (i8* %bitcast)]
207   ret void
210 ; Show that reading from unrelated memory is okay
211 define void @test_unreleated_read() {
212 ; CHECK-LABEL: @test_unreleated_read(
213 ; CHECK-NEXT:    ret void
215   %a = alloca i32, align 4
216   %a2 = alloca i32, align 4
217   %bitcast = bitcast i32* %a to i8*
218   %bitcast2 = bitcast i32* %a2 to i8*
219   call void @f2(i8* nocapture writeonly %bitcast, i8* nocapture readonly %bitcast2) argmemonly nounwind willreturn
220   ret void
223 ; Removing a capture is also okay. The capture can only be in the return value
224 ; (which is unused) or written into the dead out parameter.
225 define void @test_unrelated_capture() {
226 ; CHECK-LABEL: @test_unrelated_capture(
227 ; CHECK-NEXT:    ret void
229   %a = alloca i32, align 4
230   %a2 = alloca i32, align 4
231   %bitcast = bitcast i32* %a to i8*
232   %bitcast2 = bitcast i32* %a2 to i8*
233   call i8* @f3(i8* nocapture writeonly %bitcast, i8* readonly %bitcast2) argmemonly nounwind willreturn
234   ret void
237 ; Cannot remove call, as %bitcast2 is captured via the return value.
238 define i8 @test_neg_unrelated_capture_used_via_return() {
239 ; CHECK-LABEL: @test_neg_unrelated_capture_used_via_return(
240 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
241 ; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
242 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
243 ; CHECK-NEXT:    [[BITCAST2:%.*]] = bitcast i32* [[A2]] to i8*
244 ; CHECK-NEXT:    [[CAPTURE:%.*]] = call i8* @f3(i8* nocapture writeonly [[BITCAST]], i8* readonly [[BITCAST2]]) #[[ATTR1]]
245 ; CHECK-NEXT:    [[V:%.*]] = load i8, i8* [[CAPTURE]], align 1
246 ; CHECK-NEXT:    ret i8 [[V]]
248   %a = alloca i32, align 4
249   %a2 = alloca i32, align 4
250   %bitcast = bitcast i32* %a to i8*
251   %bitcast2 = bitcast i32* %a2 to i8*
252   %capture = call i8* @f3(i8* nocapture writeonly %bitcast, i8* readonly %bitcast2) argmemonly nounwind willreturn
253   %v = load i8, i8* %capture
254   ret i8 %v
257 ; As long as the result is unused, we can even remove reads of the alloca
258 ; itself since the write will be dropped.
259 define void @test_self_read() {
260 ; CHECK-LABEL: @test_self_read(
261 ; CHECK-NEXT:    ret void
263   %a = alloca i32, align 4
264   %bitcast = bitcast i32* %a to i8*
265   call void @f2(i8* nocapture writeonly %bitcast, i8* nocapture readonly %bitcast) argmemonly nounwind willreturn
266   ret void
269 ; We can remove the call because while we don't know the size of the write done
270 ; by the call, we do know the following store writes to the entire contents of
271 ; the alloca.
272 define i32 @test_dse_overwrite() {
273 ; CHECK-LABEL: @test_dse_overwrite(
274 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
275 ; CHECK-NEXT:    store i32 0, i32* [[A]], align 4
276 ; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[A]], align 4
277 ; CHECK-NEXT:    ret i32 [[V]]
279   %a = alloca i32, align 4
280   %bitcast = bitcast i32* %a to i8*
281   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
282   store i32 0, i32* %a
283   %v = load i32, i32* %a
284   ret i32 %v
287 ; Negative case where we can read part of the value written by @f.
288 define i32 @test_neg_dse_partial_overwrite() {
289 ; CHECK-LABEL: @test_neg_dse_partial_overwrite(
290 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
291 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
292 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]]
293 ; CHECK-NEXT:    store i8 0, i8* [[BITCAST]], align 1
294 ; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[A]], align 4
295 ; CHECK-NEXT:    ret i32 [[V]]
297   %a = alloca i32, align 4
298   %bitcast = bitcast i32* %a to i8*
299   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
300   store i8 0, i8* %bitcast
301   %v = load i32, i32* %a
302   ret i32 %v
305 ; Negative case where we don't know the size of a, and thus can't use the
306 ; full overwrite reasoning
307 define i32 @test_neg_dse_unsized(i32* %a) {
308 ; CHECK-LABEL: @test_neg_dse_unsized(
309 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[A:%.*]] to i8*
310 ; CHECK-NEXT:    call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]]
311 ; CHECK-NEXT:    store i32 0, i32* [[A]], align 4
312 ; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[A]], align 4
313 ; CHECK-NEXT:    ret i32 [[V]]
315   %bitcast = bitcast i32* %a to i8*
316   call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
317   store i32 0, i32* %a
318   %v = load i32, i32* %a
319   ret i32 %v
322 @G = global i8 0
324 ; Same as test_dse_overwrite, but with a non-alloca object.
325 define void @test_dse_non_alloca() {
326 ; CHECK-LABEL: @test_dse_non_alloca(
327 ; CHECK-NEXT:    store i8 0, i8* @G, align 1
328 ; CHECK-NEXT:    ret void
330   call void @f(i8* writeonly nocapture @G) argmemonly nounwind willreturn
331   store i8 0, i8* @G
332   ret void