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