1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -basicaa -dse -S | FileCheck %s
3; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
4target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
5
6declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
7declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
8declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
9declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
10declare void @llvm.init.trampoline(i8*, i8*, i8*)
11
12define void @test1(i32* %Q, i32* %P) {
13; CHECK-LABEL: @test1(
14; CHECK-NEXT:    store i32 0, i32* [[P:%.*]]
15; CHECK-NEXT:    ret void
16;
17  %DEAD = load i32, i32* %Q
18  store i32 %DEAD, i32* %P
19  store i32 0, i32* %P
20  ret void
21}
22
23; PR8576 - Should delete store of 10 even though p/q are may aliases.
24define void @test2(i32 *%p, i32 *%q) {
25; CHECK-LABEL: @test2(
26; CHECK-NEXT:    store i32 20, i32* [[Q:%.*]], align 4
27; CHECK-NEXT:    store i32 30, i32* [[P:%.*]], align 4
28; CHECK-NEXT:    ret void
29;
30  store i32 10, i32* %p, align 4
31  store i32 20, i32* %q, align 4
32  store i32 30, i32* %p, align 4
33  ret void
34}
35
36
37; PR8677
38@g = global i32 1
39
40define i32 @test3(i32* %g_addr) nounwind {
41; CHECK-LABEL: @test3(
42; CHECK-NEXT:    [[G_VALUE:%.*]] = load i32, i32* [[G_ADDR:%.*]], align 4
43; CHECK-NEXT:    store i32 -1, i32* @g, align 4
44; CHECK-NEXT:    store i32 [[G_VALUE]], i32* [[G_ADDR]], align 4
45; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* @g, align 4
46; CHECK-NEXT:    ret i32 [[TMP3]]
47;
48  %g_value = load i32, i32* %g_addr, align 4
49  store i32 -1, i32* @g, align 4
50  store i32 %g_value, i32* %g_addr, align 4
51  %tmp3 = load i32, i32* @g, align 4
52  ret i32 %tmp3
53}
54
55
56define void @test4(i32* %Q) {
57; CHECK-LABEL: @test4(
58; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[Q:%.*]]
59; CHECK-NEXT:    store volatile i32 [[A]], i32* [[Q]]
60; CHECK-NEXT:    ret void
61;
62  %a = load i32, i32* %Q
63  store volatile i32 %a, i32* %Q
64  ret void
65}
66
67define void @test5(i32* %Q) {
68; CHECK-LABEL: @test5(
69; CHECK-NEXT:    [[A:%.*]] = load volatile i32, i32* [[Q:%.*]]
70; CHECK-NEXT:    ret void
71;
72  %a = load volatile i32, i32* %Q
73  store i32 %a, i32* %Q
74  ret void
75}
76
77; Should delete store of 10 even though memset is a may-store to P (P and Q may
78; alias).
79define void @test6(i32 *%p, i8 *%q) {
80; CHECK-LABEL: @test6(
81; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[Q:%.*]], i8 42, i64 900, i1 false)
82; CHECK-NEXT:    store i32 30, i32* [[P:%.*]], align 4
83; CHECK-NEXT:    ret void
84;
85  store i32 10, i32* %p, align 4       ;; dead.
86  call void @llvm.memset.p0i8.i64(i8* %q, i8 42, i64 900, i1 false)
87  store i32 30, i32* %p, align 4
88  ret void
89}
90
91; Should delete store of 10 even though memset is a may-store to P (P and Q may
92; alias).
93define void @test6_atomic(i32* align 4 %p, i8* align 4 %q) {
94; CHECK-LABEL: @test6_atomic(
95; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[Q:%.*]], i8 42, i64 900, i32 4)
96; CHECK-NEXT:    store atomic i32 30, i32* [[P:%.*]] unordered, align 4
97; CHECK-NEXT:    ret void
98;
99  store atomic i32 10, i32* %p unordered, align 4       ;; dead.
100  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %q, i8 42, i64 900, i32 4)
101  store atomic i32 30, i32* %p unordered, align 4
102  ret void
103}
104
105; Should delete store of 10 even though memcpy is a may-store to P (P and Q may
106; alias).
107define void @test7(i32 *%p, i8 *%q, i8* noalias %r) {
108; CHECK-LABEL: @test7(
109; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[Q:%.*]], i8* [[R:%.*]], i64 900, i1 false)
110; CHECK-NEXT:    store i32 30, i32* [[P:%.*]], align 4
111; CHECK-NEXT:    ret void
112;
113  store i32 10, i32* %p, align 4       ;; dead.
114  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %q, i8* %r, i64 900, i1 false)
115  store i32 30, i32* %p, align 4
116  ret void
117}
118
119; Should delete store of 10 even though memcpy is a may-store to P (P and Q may
120; alias).
121define void @test7_atomic(i32* align 4 %p, i8* align 4 %q, i8* noalias align 4 %r) {
122; CHECK-LABEL: @test7_atomic(
123; CHECK-NEXT:    call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 4 [[Q:%.*]], i8* align 4 [[R:%.*]], i64 900, i32 4)
124; CHECK-NEXT:    store atomic i32 30, i32* [[P:%.*]] unordered, align 4
125; CHECK-NEXT:    ret void
126;
127  store atomic i32 10, i32* %p unordered, align 4       ;; dead.
128  call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 4 %q, i8* align 4 %r, i64 900, i32 4)
129  store atomic i32 30, i32* %p unordered, align 4
130  ret void
131}
132
133; Do not delete stores that are only partially killed.
134define i32 @test8() {
135; CHECK-LABEL: @test8(
136; CHECK-NEXT:    [[V:%.*]] = alloca i32
137; CHECK-NEXT:    store i32 1234567, i32* [[V]]
138; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[V]]
139; CHECK-NEXT:    ret i32 [[X]]
140;
141  %V = alloca i32
142  store i32 1234567, i32* %V
143  %V2 = bitcast i32* %V to i8*
144  store i8 0, i8* %V2
145  %X = load i32, i32* %V
146  ret i32 %X
147
148}
149
150
151; Test for byval handling.
152%struct.x = type { i32, i32, i32, i32 }
153define void @test9(%struct.x* byval  %a) nounwind  {
154; CHECK-LABEL: @test9(
155; CHECK-NEXT:    ret void
156;
157  %tmp2 = getelementptr %struct.x, %struct.x* %a, i32 0, i32 0
158  store i32 1, i32* %tmp2, align 4
159  ret void
160}
161
162; Test for inalloca handling.
163define void @test9_2(%struct.x* inalloca  %a) nounwind  {
164; CHECK-LABEL: @test9_2(
165; CHECK-NEXT:    ret void
166;
167  %tmp2 = getelementptr %struct.x, %struct.x* %a, i32 0, i32 0
168  store i32 1, i32* %tmp2, align 4
169  ret void
170}
171
172; va_arg has fuzzy dependence, the store shouldn't be zapped.
173define double @test10(i8* %X) {
174; CHECK-LABEL: @test10(
175; CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i8*
176; CHECK-NEXT:    store i8* [[X:%.*]], i8** [[X_ADDR]]
177; CHECK-NEXT:    [[TMP_0:%.*]] = va_arg i8** [[X_ADDR]], double
178; CHECK-NEXT:    ret double [[TMP_0]]
179;
180  %X_addr = alloca i8*
181  store i8* %X, i8** %X_addr
182  %tmp.0 = va_arg i8** %X_addr, double
183  ret double %tmp.0
184}
185
186
187; DSE should delete the dead trampoline.
188declare void @test11f()
189define void @test11() {
190; CHECK-LABEL: @test11(
191; CHECK-NEXT:    ret void
192;
193  %storage = alloca [10 x i8], align 16		; <[10 x i8]*> [#uses=1]
194  %cast = getelementptr [10 x i8], [10 x i8]* %storage, i32 0, i32 0		; <i8*> [#uses=1]
195  call void @llvm.init.trampoline( i8* %cast, i8* bitcast (void ()* @test11f to i8*), i8* null )		; <i8*> [#uses=1]
196  ret void
197}
198
199
200; PR2599 - load -> store to same address.
201define void @test12({ i32, i32 }* %x) nounwind  {
202; CHECK-LABEL: @test12(
203; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[X:%.*]], i32 0, i32 1
204; CHECK-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
205; CHECK-NEXT:    [[TMP17:%.*]] = sub i32 0, [[TMP8]]
206; CHECK-NEXT:    store i32 [[TMP17]], i32* [[TMP7]], align 4
207; CHECK-NEXT:    ret void
208;
209  %tmp4 = getelementptr { i32, i32 }, { i32, i32 }* %x, i32 0, i32 0
210  %tmp5 = load i32, i32* %tmp4, align 4
211  %tmp7 = getelementptr { i32, i32 }, { i32, i32 }* %x, i32 0, i32 1
212  %tmp8 = load i32, i32* %tmp7, align 4
213  %tmp17 = sub i32 0, %tmp8
214  store i32 %tmp5, i32* %tmp4, align 4
215  store i32 %tmp17, i32* %tmp7, align 4
216  ret void
217}
218
219
220; %P doesn't escape, the DEAD instructions should be removed.
221declare void @test13f()
222define i32* @test13() {
223; CHECK-LABEL: @test13(
224; CHECK-NEXT:    [[PTR:%.*]] = tail call i8* @malloc(i32 4)
225; CHECK-NEXT:    [[P:%.*]] = bitcast i8* [[PTR]] to i32*
226; CHECK-NEXT:    call void @test13f()
227; CHECK-NEXT:    store i32 0, i32* [[P]]
228; CHECK-NEXT:    ret i32* [[P]]
229;
230  %ptr = tail call i8* @malloc(i32 4)
231  %P = bitcast i8* %ptr to i32*
232  %DEAD = load i32, i32* %P
233  %DEAD2 = add i32 %DEAD, 1
234  store i32 %DEAD2, i32* %P
235  call void @test13f( )
236  store i32 0, i32* %P
237  ret i32* %P
238}
239
240define i32 addrspace(1)* @test13_addrspacecast() {
241; CHECK-LABEL: @test13_addrspacecast(
242; CHECK-NEXT:    [[P:%.*]] = tail call i8* @malloc(i32 4)
243; CHECK-NEXT:    [[P_BC:%.*]] = bitcast i8* [[P]] to i32*
244; CHECK-NEXT:    [[P:%.*]] = addrspacecast i32* [[P_BC]] to i32 addrspace(1)*
245; CHECK-NEXT:    call void @test13f()
246; CHECK-NEXT:    store i32 0, i32 addrspace(1)* [[P]]
247; CHECK-NEXT:    ret i32 addrspace(1)* [[P]]
248;
249  %p = tail call i8* @malloc(i32 4)
250  %p.bc = bitcast i8* %p to i32*
251  %P = addrspacecast i32* %p.bc to i32 addrspace(1)*
252  %DEAD = load i32, i32 addrspace(1)* %P
253  %DEAD2 = add i32 %DEAD, 1
254  store i32 %DEAD2, i32 addrspace(1)* %P
255  call void @test13f( )
256  store i32 0, i32 addrspace(1)* %P
257  ret i32 addrspace(1)* %P
258}
259
260declare noalias i8* @malloc(i32)
261declare noalias i8* @calloc(i32, i32)
262declare noalias i8* @aligned_alloc(i32, i32)
263declare void @free(i8*)
264
265
266define void @test14(i32* %Q) {
267; CHECK-LABEL: @test14(
268; CHECK-NEXT:    ret void
269;
270  %P = alloca i32
271  %DEAD = load i32, i32* %Q
272  store i32 %DEAD, i32* %P
273  ret void
274
275}
276
277; Dead store on an aligned_alloc: should know that %M doesn't alias with %A.
278define i32 @test14a(i8* %M, i8 %value) {
279; CHECK-LABEL: @test14a(
280; CHECK-NOT: store
281; CHECK:     ret i32 0
282;
283  %A = tail call i8* @aligned_alloc(i32 32, i32 1024)
284  store i8 %value, i8* %A
285  tail call void @free(i8* %A)
286  ret i32 0
287}
288
289; PR8701
290
291;; Fully dead overwrite of memcpy.
292define void @test15(i8* %P, i8* %Q) nounwind ssp {
293; CHECK-LABEL: @test15(
294; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
295; CHECK-NEXT:    ret void
296;
297  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
298  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
299  ret void
300}
301
302;; Fully dead overwrite of memcpy.
303define void @test15_atomic(i8* %P, i8* %Q) nounwind ssp {
304; CHECK-LABEL: @test15_atomic(
305; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
306; CHECK-NEXT:    ret void
307;
308  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
309  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
310  ret void
311}
312
313;; Fully dead overwrite of memcpy.
314define void @test15_atomic_weaker(i8* %P, i8* %Q) nounwind ssp {
315; CHECK-LABEL: @test15_atomic_weaker(
316; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
317; CHECK-NEXT:    ret void
318;
319  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
320  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
321  ret void
322}
323
324;; Fully dead overwrite of memcpy.
325define void @test15_atomic_weaker_2(i8* %P, i8* %Q) nounwind ssp {
326; CHECK-LABEL: @test15_atomic_weaker_2(
327; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
328; CHECK-NEXT:    ret void
329;
330  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
331  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
332  ret void
333}
334
335;; Full overwrite of smaller memcpy.
336define void @test16(i8* %P, i8* %Q) nounwind ssp {
337; CHECK-LABEL: @test16(
338; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
339; CHECK-NEXT:    ret void
340;
341  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
342  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
343  ret void
344}
345
346;; Full overwrite of smaller memcpy.
347define void @test16_atomic(i8* %P, i8* %Q) nounwind ssp {
348; CHECK-LABEL: @test16_atomic(
349; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
350; CHECK-NEXT:    ret void
351;
352  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i32 1)
353  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
354  ret void
355}
356
357;; Full overwrite of smaller memory where overwrite has stronger atomicity
358define void @test16_atomic_weaker(i8* %P, i8* %Q) nounwind ssp {
359; CHECK-LABEL: @test16_atomic_weaker(
360; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
361; CHECK-NEXT:    ret void
362;
363  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i1 false)
364  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
365  ret void
366}
367
368;; Full overwrite of smaller memory where overwrite has weaker atomicity.
369define void @test16_atomic_weaker_2(i8* %P, i8* %Q) nounwind ssp {
370; CHECK-LABEL: @test16_atomic_weaker_2(
371; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
372; CHECK-NEXT:    ret void
373;
374  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i32 1)
375  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
376  ret void
377}
378
379;; Overwrite of memset by memcpy.
380define void @test17(i8* %P, i8* noalias %Q) nounwind ssp {
381; CHECK-LABEL: @test17(
382; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
383; CHECK-NEXT:    ret void
384;
385  tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
386  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
387  ret void
388}
389
390;; Overwrite of memset by memcpy.
391define void @test17_atomic(i8* %P, i8* noalias %Q) nounwind ssp {
392; CHECK-LABEL: @test17_atomic(
393; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
394; CHECK-NEXT:    ret void
395;
396  tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
397  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
398  ret void
399}
400
401;; Overwrite of memset by memcpy. Overwrite is stronger atomicity. We can
402;; remove the memset.
403define void @test17_atomic_weaker(i8* %P, i8* noalias %Q) nounwind ssp {
404; CHECK-LABEL: @test17_atomic_weaker(
405; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
406; CHECK-NEXT:    ret void
407;
408  tail call void @llvm.memset.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i1 false)
409  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
410  ret void
411}
412
413;; Overwrite of memset by memcpy. Overwrite is weaker atomicity. We can remove
414;; the memset.
415define void @test17_atomic_weaker_2(i8* %P, i8* noalias %Q) nounwind ssp {
416; CHECK-LABEL: @test17_atomic_weaker_2(
417; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
418; CHECK-NEXT:    ret void
419;
420  tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
421  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
422  ret void
423}
424
425; Should not delete the volatile memset.
426define void @test17v(i8* %P, i8* %Q) nounwind ssp {
427; CHECK-LABEL: @test17v(
428; CHECK-NEXT:    tail call void @llvm.memset.p0i8.i64(i8* [[P:%.*]], i8 42, i64 8, i1 true)
429; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[Q:%.*]], i64 12, i1 false)
430; CHECK-NEXT:    ret void
431;
432  tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 true)
433  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
434  ret void
435}
436
437; PR8728
438; Do not delete instruction where possible situation is:
439; A = B
440; A = A
441;
442; NB! See PR11763 - currently LLVM allows memcpy's source and destination to be
443; equal (but not inequal and overlapping).
444define void @test18(i8* %P, i8* %Q, i8* %R) nounwind ssp {
445; CHECK-LABEL: @test18(
446; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
447; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[R:%.*]], i64 12, i1 false)
448; CHECK-NEXT:    ret void
449;
450  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
451  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
452  ret void
453}
454
455define void @test18_atomic(i8* %P, i8* %Q, i8* %R) nounwind ssp {
456; CHECK-LABEL: @test18_atomic(
457; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
458; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
459; CHECK-NEXT:    ret void
460;
461  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
462  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
463  ret void
464}
465
466
467; The store here is not dead because the byval call reads it.
468declare void @test19f({i32}* byval align 4 %P)
469
470define void @test19({i32} * nocapture byval align 4 %arg5) nounwind ssp {
471; CHECK-LABEL: @test19(
472; CHECK-NEXT:  bb:
473; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds { i32 }, { i32 }* [[ARG5:%.*]], i32 0, i32 0
474; CHECK-NEXT:    store i32 912, i32* [[TMP7]]
475; CHECK-NEXT:    call void @test19f({ i32 }* byval align 4 [[ARG5]])
476; CHECK-NEXT:    ret void
477;
478bb:
479  %tmp7 = getelementptr inbounds {i32}, {i32}* %arg5, i32 0, i32 0
480  store i32 912, i32* %tmp7
481  call void @test19f({i32}* byval align 4 %arg5)
482  ret void
483
484}
485
486define void @test20() {
487; CHECK-LABEL: @test20(
488; CHECK-NEXT:    ret void
489;
490  %m = call i8* @malloc(i32 24)
491  store i8 0, i8* %m
492  ret void
493}
494
495define void @test21() {
496; CHECK-LABEL: @test21(
497; CHECK-NEXT:    ret void
498;
499  %m = call i8* @calloc(i32 9, i32 7)
500  store i8 0, i8* %m
501  ret void
502}
503
504define void @test22(i1 %i, i32 %k, i32 %m) nounwind {
505; CHECK-LABEL: @test22(
506; CHECK-NEXT:    ret void
507;
508  %k.addr = alloca i32
509  %m.addr = alloca i32
510  %k.addr.m.addr = select i1 %i, i32* %k.addr, i32* %m.addr
511  store i32 0, i32* %k.addr.m.addr, align 4
512  ret void
513}
514
515; PR13547
516declare noalias i8* @strdup(i8* nocapture) nounwind
517define noalias i8* @test23() nounwind uwtable ssp {
518; CHECK-LABEL: @test23(
519; CHECK-NEXT:    [[X:%.*]] = alloca [2 x i8], align 1
520; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0
521; CHECK-NEXT:    store i8 97, i8* [[ARRAYIDX]], align 1
522; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1
523; CHECK-NEXT:    store i8 0, i8* [[ARRAYIDX1]], align 1
524; CHECK-NEXT:    [[CALL:%.*]] = call i8* @strdup(i8* [[ARRAYIDX]]) #3
525; CHECK-NEXT:    ret i8* [[CALL]]
526;
527  %x = alloca [2 x i8], align 1
528  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 0
529  store i8 97, i8* %arrayidx, align 1
530  %arrayidx1 = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 1
531  store i8 0, i8* %arrayidx1, align 1
532  %call = call i8* @strdup(i8* %arrayidx) nounwind
533  ret i8* %call
534}
535
536; Make sure same sized store to later element is deleted
537define void @test24([2 x i32]* %a, i32 %b, i32 %c) nounwind {
538; CHECK-LABEL: @test24(
539; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A:%.*]], i64 0, i64 0
540; CHECK-NEXT:    store i32 [[B:%.*]], i32* [[TMP1]], align 4
541; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A]], i64 0, i64 1
542; CHECK-NEXT:    store i32 [[C:%.*]], i32* [[TMP2]], align 4
543; CHECK-NEXT:    ret void
544;
545  %1 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 0, i64 0
546  store i32 0, i32* %1, align 4
547  %2 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 0, i64 1
548  store i32 0, i32* %2, align 4
549  %3 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 0, i64 0
550  store i32 %b, i32* %3, align 4
551  %4 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 0, i64 1
552  store i32 %c, i32* %4, align 4
553  ret void
554}
555
556; Check another case like PR13547 where strdup is not like malloc.
557define i8* @test25(i8* %p) nounwind {
558; CHECK-LABEL: @test25(
559; CHECK-NEXT:    [[P_4:%.*]] = getelementptr i8, i8* [[P:%.*]], i64 4
560; CHECK-NEXT:    [[TMP:%.*]] = load i8, i8* [[P_4]], align 1
561; CHECK-NEXT:    store i8 0, i8* [[P_4]], align 1
562; CHECK-NEXT:    [[Q:%.*]] = call i8* @strdup(i8* [[P]]) #6
563; CHECK-NEXT:    store i8 [[TMP]], i8* [[P_4]], align 1
564; CHECK-NEXT:    ret i8* [[Q]]
565;
566  %p.4 = getelementptr i8, i8* %p, i64 4
567  %tmp = load i8, i8* %p.4, align 1
568  store i8 0, i8* %p.4, align 1
569  %q = call i8* @strdup(i8* %p) nounwind optsize
570  store i8 %tmp, i8* %p.4, align 1
571  ret i8* %q
572}
573
574; Remove redundant store if loaded value is in another block.
575define i32 @test26(i1 %c, i32* %p) {
576; CHECK-LABEL: @test26(
577; CHECK-NEXT:  entry:
578; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
579; CHECK:       bb1:
580; CHECK-NEXT:    br label [[BB3:%.*]]
581; CHECK:       bb2:
582; CHECK-NEXT:    br label [[BB3]]
583; CHECK:       bb3:
584; CHECK-NEXT:    ret i32 0
585;
586entry:
587  %v = load i32, i32* %p, align 4
588  br i1 %c, label %bb1, label %bb2
589bb1:
590  br label %bb3
591bb2:
592  store i32 %v, i32* %p, align 4
593  br label %bb3
594bb3:
595  ret i32 0
596}
597
598; Remove redundant store if loaded value is in another block.
599define i32 @test27(i1 %c, i32* %p) {
600; CHECK-LABEL: @test27(
601; CHECK-NEXT:  entry:
602; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
603; CHECK:       bb1:
604; CHECK-NEXT:    br label [[BB3:%.*]]
605; CHECK:       bb2:
606; CHECK-NEXT:    br label [[BB3]]
607; CHECK:       bb3:
608; CHECK-NEXT:    ret i32 0
609;
610entry:
611  %v = load i32, i32* %p, align 4
612  br i1 %c, label %bb1, label %bb2
613bb1:
614  br label %bb3
615bb2:
616  br label %bb3
617bb3:
618  store i32 %v, i32* %p, align 4
619  ret i32 0
620}
621
622; Don't remove redundant store because of may-aliased store.
623define i32 @test28(i1 %c, i32* %p, i32* %p2, i32 %i) {
624; CHECK-LABEL: @test28(
625; CHECK-NEXT:  entry:
626; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
627; CHECK-NEXT:    store i32 [[I:%.*]], i32* [[P2:%.*]], align 4
628; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
629; CHECK:       bb1:
630; CHECK-NEXT:    br label [[BB3:%.*]]
631; CHECK:       bb2:
632; CHECK-NEXT:    br label [[BB3]]
633; CHECK:       bb3:
634; CHECK-NEXT:    store i32 [[V]], i32* [[P]], align 4
635; CHECK-NEXT:    ret i32 0
636;
637entry:
638  %v = load i32, i32* %p, align 4
639
640  ; Might overwrite value at %p
641  store i32 %i, i32* %p2, align 4
642  br i1 %c, label %bb1, label %bb2
643bb1:
644  br label %bb3
645bb2:
646  br label %bb3
647bb3:
648  store i32 %v, i32* %p, align 4
649  ret i32 0
650}
651
652; Don't remove redundant store because of may-aliased store.
653define i32 @test29(i1 %c, i32* %p, i32* %p2, i32 %i) {
654; CHECK-LABEL: @test29(
655; CHECK-NEXT:  entry:
656; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
657; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
658; CHECK:       bb1:
659; CHECK-NEXT:    br label [[BB3:%.*]]
660; CHECK:       bb2:
661; CHECK-NEXT:    store i32 [[I:%.*]], i32* [[P2:%.*]], align 4
662; CHECK-NEXT:    br label [[BB3]]
663; CHECK:       bb3:
664; CHECK-NEXT:    store i32 [[V]], i32* [[P]], align 4
665; CHECK-NEXT:    ret i32 0
666;
667entry:
668  %v = load i32, i32* %p, align 4
669  br i1 %c, label %bb1, label %bb2
670bb1:
671  br label %bb3
672bb2:
673  ; Might overwrite value at %p
674  store i32 %i, i32* %p2, align 4
675  br label %bb3
676bb3:
677  store i32 %v, i32* %p, align 4
678  ret i32 0
679}
680
681declare void @unknown_func()
682
683; Don't remove redundant store because of unknown call.
684define i32 @test30(i1 %c, i32* %p, i32 %i) {
685; CHECK-LABEL: @test30(
686; CHECK-NEXT:  entry:
687; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
688; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
689; CHECK:       bb1:
690; CHECK-NEXT:    br label [[BB3:%.*]]
691; CHECK:       bb2:
692; CHECK-NEXT:    call void @unknown_func()
693; CHECK-NEXT:    br label [[BB3]]
694; CHECK:       bb3:
695; CHECK-NEXT:    store i32 [[V]], i32* [[P]], align 4
696; CHECK-NEXT:    ret i32 0
697;
698entry:
699  %v = load i32, i32* %p, align 4
700  br i1 %c, label %bb1, label %bb2
701bb1:
702  br label %bb3
703bb2:
704  ; Might overwrite value at %p
705  call void @unknown_func()
706  br label %bb3
707bb3:
708  store i32 %v, i32* %p, align 4
709  ret i32 0
710}
711
712; Remove redundant store if loaded value is in another block inside a loop.
713define i32 @test31(i1 %c, i32* %p, i32 %i) {
714; CHECK-LABEL: @test31(
715; CHECK-NEXT:  entry:
716; CHECK-NEXT:    br label [[BB1:%.*]]
717; CHECK:       bb1:
718; CHECK-NEXT:    br i1 undef, label [[BB1]], label [[BB2:%.*]]
719; CHECK:       bb2:
720; CHECK-NEXT:    ret i32 0
721;
722entry:
723  %v = load i32, i32* %p, align 4
724  br label %bb1
725bb1:
726  store i32 %v, i32* %p, align 4
727  br i1 undef, label %bb1, label %bb2
728bb2:
729  ret i32 0
730}
731
732; Don't remove redundant store in a loop with a may-alias store.
733define i32 @test32(i1 %c, i32* %p, i32 %i) {
734; CHECK-LABEL: @test32(
735; CHECK-NEXT:  entry:
736; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
737; CHECK-NEXT:    br label [[BB1:%.*]]
738; CHECK:       bb1:
739; CHECK-NEXT:    store i32 [[V]], i32* [[P]], align 4
740; CHECK-NEXT:    call void @unknown_func()
741; CHECK-NEXT:    br i1 undef, label [[BB1]], label [[BB2:%.*]]
742; CHECK:       bb2:
743; CHECK-NEXT:    ret i32 0
744;
745entry:
746  %v = load i32, i32* %p, align 4
747  br label %bb1
748bb1:
749  store i32 %v, i32* %p, align 4
750  ; Might read and overwrite value at %p
751  call void @unknown_func()
752  br i1 undef, label %bb1, label %bb2
753bb2:
754  ret i32 0
755}
756
757; Remove redundant store, which is in the lame loop as the load.
758define i32 @test33(i1 %c, i32* %p, i32 %i) {
759; CHECK-LABEL: @test33(
760; CHECK-NEXT:  entry:
761; CHECK-NEXT:    br label [[BB1:%.*]]
762; CHECK:       bb1:
763; CHECK-NEXT:    br label [[BB2:%.*]]
764; CHECK:       bb2:
765; CHECK-NEXT:    call void @unknown_func()
766; CHECK-NEXT:    br i1 undef, label [[BB1]], label [[BB3:%.*]]
767; CHECK:       bb3:
768; CHECK-NEXT:    ret i32 0
769;
770entry:
771  br label %bb1
772bb1:
773  %v = load i32, i32* %p, align 4
774  br label %bb2
775bb2:
776  store i32 %v, i32* %p, align 4
777  ; Might read and overwrite value at %p, but doesn't matter.
778  call void @unknown_func()
779  br i1 undef, label %bb1, label %bb3
780bb3:
781  ret i32 0
782}
783
784; Don't remove redundant store: unknown_func could unwind
785define void @test34(i32* noalias %p) {
786; CHECK-LABEL: @test34(
787; CHECK-NEXT:    store i32 1, i32* [[P:%.*]]
788; CHECK-NEXT:    call void @unknown_func()
789; CHECK-NEXT:    store i32 0, i32* [[P]]
790; CHECK-NEXT:    ret void
791;
792  store i32 1, i32* %p
793  call void @unknown_func()
794  store i32 0, i32* %p
795  ret void
796}
797
798; Remove redundant store even with an unwinding function in the same block
799define void @test35(i32* noalias %p) {
800; CHECK-LABEL: @test35(
801; CHECK-NEXT:    call void @unknown_func()
802; CHECK-NEXT:    store i32 0, i32* [[P:%.*]]
803; CHECK-NEXT:    ret void
804;
805  call void @unknown_func()
806  store i32 1, i32* %p
807  store i32 0, i32* %p
808  ret void
809}
810
811; We cannot optimize away the first memmove since %P could overlap with %Q.
812define void @test36(i8* %P, i8* %Q) {
813; CHECK-LABEL: @test36(
814; CHECK-NEXT:    tail call void @llvm.memmove.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
815; CHECK-NEXT:    tail call void @llvm.memmove.p0i8.p0i8.i64(i8* [[P]], i8* [[Q]], i64 12, i1 false)
816; CHECK-NEXT:    ret void
817;
818
819  tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
820  tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
821  ret void
822}
823
824define void @test36_atomic(i8* %P, i8* %Q) {
825; CHECK-LABEL: @test36_atomic(
826; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
827; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i32 1)
828; CHECK-NEXT:    ret void
829;
830
831  tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
832  tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
833  ret void
834}
835
836define void @test37(i8* %P, i8* %Q, i8* %R) {
837; CHECK-LABEL: @test37(
838; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
839; CHECK-NEXT:    tail call void @llvm.memmove.p0i8.p0i8.i64(i8* [[P]], i8* [[R:%.*]], i64 12, i1 false)
840; CHECK-NEXT:    ret void
841;
842
843  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
844  tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
845  ret void
846}
847
848define void @test37_atomic(i8* %P, i8* %Q, i8* %R) {
849; CHECK-LABEL: @test37_atomic(
850; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
851; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
852; CHECK-NEXT:    ret void
853;
854
855  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
856  tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
857  ret void
858}
859
860; Same caveat about memcpy as in @test18 applies here.
861define void @test38(i8* %P, i8* %Q, i8* %R) {
862; CHECK-LABEL: @test38(
863; CHECK-NEXT:    tail call void @llvm.memmove.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
864; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[R:%.*]], i64 12, i1 false)
865; CHECK-NEXT:    ret void
866;
867
868  tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
869  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
870  ret void
871}
872
873define void @test38_atomic(i8* %P, i8* %Q, i8* %R) {
874; CHECK-LABEL: @test38_atomic(
875; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
876; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
877; CHECK-NEXT:    ret void
878;
879
880  tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
881  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
882  ret void
883}
884
885define void @test39(i8* %P, i8* %Q, i8* %R) {
886; CHECK-LABEL: @test39(
887; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
888; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[R:%.*]], i64 8, i1 false)
889; CHECK-NEXT:    ret void
890;
891
892  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
893  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 8, i1 false)
894  ret void
895}
896
897define void @test39_atomic(i8* %P, i8* %Q, i8* %R) {
898; CHECK-LABEL: @test39_atomic(
899; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
900; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 8, i32 1)
901; CHECK-NEXT:    ret void
902;
903
904  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
905  tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 8, i32 1)
906  ret void
907}
908
909define i32 @test40() {
910; CHECK-LABEL: @test40(
911; CHECK-NEXT:  entry:
912; CHECK-NEXT:    [[M:%.*]] = call i8* @calloc(i32 9, i32 20)
913; CHECK-NEXT:    br label [[LOOP:%.*]]
914; CHECK:       loop:
915; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
916; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
917; CHECK-NEXT:    [[P_NEXT:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV_NEXT]]
918; CHECK-NEXT:    store i8 1, i8* [[P_NEXT]]
919; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV]]
920; CHECK-NEXT:    store i8 0, i8* [[P]]
921; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ugt i64 [[INDVARS_IV]], 15
922; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[RETURN:%.*]]
923; CHECK:       return:
924; CHECK-NEXT:    ret i32 0
925;
926entry:
927  %m = call i8* @calloc(i32 9, i32 20)
928  br label %loop
929loop:
930  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
931  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
932  %p.next = getelementptr inbounds i8, i8* %m, i64 %indvars.iv.next
933  store i8 1, i8* %p.next
934  %p = getelementptr inbounds i8, i8* %m, i64 %indvars.iv
935  store i8 0, i8* %p
936  %continue = icmp ugt i64 %indvars.iv, 15
937  br i1 %continue, label %loop, label %return
938return:
939  ret i32 0
940}
941
942define i32 @test41() {
943; CHECK-LABEL: @test41(
944; CHECK-NEXT:  entry:
945; CHECK-NEXT:    [[M:%.*]] = call i8* @calloc(i32 9, i32 20)
946; CHECK-NEXT:    br label [[LOOP:%.*]]
947; CHECK:       loop:
948; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[CONT:%.*]] ]
949; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
950; CHECK-NEXT:    [[P_NEXT:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV_NEXT]]
951; CHECK-NEXT:    store i8 1, i8* [[P_NEXT]]
952; CHECK-NEXT:    br label [[CONT]]
953; CHECK:       cont:
954; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV]]
955; CHECK-NEXT:    store i8 0, i8* [[P]]
956; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ugt i64 [[INDVARS_IV]], 15
957; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[RETURN:%.*]]
958; CHECK:       return:
959; CHECK-NEXT:    ret i32 0
960;
961entry:
962  %m = call i8* @calloc(i32 9, i32 20)
963  br label %loop
964loop:
965  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %cont ]
966  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
967  %p.next = getelementptr inbounds i8, i8* %m, i64 %indvars.iv.next
968  store i8 1, i8* %p.next
969  br label %cont
970
971cont:
972  %p = getelementptr inbounds i8, i8* %m, i64 %indvars.iv
973  store i8 0, i8* %p
974  %continue = icmp ugt i64 %indvars.iv, 15
975  br i1 %continue, label %loop, label %return
976
977return:
978  ret i32 0
979}
980
981; The store is redundant here, but currently we fail to eliminate it.
982; We are walking from the store up to the calloc and translate phis as
983; needed. In this case we fail to translate %p while going over the
984; backedge. Because of that we conservatively assume that zero initialized
985; memory is clobbered.
986define i32 @test42() {
987; CHECK-LABEL: @test42(
988; CHECK-NEXT:  entry:
989; CHECK-NEXT:    [[M:%.*]] = call i8* @calloc(i32 9, i32 20)
990; CHECK-NEXT:    br label [[LOOP:%.*]]
991; CHECK:       loop:
992; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[CONT:%.*]] ]
993; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
994; CHECK-NEXT:    br label [[CONT]]
995; CHECK:       cont:
996; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV]]
997; CHECK-NEXT:    store i8 0, i8* [[P]]
998; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ugt i64 [[INDVARS_IV]], 15
999; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[RETURN:%.*]]
1000; CHECK:       return:
1001; CHECK-NEXT:    ret i32 0
1002;
1003entry:
1004  %m = call i8* @calloc(i32 9, i32 20)
1005  br label %loop
1006loop:
1007  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %cont ]
1008  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
1009  br label %cont
1010
1011cont:
1012  %p = getelementptr inbounds i8, i8* %m, i64 %indvars.iv
1013  store i8 0, i8* %p
1014  %continue = icmp ugt i64 %indvars.iv, 15
1015  br i1 %continue, label %loop, label %return
1016
1017return:
1018  ret i32 0
1019}
1020
1021define i32 @test43() {
1022; CHECK-LABEL: @test43(
1023; CHECK-NEXT:  entry:
1024; CHECK-NEXT:    [[M:%.*]] = call i8* @calloc(i32 9, i32 20)
1025; CHECK-NEXT:    br label [[LOOP:%.*]]
1026; CHECK:       loop:
1027; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[CONT_2:%.*]] ]
1028; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1029; CHECK-NEXT:    [[P_NEXT:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV_NEXT]]
1030; CHECK-NEXT:    store i8 1, i8* [[P_NEXT]]
1031; CHECK-NEXT:    br label [[CONT:%.*]]
1032; CHECK:       cont:
1033; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV]]
1034; CHECK-NEXT:    store i8 0, i8* [[P]]
1035; CHECK-NEXT:    br label [[CONT_2]]
1036; CHECK:       cont.2:
1037; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ugt i64 [[INDVARS_IV]], 15
1038; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[RETURN:%.*]]
1039; CHECK:       return:
1040; CHECK-NEXT:    ret i32 0
1041;
1042entry:
1043  %m = call i8* @calloc(i32 9, i32 20)
1044  br label %loop
1045loop:
1046  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %cont.2 ]
1047  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
1048  %p.next = getelementptr inbounds i8, i8* %m, i64 %indvars.iv.next
1049  store i8 1, i8* %p.next
1050  br label %cont
1051
1052cont:
1053  %p = getelementptr inbounds i8, i8* %m, i64 %indvars.iv
1054  store i8 0, i8* %p
1055  br label %cont.2
1056
1057cont.2:
1058  %continue = icmp ugt i64 %indvars.iv, 15
1059  br i1 %continue, label %loop, label %return
1060
1061return:
1062  ret i32 0
1063}
1064
1065define i32 @test44() {
1066; CHECK-LABEL: @test44(
1067; CHECK-NEXT:  entry:
1068; CHECK-NEXT:    [[M:%.*]] = call i8* @calloc(i32 9, i32 20)
1069; CHECK-NEXT:    br label [[LOOP:%.*]]
1070; CHECK:       loop:
1071; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[CONT_2:%.*]] ]
1072; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1073; CHECK-NEXT:    [[P_NEXT:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV_NEXT]]
1074; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[INDVARS_IV]]
1075; CHECK-NEXT:    store i8 0, i8* [[P]]
1076; CHECK-NEXT:    br label [[CONT:%.*]]
1077; CHECK:       cont:
1078; CHECK-NEXT:    store i8 1, i8* [[P_NEXT]]
1079; CHECK-NEXT:    br label [[CONT_2]]
1080; CHECK:       cont.2:
1081; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ugt i64 [[INDVARS_IV]], 15
1082; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[RETURN:%.*]]
1083; CHECK:       return:
1084; CHECK-NEXT:    ret i32 0
1085;
1086entry:
1087  %m = call i8* @calloc(i32 9, i32 20)
1088  br label %loop
1089loop:
1090  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %cont.2 ]
1091  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
1092  %p.next = getelementptr inbounds i8, i8* %m, i64 %indvars.iv.next
1093  %p = getelementptr inbounds i8, i8* %m, i64 %indvars.iv
1094  store i8 0, i8* %p
1095  br label %cont
1096
1097cont:
1098  store i8 1, i8* %p.next
1099  br label %cont.2
1100
1101cont.2:
1102  %continue = icmp ugt i64 %indvars.iv, 15
1103  br i1 %continue, label %loop, label %return
1104
1105return:
1106  ret i32 0
1107}
1108
1109; This is an example which can potentially benefit from PHI translation.
1110; Current implementation doesn't handle this case though. This is because
1111; we don't visit the same block with different addresses while looking for
1112; clobbering instructions.
1113define i32 @test45(i1 %c) {
1114; CHECK-LABEL: @test45(
1115; CHECK-NEXT:  entry:
1116; CHECK-NEXT:    [[M:%.*]] = call i8* @calloc(i32 9, i32 20)
1117; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1118; CHECK:       true:
1119; CHECK-NEXT:    [[P_1:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 1
1120; CHECK-NEXT:    store i8 1, i8* [[P_1]]
1121; CHECK-NEXT:    br label [[CONT:%.*]]
1122; CHECK:       false:
1123; CHECK-NEXT:    [[P_2:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 2
1124; CHECK-NEXT:    store i8 1, i8* [[P_2]]
1125; CHECK-NEXT:    br label [[CONT]]
1126; CHECK:       cont:
1127; CHECK-NEXT:    [[OFFSET:%.*]] = phi i64 [ 2, [[TRUE]] ], [ 1, [[FALSE]] ]
1128; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 [[OFFSET]]
1129; CHECK-NEXT:    store i8 0, i8* [[P]]
1130; CHECK-NEXT:    br label [[RETURN:%.*]]
1131; CHECK:       return:
1132; CHECK-NEXT:    ret i32 0
1133;
1134entry:
1135  %m = call i8* @calloc(i32 9, i32 20)
1136  br i1 %c, label %true, label %false
1137
1138true:
1139  %p.1 = getelementptr inbounds i8, i8* %m, i64 1
1140  store i8 1, i8* %p.1
1141  br label %cont
1142
1143false:
1144  %p.2 = getelementptr inbounds i8, i8* %m, i64 2
1145  store i8 1, i8* %p.2
1146  br label %cont
1147
1148cont:
1149  %offset = phi i64 [ 2, %true ], [ 1, %false ]
1150  %p = getelementptr inbounds i8, i8* %m, i64 %offset
1151  store i8 0, i8* %p
1152  br label %return
1153
1154return:
1155  ret i32 0
1156}
1157
1158; This is test45 modified in a way to demonstrate PHI translation
1159; improving the accuracy of the analysis (on a slightly convoluted
1160; case though).
1161define i32 @test46(i1 %c) {
1162; CHECK-LABEL: @test46(
1163; CHECK-NEXT:  entry:
1164; CHECK-NEXT:    [[M:%.*]] = call i8* @calloc(i32 9, i32 20)
1165; CHECK-NEXT:    [[P_1:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 1
1166; CHECK-NEXT:    [[P_2:%.*]] = getelementptr inbounds i8, i8* [[M]], i64 2
1167; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1168; CHECK:       true:
1169; CHECK-NEXT:    store i8 1, i8* [[P_1]]
1170; CHECK-NEXT:    br label [[CONT:%.*]]
1171; CHECK:       false:
1172; CHECK-NEXT:    store i8 1, i8* [[P_1]]
1173; CHECK-NEXT:    br label [[CONT]]
1174; CHECK:       cont:
1175; CHECK-NEXT:    br label [[RETURN:%.*]]
1176; CHECK:       return:
1177; CHECK-NEXT:    ret i32 0
1178;
1179entry:
1180  %m = call i8* @calloc(i32 9, i32 20)
1181  %p.1 = getelementptr inbounds i8, i8* %m, i64 1
1182  %p.2 = getelementptr inbounds i8, i8* %m, i64 2
1183  br i1 %c, label %true, label %false
1184
1185true:
1186  store i8 1, i8* %p.1
1187  br label %cont
1188
1189false:
1190  store i8 1, i8* %p.1
1191  br label %cont
1192
1193cont:
1194  %offset = phi i64 [ 2, %true ], [ 2, %false ]
1195  %p = getelementptr inbounds i8, i8* %m, i64 %offset
1196  store i8 0, i8* %p
1197  br label %return
1198
1199return:
1200  ret i32 0
1201}
1202
1203declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1)
1204declare void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32)
1205