[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Analysis / MemorySSA / phi-translation.ll
blob152921325ae99b2929d67747c0cf59f79b1353cf
1 ; RUN: opt -basic-aa -print-memoryssa -verify-memoryssa -enable-new-pm=0 -analyze < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NOLIMIT
2 ; RUN: opt -memssa-check-limit=0 -basic-aa -print-memoryssa -verify-memoryssa -enable-new-pm=0 -analyze < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LIMIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NOLIMIT
4 ; RUN: opt -memssa-check-limit=0 -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LIMIT
6 ; %ptr can't alias %local, so we should be able to optimize the use of %local to
7 ; point to the store to %local.
8 ; CHECK-LABEL: define void @check
9 define void @check(i8* %ptr, i1 %bool) {
10 entry:
11   %local = alloca i8, align 1
12 ; CHECK: 1 = MemoryDef(liveOnEntry)
13 ; CHECK-NEXT: store i8 0, i8* %local, align 1
14   store i8 0, i8* %local, align 1
15   br i1 %bool, label %if.then, label %if.end
17 if.then:
18   %p2 = getelementptr inbounds i8, i8* %ptr, i32 1
19 ; CHECK: 2 = MemoryDef(1)
20 ; CHECK-NEXT: store i8 0, i8* %p2, align 1
21   store i8 0, i8* %p2, align 1
22   br label %if.end
24 if.end:
25 ; CHECK: 3 = MemoryPhi({entry,1},{if.then,2})
26 ; NOLIMIT: MemoryUse(1) MayAlias
27 ; NOLIMIT-NEXT: load i8, i8* %local, align 1
28 ; LIMIT: MemoryUse(3)
29 ; LIMIT-NEXT: load i8, i8* %local, align 1
30   load i8, i8* %local, align 1
31   ret void
34 ; CHECK-LABEL: define void @check2
35 define void @check2(i1 %val1, i1 %val2, i1 %val3) {
36 entry:
37   %local = alloca i8, align 1
38   %local2 = alloca i8, align 1
40 ; CHECK: 1 = MemoryDef(liveOnEntry)
41 ; CHECK-NEXT: store i8 0, i8* %local
42   store i8 0, i8* %local
43   br i1 %val1, label %if.then, label %phi.3
45 if.then:
46 ; CHECK: 2 = MemoryDef(1)
47 ; CHECK-NEXT: store i8 2, i8* %local2
48   store i8 2, i8* %local2
49   br i1 %val2, label %phi.2, label %phi.3
51 phi.3:
52 ; CHECK: 7 = MemoryPhi({entry,1},{if.then,2})
53 ; CHECK: 3 = MemoryDef(7)
54 ; CHECK-NEXT: store i8 3, i8* %local2
55   store i8 3, i8* %local2
56   br i1 %val3, label %phi.2, label %phi.1
58 phi.2:
59 ; CHECK: 5 = MemoryPhi({if.then,2},{phi.3,3})
60 ; CHECK: 4 = MemoryDef(5)
61 ; CHECK-NEXT: store i8 4, i8* %local2
62   store i8 4, i8* %local2
63   br label %phi.1
65 phi.1:
66 ; Order matters here; phi.2 needs to come before phi.3, because that's the order
67 ; they're visited in.
68 ; CHECK: 6 = MemoryPhi({phi.2,4},{phi.3,3})
69 ; NOLIMIT: MemoryUse(1) MayAlias
70 ; NOLIMIT-NEXT: load i8, i8* %local
71 ; LIMIT: MemoryUse(6)
72 ; LIMIT-NEXT: load i8, i8* %local
73   load i8, i8* %local
74   ret void
77 ; CHECK-LABEL: define void @cross_phi
78 define void @cross_phi(i8* noalias %p1, i8* noalias %p2) {
79 ; CHECK: 1 = MemoryDef(liveOnEntry)
80 ; CHECK-NEXT: store i8 0, i8* %p1
81   store i8 0, i8* %p1
82 ; NOLIMIT: MemoryUse(1) MustAlias
83 ; NOLIMIT-NEXT: load i8, i8* %p1
84 ; LIMIT: MemoryUse(1)
85 ; LIMIT-NEXT: load i8, i8* %p1
86   load i8, i8* %p1
87   br i1 undef, label %a, label %b
90 ; CHECK: 2 = MemoryDef(1)
91 ; CHECK-NEXT: store i8 0, i8* %p2
92   store i8 0, i8* %p2
93   br i1 undef, label %c, label %d
96 ; CHECK: 3 = MemoryDef(1)
97 ; CHECK-NEXT: store i8 1, i8* %p2
98   store i8 1, i8* %p2
99   br i1 undef, label %c, label %d
102 ; CHECK: 6 = MemoryPhi({a,2},{b,3})
103 ; CHECK: 4 = MemoryDef(6)
104 ; CHECK-NEXT: store i8 2, i8* %p2
105   store i8 2, i8* %p2
106   br label %e
109 ; CHECK: 7 = MemoryPhi({a,2},{b,3})
110 ; CHECK: 5 = MemoryDef(7)
111 ; CHECK-NEXT: store i8 3, i8* %p2
112   store i8 3, i8* %p2
113   br label %e
116 ; 8 = MemoryPhi({c,4},{d,5})
117 ; NOLIMIT: MemoryUse(1) MustAlias
118 ; NOLIMIT-NEXT: load i8, i8* %p1
119 ; LIMIT: MemoryUse(8)
120 ; LIMIT-NEXT: load i8, i8* %p1
121   load i8, i8* %p1
122   ret void
125 ; CHECK-LABEL: define void @looped
126 define void @looped(i8* noalias %p1, i8* noalias %p2) {
127 ; CHECK: 1 = MemoryDef(liveOnEntry)
128 ; CHECK-NEXT: store i8 0, i8* %p1
129   store i8 0, i8* %p1
130   br label %loop.1
132 loop.1:
133 ; CHECK: 6 = MemoryPhi({%0,1},{loop.3,4})
134 ; CHECK: 2 = MemoryDef(6)
135 ; CHECK-NEXT: store i8 0, i8* %p2
136   store i8 0, i8* %p2
137   br i1 undef, label %loop.2, label %loop.3
139 loop.2:
140 ; CHECK: 5 = MemoryPhi({loop.1,2},{loop.3,4})
141 ; CHECK: 3 = MemoryDef(5)
142 ; CHECK-NEXT: store i8 1, i8* %p2
143   store i8 1, i8* %p2
144   br label %loop.3
146 loop.3:
147 ; CHECK: 7 = MemoryPhi({loop.1,2},{loop.2,3})
148 ; CHECK: 4 = MemoryDef(7)
149 ; CHECK-NEXT: store i8 2, i8* %p2
150   store i8 2, i8* %p2
151 ; NOLIMIT: MemoryUse(1) MayAlias
152 ; NOLIMIT-NEXT: load i8, i8* %p1
153 ; LIMIT: MemoryUse(4)
154 ; LIMIT-NEXT: load i8, i8* %p1
155   load i8, i8* %p1
156   br i1 undef, label %loop.2, label %loop.1
159 ; CHECK-LABEL: define void @looped_visitedonlyonce
160 define void @looped_visitedonlyonce(i8* noalias %p1, i8* noalias %p2) {
161   br label %while.cond
163 while.cond:
164 ; CHECK: 5 = MemoryPhi({%0,liveOnEntry},{if.end,3})
165 ; CHECK-NEXT: br i1 undef, label %if.then, label %if.end
166   br i1 undef, label %if.then, label %if.end
168 if.then:
169 ; CHECK: 1 = MemoryDef(5)
170 ; CHECK-NEXT: store i8 0, i8* %p1
171   store i8 0, i8* %p1
172   br i1 undef, label %if.end, label %if.then2
174 if.then2:
175 ; CHECK: 2 = MemoryDef(1)
176 ; CHECK-NEXT: store i8 1, i8* %p2
177   store i8 1, i8* %p2
178   br label %if.end
180 if.end:
181 ; CHECK: 4 = MemoryPhi({while.cond,5},{if.then,1},{if.then2,2})
182 ; CHECK: MemoryUse(4)
183 ; CHECK-NEXT: load i8, i8* %p1
184   load i8, i8* %p1
185 ; CHECK: 3 = MemoryDef(4)
186 ; CHECK-NEXT: store i8 2, i8* %p2
187   store i8 2, i8* %p2
188 ; NOLIMIT: MemoryUse(4) MayAlias
189 ; NOLIMIT-NEXT: load i8, i8* %p1
190 ; LIMIT: MemoryUse(3)
191 ; LIMIT-NEXT: load i8, i8* %p1
192   load i8, i8* %p1
193   br label %while.cond
196 ; CHECK-LABEL: define i32 @use_not_optimized_due_to_backedge
197 define i32 @use_not_optimized_due_to_backedge(i32* nocapture %m_i_strides, i32* nocapture readonly %eval_left_dims) {
198 entry:
199 ; CHECK: 1 = MemoryDef(liveOnEntry)
200 ; CHECK_NEXT: store i32 1, i32* %m_i_strides, align 4
201   store i32 1, i32* %m_i_strides, align 4
202   br label %for.body
204 for.cond.cleanup:                                 ; preds = %for.inc
205   ret i32 %m_i_size.1
207 for.body:                                         ; preds = %entry, %for.inc
208 ; CHECK: 4 = MemoryPhi({entry,1},{for.inc,3})
209 ; CHECK-NEXT: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ]
210   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ]
211   %m_i_size.022 = phi i32 [ 1, %entry ], [ %m_i_size.1, %for.inc ]
212   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
213   %cmp1 = icmp eq i64 %indvars.iv, 0
214   %arrayidx2 = getelementptr inbounds i32, i32* %m_i_strides, i64 %indvars.iv
215 ; CHECK: MemoryUse(4)
216 ; CHECK-NEXT: %0 = load i32, i32* %arrayidx2, align 4
217   %0 = load i32, i32* %arrayidx2, align 4
218   %arrayidx4 = getelementptr inbounds i32, i32* %eval_left_dims, i64 %indvars.iv
219 ; CHECK: MemoryUse(4)
220 ; CHECK-NEXT: %1 = load i32, i32* %arrayidx4, align 4
221   %1 = load i32, i32* %arrayidx4, align 4
222   %mul = mul nsw i32 %1, %0
223   br i1 %cmp1, label %if.then, label %for.inc
225 if.then:                                          ; preds = %for.body
226   %arrayidx7 = getelementptr inbounds i32, i32* %m_i_strides, i64 %indvars.iv.next
227 ; CHECK: 2 = MemoryDef(4)
228 ; CHECK-NEXT: store i32 %mul, i32* %arrayidx7, align 4
229   store i32 %mul, i32* %arrayidx7, align 4
230   br label %for.inc
232 for.inc:                                          ; preds = %for.body, %if.then
233 ; CHECK: 3 = MemoryPhi({for.body,4},{if.then,2})
234 ; CHECK-NEXT: %m_i_size.1 = phi i32 [ %m_i_size.022, %if.then ], [ %mul, %for.body ]
235   %m_i_size.1 = phi i32 [ %m_i_size.022, %if.then ], [ %mul, %for.body ]
236   br i1 %cmp1, label %for.body, label %for.cond.cleanup
240 %ArrayType = type { [2 x i64] }
241 %StructOverArrayType = type { %ArrayType }
242 %BigStruct = type { i8, i8, i8, i8, i8, i8, i8, %ArrayType, %ArrayType}
244 ; CHECK-LABEL: define void @use_not_optimized_due_to_backedge_unknown
245 define void @use_not_optimized_due_to_backedge_unknown(%BigStruct* %this) {
246 entry:
247   %eval_left_dims = alloca %StructOverArrayType, align 8
248   %tmp0 = bitcast %StructOverArrayType* %eval_left_dims to i8*
249   %eval_right_dims = alloca %StructOverArrayType, align 8
250   %tmp1 = bitcast %StructOverArrayType* %eval_right_dims to i8*
251   %lhs_strides = alloca %ArrayType, align 8
252   %rhs_strides = alloca %ArrayType, align 8
253   br label %for.body.preheader
255 for.body.preheader:                               ; preds = %entry
256   %arrayidx.i527 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 7, i32 0, i64 0
257 ; CHECK: 1 = MemoryDef(liveOnEntry)
258 ; CHECK-NEXT: store i64 1, i64* %arrayidx.i527, align 8
259   store i64 1, i64* %arrayidx.i527, align 8
260   %arrayidx.i528 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 8, i32 0, i64 0
261 ; CHECK: 2 = MemoryDef(1)
262 ; CHECK-NEXT: store i64 1, i64* %arrayidx.i528, align 8
263   store i64 1, i64* %arrayidx.i528, align 8
264   br label %for.main.body
266 for.main.body:               ; preds = %if.end220.if.then185_crit_edge, %for.body.preheader
267 ; CHECK: 4 = MemoryPhi({for.body.preheader,2},{if.end220.if.then185_crit_edge,3})
268 ; CHECK-NEXT: %nocontract_idx.0656 = phi i64 [ 0, %for.body.preheader ], [ 1, %if.end220.if.then185_crit_edge ]
269   %nocontract_idx.0656 = phi i64 [ 0, %for.body.preheader ], [ 1, %if.end220.if.then185_crit_edge ]
270   %add199 = add nuw nsw i64 %nocontract_idx.0656, 1
271   %cmp200 = icmp eq i64 %nocontract_idx.0656, 0
272   %arrayidx.i559 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 7, i32 0, i64 %nocontract_idx.0656
273 ; CHECK: MemoryUse(4)
274 ; CHECK-NEXT: %tmp21 = load i64, i64* %arrayidx.i559, align 8
275   %tmp21 = load i64, i64* %arrayidx.i559, align 8
276   %mul206 = mul nsw i64 %tmp21, %tmp21
277   br i1 %cmp200, label %if.end220.if.then185_crit_edge, label %the.end
279 if.end220.if.then185_crit_edge:                   ; preds = %for.main.body
280   %arrayidx.i571 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 7, i32 0, i64 %add199
281 ; CHECK: 3 = MemoryDef(4)
282 ; CHECK-NEXT: store i64 %mul206, i64* %arrayidx.i571, align 8
283   store i64 %mul206, i64* %arrayidx.i571, align 8
284   br label %for.main.body
286 the.end:                            ; preds = %for.main.body
287   ret void
292 @c = local_unnamed_addr global [2 x i16] zeroinitializer, align 2
294 define i32 @dont_merge_noalias_simple(i32* noalias %ptr) {
295 ; CHECK-LABEL: define i32 @dont_merge_noalias_simple
296 ; CHECK-LABEL: entry:
297 ; CHECK:       ; 1 = MemoryDef(liveOnEntry)
298 ; CHECK-NEXT:  store i16 1, i16* %s1.ptr, align 2
300 ; CHECK-LABEL: %for.body
301 ; CHECK:       ; MemoryUse(4)
302 ; CHECK-NEXT:    %lv = load i16, i16* %arrayidx, align 2
304 entry:
305   %s1.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
306   store i16 1, i16* %s1.ptr, align 2
307   br label %for.body
309 for.body:                                         ; preds = %for.body, %entry
310   %storemerge2 = phi i32 [ 1, %entry ], [ %dec, %for.body ]
311   %idxprom1 = zext i32 %storemerge2 to i64
312   %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 %idxprom1
313   %lv = load i16, i16* %arrayidx, align 2
314   %conv = sext i16 %lv to i32
315   store i32 %conv, i32* %ptr, align 4
316   %dec = add nsw i32 %storemerge2, -1
317   %cmp = icmp sgt i32 %storemerge2, 0
318   br i1 %cmp, label %for.body, label %for.end
320 for.end:                                          ; preds = %for.body
321   %s2.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
322   store i16 0, i16* %s2.ptr, align 2
323   ret i32 0
327 define i32 @dont_merge_noalias_complex(i32* noalias %ptr, i32* noalias %another) {
328 ; CHECK-LABEL: define i32 @dont_merge_noalias_complex
329 ; CHECK-LABEL: entry:
330 ; CHECK:       ; 1 = MemoryDef(liveOnEntry)
331 ; CHECK-NEXT:  store i16 1, i16* %s1.ptr, align 2
333 ; CHECK-LABEL: %for.body
334 ; CHECK:       ; MemoryUse(7)
335 ; CHECK-NEXT:    %lv = load i16, i16* %arrayidx, align 2
337 entry:
338   %s1.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
339   store i16 1, i16* %s1.ptr, align 2
340   br label %for.body
342 for.body:                                         ; preds = %for.body, %entry
343   %storemerge2 = phi i32 [ 1, %entry ], [ %dec, %merge.body ]
344   %idxprom1 = zext i32 %storemerge2 to i64
345   %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 %idxprom1
346   %lv = load i16, i16* %arrayidx, align 2
347   %conv = sext i16 %lv to i32
348   store i32 %conv, i32* %ptr, align 4
349   %dec = add nsw i32 %storemerge2, -1
351   %cmpif = icmp sgt i32 %storemerge2, 1
352   br i1 %cmpif, label %if.body, label %else.body
354 if.body:
355   store i32 %conv, i32* %another, align 4
356   br label %merge.body
358 else.body:
359   store i32 %conv, i32* %another, align 4
360   br label %merge.body
362 merge.body:
363   %cmp = icmp sgt i32 %storemerge2, 0
364   br i1 %cmp, label %for.body, label %for.end
366 for.end:                                          ; preds = %for.body
367   %s2.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
368   store i16 0, i16* %s2.ptr, align 2
369   ret i32 0
372 declare i1 @should_exit(i32) readnone
373 declare void @init([32 x i32]*)
375 ; Test case for PR47498.
376 ; %l.1 may read the result of `store i32 10, i32* %p.1` in %storebb, because
377 ; after %storebb has been executed, %loop.1.header might be executed again.
378 ; Make sure %l.1's defining access is the MemoryPhi in the block.
379 define void @dont_merge_noalias_complex_2(i32 %arg, i32 %arg1)  {
380 ; CHECK-LABEL: define void @dont_merge_noalias_complex_2(
382 ; CHECK-LABEL: entry:
383 ; CHECK:       ; 1 = MemoryDef(liveOnEntry)
384 ; CHECK-NEXT:  call void @init([32 x i32]* %tmp)
386 ; CHECK-LABEL: loop.1.header:
387 ; CHECK-NEXT:  ; 4 = MemoryPhi({entry,1},{loop.1.latch,3})
388 ; CHECK:       ; MemoryUse(4)
389 ; CHECK-NEXT:  %l.1 = load i32, i32* %p.1, align 4
391 ; CHECK-LABEL: loop.1.latch:
392 ; CHECK-NEXT:  ; 3 = MemoryPhi({loop.1.header,4},{storebb,2})
394 ; CHECK-LABEL: storebb:
395 ; CHECK-NEXT:  %iv.add2 = add nuw nsw i64 %iv, 2
396 ; CHECK-NEXT:  %p.2 = getelementptr inbounds [32 x i32], [32 x i32]* %tmp, i64 0, i64 %iv.add2
397 ; CHECK-NEXT:  ; MemoryUse(4)
398 ; CHECK-NEXT:  %l.2 = load i32, i32* %p.2, align 4
399 ; CHECK-NEXT:  ; 2 = MemoryDef(4)
400 ; CHECK-NEXT:  store i32 10, i32* %p.1, align 4
401 entry:
402   %tmp = alloca [32 x i32], align 16
403   call void @init([32 x i32]* %tmp)
404   br label %loop.1.header
406 loop.1.header:
407   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.1.latch ]
408   %iv.next = add nuw nsw i64 %iv, 1
409   %p.1 = getelementptr inbounds [32 x i32], [32 x i32]* %tmp, i64 0, i64 %iv.next
410   %l.1 = load i32, i32* %p.1, align 4
411   %tmp244 = icmp ult i64 %iv, 10
412   br i1 %tmp244, label %loop.1.latch, label %storebb
414 loop.1.latch:
415   %ec = call i1 @should_exit(i32 %l.1)
416   br i1 %ec, label %exit, label %loop.1.header
418 storebb:
419   %iv.add2 = add nuw nsw i64 %iv, 2
420   %p.2 = getelementptr inbounds [32 x i32], [32 x i32]* %tmp, i64 0, i64 %iv.add2
421   %l.2 = load i32, i32* %p.2, align 4
422   store i32 10, i32* %p.1, align 4
423   br label %loop.1.latch
425 exit:
426   ret void
429 ; CHECK-LABEL: define void @use_clobbered_by_def_in_loop()
430 define void @use_clobbered_by_def_in_loop() {
431 entry:
432   %nodeStack = alloca [12 x i32], align 4
433   %0 = bitcast [12 x i32]* %nodeStack to i8*
434   call void @llvm.lifetime.start.p0i8(i64 48, i8* nonnull %0)
435   br i1 false, label %cleanup, label %while.cond
437 ; CHECK-LABEL: while.cond:
438 ; CHECK-NEXT: ; [[NO6:.*]] = MemoryPhi({entry,1},{while.cond.backedge,5})
440 while.cond:                                       ; preds = %entry, %while.cond.backedge
441   %depth.1 = phi i32 [ %depth.1.be, %while.cond.backedge ], [ 0, %entry ]
442   %cmp = icmp sgt i32 %depth.1, 0
443   br i1 %cmp, label %land.rhs, label %while.end
445 ; CHECK-LABEL: land.rhs:
446 ; CHECK-NEXT: %sub = add nsw i32 %depth.1, -1
447 ; CHECK-NEXT: %arrayidx = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %sub
448 ; CHECK-NEXT: ; MemoryUse([[NO6]])
449 ; CHECK-NEXT: %1 = load i32, i32* %arrayidx, align 4
451 land.rhs:                                         ; preds = %while.cond
452   %sub = add nsw i32 %depth.1, -1
453   %arrayidx = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %sub
454   %1 = load i32, i32* %arrayidx, align 4
455   br i1 true, label %while.body, label %while.end
457 while.body:                                       ; preds = %land.rhs
458   br i1 true, label %cleanup, label %while.cond.backedge
460 while.cond.backedge:                              ; preds = %while.body, %while.end
461   %depth.1.be = phi i32 [ %sub, %while.body ], [ %inc, %while.end ]
462   br label %while.cond
464 while.end:                                        ; preds = %while.cond, %land.rhs
465   %arrayidx10 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %depth.1
466   store i32 %depth.1, i32* %arrayidx10, align 4
467   %inc = add nsw i32 %depth.1, 1
468   br i1 true, label %cleanup, label %while.cond.backedge
470 cleanup:                                          ; preds = %while.body, %while.end, %entry
471   call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull %0)
472   ret void
475 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
476 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
478 define void @another_loop_clobber_inc() {
479 ; CHECK-LABEL: void @another_loop_clobber_inc
480 ; CHECK-LABEL: loop.header:
481 ; CHECK-NEXT:  ; 4 = MemoryPhi({entry,1},{cond.read,3})
483 ; CHECK-LABEL: cond.read:
484 ; CHECK:       ; MemoryUse(4)
485 ; CHECK-NEXT:  %use = load i32, i32* %ptr.1, align 4
486 ; CHECK-NEXT:  ; 2 = MemoryDef(4)
487 ; CHECK-NEXT:  %c.2 = call i1 @cond(i32 %use)
488 ; CHECK-NEXT:  %ptr.10 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %inc
489 ; CHECK-NEXT:  ; 3 = MemoryDef(2)
490 ; CHECK-NEXT:  store i32 10, i32* %ptr.2, align 4
492 entry:
493   %nodeStack = alloca [12 x i32], align 4
494   %c.1 = call i1 @cond(i32 1)
495   br i1 %c.1, label %cleanup, label %loop.header
497 loop.header:                                       ; preds = %entry, %while.cond.backedge
498   %depth.1 = phi i32 [ %inc, %cond.read], [ 1, %entry ]
499   %cmp = icmp sgt i32 %depth.1, 0
500   %inc = add nsw i32 %depth.1, 3
501   %inc2 = add nsw i32 %depth.1, 6
502   br i1 %cmp, label %cond.read, label %cleanup
504 cond.read:                                        ; preds = %while.cond
505   %ptr.1 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %depth.1
506   %ptr.2 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %inc2
507   %use = load i32, i32* %ptr.1, align 4
508   %c.2 = call i1 @cond(i32 %use)
509   %ptr.10 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %inc
510   store i32 10, i32* %ptr.2, align 4
511   br i1 %c.2, label %loop.header, label %cleanup
513 cleanup:
514   ret void
517 define void @another_loop_clobber_dec() {
518 ; CHECK-LABEL: void @another_loop_clobber_dec
519 ; CHECK-LABEL: loop.header:
520 ; CHECK-NEXT:  ; 4 = MemoryPhi({entry,1},{cond.read,3})
522 ; CHECK-LABEL: cond.read:
523 ; CHECK:       ; MemoryUse(4)
524 ; CHECK-NEXT:  %use = load i32, i32* %ptr.1, align 4
525 ; CHECK-NEXT:  ; 2 = MemoryDef(4)
526 ; CHECK-NEXT:  %c.2 = call i1 @cond(i32 %use)
527 ; CHECK-NEXT:  %ptr.10 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i64 %sub
528 ; CHECK-NEXT:  ; 3 = MemoryDef(2)
529 ; CHECK-NEXT:  store i32 10, i32* %ptr.2, align 4
531 entry:
532   %nodeStack = alloca [12 x i32], align 4
533   %c.1 = call i1 @cond(i32 1)
534   br i1 %c.1, label %cleanup, label %loop.header
536 loop.header:                                       ; preds = %entry, %while.cond.backedge
537   %depth.1 = phi i64 [ %sub, %cond.read], [ 20, %entry ]
538   %cmp = icmp sgt i64 %depth.1, 6
539   %sub = sub nsw nuw i64 %depth.1, 3
540   %sub2 = sub nsw nuw i64 %depth.1, 6
541   br i1 %cmp, label %cond.read, label %cleanup
543 cond.read:                                        ; preds = %while.cond
544   %ptr.1 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i64 %depth.1
545   %ptr.2 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i64 %sub2
546   %use = load i32, i32* %ptr.1, align 4
547   %c.2 = call i1 @cond(i32 %use)
548   %ptr.10 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i64 %sub
549   store i32 10, i32* %ptr.2, align 4
550   br i1 %c.2, label %loop.header, label %cleanup
552 cleanup:
553   ret void
556 declare i1 @cond(i32)