1 ; RUN: opt -passes='print<access-info>' -disable-output < %s 2>&1 | FileCheck %s
3 %s1 = type { [32000 x double], [32000 x double], [32000 x double] }
5 define i32 @load_with_pointer_phi_no_runtime_checks(ptr %data) {
6 ; CHECK-LABEL: load_with_pointer_phi_no_runtime_checks
7 ; CHECK-NEXT: loop.header:
8 ; CHECK-NEXT: Memory dependences are safe
13 loop.header: ; preds = %loop.latch, %entry
14 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
15 %iv.next = add nuw nsw i64 %iv, 1
16 %cmp5 = icmp ult i64 %iv, 15999
17 %arrayidx = getelementptr inbounds %s1, ptr %data, i64 0, i32 0, i64 %iv
18 br i1 %cmp5, label %if.then, label %if.else
20 if.then: ; preds = %loop.header
21 %gep.1 = getelementptr inbounds %s1, ptr %data, i64 0, i32 1, i64 %iv
24 if.else: ; preds = %loop.header
25 %gep.2 = getelementptr inbounds %s1, ptr %data, i64 0, i32 2, i64 %iv
28 loop.latch: ; preds = %if.else, %if.then
29 %gep.2.sink = phi ptr [ %gep.2, %if.else ], [ %gep.1, %if.then ]
30 %v8 = load double, ptr %gep.2.sink, align 8
31 %mul16 = fmul double 3.0, %v8
32 store double %mul16, ptr %arrayidx, align 8
33 %exitcond.not = icmp eq i64 %iv.next, 32000
34 br i1 %exitcond.not, label %exit, label %loop.header
36 exit: ; preds = %loop.latch
40 define i32 @store_with_pointer_phi_no_runtime_checks(ptr %data) {
41 ; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks'
42 ; CHECK-NEXT: loop.header:
43 ; CHECK-NEXT: Memory dependences are safe
48 loop.header: ; preds = %loop.latch, %entry
49 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
50 %iv.next = add nuw nsw i64 %iv, 1
51 %cmp5 = icmp ult i64 %iv, 15999
52 %arrayidx = getelementptr inbounds %s1, ptr %data, i64 0, i32 0, i64 %iv
53 br i1 %cmp5, label %if.then, label %if.else
55 if.then: ; preds = %loop.header
56 %gep.1 = getelementptr inbounds %s1, ptr %data, i64 0, i32 1, i64 %iv
59 if.else: ; preds = %loop.header
60 %gep.2 = getelementptr inbounds %s1, ptr %data, i64 0, i32 2, i64 %iv
63 loop.latch: ; preds = %if.else, %if.then
64 %gep.2.sink = phi ptr [ %gep.2, %if.else ], [ %gep.1, %if.then ]
65 %v8 = load double, ptr %arrayidx, align 8
66 %mul16 = fmul double 3.0, %v8
67 store double %mul16, ptr %gep.2.sink, align 8
68 %exitcond.not = icmp eq i64 %iv.next, 32000
69 br i1 %exitcond.not, label %exit, label %loop.header
71 exit: ; preds = %loop.latch
75 define i32 @store_with_pointer_phi_runtime_checks(ptr %A, ptr %B, ptr %C) {
76 ; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks'
77 ; CHECK-NEXT: loop.header:
78 ; CHECK-NEXT: Memory dependences are safe with run-time checks
79 ; CHECK: Run-time memory checks:
80 ; CHECK-NEXT: Check 0:
81 ; CHECK-NEXT: Comparing group ([[GROUP_B:.+]]):
82 ; CHECK-NEXT: %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
83 ; CHECK-NEXT: Against group ([[GROUP_C:.+]]):
84 ; CHECK-NEXT: %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
85 ; CHECK-NEXT: Check 1:
86 ; CHECK-NEXT: Comparing group ([[GROUP_B]]):
87 ; CHECK-NEXT: %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
88 ; CHECK-NEXT: Against group ([[GROUP_A:.+]]):
89 ; CHECK-NEXT: %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
90 ; CHECK-NEXT: Check 2:
91 ; CHECK-NEXT: Comparing group ([[GROUP_C]]):
92 ; CHECK-NEXT: %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
93 ; CHECK-NEXT: Against group ([[GROUP_A]]):
94 ; CHECK-NEXT: %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
99 loop.header: ; preds = %loop.latch, %entry
100 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
101 %iv.next = add nuw nsw i64 %iv, 1
102 %cmp5 = icmp ult i64 %iv, 15999
103 %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
104 br i1 %cmp5, label %if.then, label %if.else
106 if.then: ; preds = %loop.header
107 %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
110 if.else: ; preds = %loop.header
111 %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
114 loop.latch: ; preds = %if.else, %if.then
115 %gep.2.sink = phi ptr [ %gep.2, %if.else ], [ %gep.1, %if.then ]
116 %v8 = load double, ptr %arrayidx, align 8
117 %mul16 = fmul double 3.0, %v8
118 store double %mul16, ptr %gep.2.sink, align 8
119 %exitcond.not = icmp eq i64 %iv.next, 32000
120 br i1 %exitcond.not, label %exit, label %loop.header
122 exit: ; preds = %loop.latch
126 define i32 @load_with_pointer_phi_outside_loop(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
127 ; CHECK-LABEL: 'load_with_pointer_phi_outside_loop'
128 ; CHECK-NEXT: loop.header:
129 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop
130 ; CHECK-NEXT: Unknown data dependence.
131 ; CHECK-NEXT: Dependences:
132 ; CHECK-NEXT: Unknown:
133 ; CHECK-NEXT: %v8 = load double, ptr %ptr, align 8 ->
134 ; CHECK-NEXT: store double %mul16, ptr %arrayidx, align 8
137 br i1 %c.0, label %if.then, label %if.else
143 %ptr.select = select i1 %c.1, ptr %C, ptr %B
147 %ptr = phi ptr [ %A, %if.then ], [ %ptr.select, %if.else ]
148 br label %loop.header
150 loop.header: ; preds = %loop.latch, %entry
151 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
152 %iv.next = add nuw nsw i64 %iv, 1
153 %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
154 %v8 = load double, ptr %ptr, align 8
155 %mul16 = fmul double 3.0, %v8
156 store double %mul16, ptr %arrayidx, align 8
157 %exitcond.not = icmp eq i64 %iv.next, 32000
158 br i1 %exitcond.not, label %exit, label %loop.header
160 exit: ; preds = %loop.latch
164 define i32 @store_with_pointer_phi_outside_loop(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
165 ; CHECK-LABEL: 'store_with_pointer_phi_outside_loop'
166 ; CHECK-NEXT: loop.header:
167 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop.
168 ; CHECK-NEXT: Unknown data dependence.
169 ; CHECK-NEXT: Dependences:
170 ; CHECK-NEXT: Unknown:
171 ; CHECK-NEXT: %v8 = load double, ptr %arrayidx, align 8 ->
172 ; CHECK-NEXT: store double %mul16, ptr %ptr, align 8
175 br i1 %c.0, label %if.then, label %if.else
181 %ptr.select = select i1 %c.1, ptr %C, ptr %B
185 %ptr = phi ptr [ %A, %if.then ], [ %ptr.select, %if.else ]
186 br label %loop.header
188 loop.header: ; preds = %loop.latch, %entry
189 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
190 %iv.next = add nuw nsw i64 %iv, 1
191 %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
192 %v8 = load double, ptr %arrayidx, align 8
193 %mul16 = fmul double 3.0, %v8
194 store double %mul16, ptr %ptr, align 8
195 %exitcond.not = icmp eq i64 %iv.next, 32000
196 br i1 %exitcond.not, label %exit, label %loop.header
198 exit: ; preds = %loop.latch
202 define i32 @store_with_pointer_phi_incoming_phi(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
203 ; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi'
204 ; CHECK-NEXT: loop.header:
205 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
206 ; CHECK-NEXT: Unknown data dependence.
207 ; CHECK-NEXT: Dependences:
208 ; CHECK-NEXT: Unknown:
209 ; CHECK-NEXT: %v8 = load double, ptr %arrayidx, align 8 ->
210 ; CHECK-NEXT: store double %mul16, ptr %ptr.2, align 8
212 ; CHECK-NEXT: Run-time memory checks:
213 ; CHECK-NEXT: Check 0:
214 ; CHECK-NEXT: Comparing group ([[GROUP_C:.+]]):
216 ; CHECK-NEXT: Against group ([[GROUP_B:.+]]):
218 ; CHECK-NEXT: Check 1:
219 ; CHECK-NEXT: Comparing group ([[GROUP_C]]):
221 ; CHECK-NEXT: Against group ([[GROUP_A:.+]]):
222 ; CHECK-NEXT: %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
224 ; CHECK-NEXT: Check 2:
225 ; CHECK-NEXT: Comparing group ([[GROUP_B]]):
227 ; CHECK-NEXT: Against group ([[GROUP_A]]):
228 ; CHECK-NEXT: %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
230 ; CHECK-NEXT: Grouped accesses:
231 ; CHECK-NEXT: Group [[GROUP_C]]:
232 ; CHECK-NEXT: (Low: %C High: (8 + %C))
233 ; CHECK-NEXT: Member: %C
234 ; CHECK-NEXT: Group [[GROUP_B]]:
235 ; CHECK-NEXT: (Low: %B High: (8 + %B))
236 ; CHECK-NEXT: Member: %B
237 ; CHECK-NEXT: Group [[GROUP_A]]:
238 ; CHECK-NEXT: (Low: %A High: (256000 + %A))
239 ; CHECK-NEXT: Member: {%A,+,8}<nuw><%loop.header>
240 ; CHECK-NEXT: Member: %A
243 br label %loop.header
245 loop.header: ; preds = %loop.latch, %entry
246 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
247 %iv.next = add nuw nsw i64 %iv, 1
248 %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
249 %v8 = load double, ptr %arrayidx, align 8
250 %mul16 = fmul double 3.0, %v8
251 br i1 %c.0, label %loop.then, label %loop.latch
254 br i1 %c.0, label %loop.then.2, label %loop.else.2
264 %ptr = phi ptr [ %A, %loop.then.2 ], [ %B, %loop.else.2 ]
269 %ptr.2 = phi ptr [ %ptr, %merge.2], [ %C, %loop.header ]
270 store double %mul16, ptr %ptr.2, align 8
271 %exitcond.not = icmp eq i64 %iv.next, 32000
272 br i1 %exitcond.not, label %exit, label %loop.header
274 exit: ; preds = %loop.latch
278 ; Test cases with pointer phis forming a cycle.
279 define i32 @store_with_pointer_phi_incoming_phi_irreducible_cycle(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
280 ; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi_irreducible_cycle'
281 ; CHECK-NEXT: loop.header:
282 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
283 ; CHECK-NEXT: Unknown data dependence.
284 ; CHECK-NEXT: Dependences:
285 ; CHECK-NEXT: Unknown:
286 ; CHECK-NEXT: %v8 = load double, ptr %arrayidx, align 8 ->
287 ; CHECK-NEXT: store double %mul16, ptr %ptr.3, align 8
289 ; CHECK-NEXT: Run-time memory checks:
290 ; CHECK-NEXT: Check 0:
291 ; CHECK-NEXT: Comparing group ([[GROUP_C:.+]]):
293 ; CHECK-NEXT: Against group ([[GROUP_B:.+]]):
295 ; CHECK-NEXT: Check 1:
296 ; CHECK-NEXT: Comparing group ([[GROUP_C]]):
298 ; CHECK-NEXT: Against group ([[GROUP_A:.+]]):
299 ; CHECK-NEXT: %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
301 ; CHECK-NEXT: Check 2:
302 ; CHECK-NEXT: Comparing group ([[GROUP_B]]):
304 ; CHECK-NEXT: Against group ([[GROUP_A]]):
305 ; CHECK-NEXT: %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
307 ; CHECK-NEXT: Grouped accesses:
308 ; CHECK-NEXT: Group [[GROUP_C]]
309 ; CHECK-NEXT: (Low: %C High: (8 + %C))
310 ; CHECK-NEXT: Member: %C
311 ; CHECK-NEXT: Group [[GROUP_B]]
312 ; CHECK-NEXT: (Low: %B High: (8 + %B))
313 ; CHECK-NEXT: Member: %B
314 ; CHECK-NEXT: Group [[GROUP_A]]
315 ; CHECK-NEXT: (Low: %A High: (256000 + %A))
316 ; CHECK-NEXT: Member: {%A,+,8}<nuw><%loop.header>
317 ; CHECK-NEXT: Member: %A
320 br label %loop.header
322 loop.header: ; preds = %loop.latch, %entry
323 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
324 %iv.next = add nuw nsw i64 %iv, 1
325 %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
326 %v8 = load double, ptr %arrayidx, align 8
327 %mul16 = fmul double 3.0, %v8
328 br i1 %c.0, label %loop.then, label %loop.latch
331 br i1 %c.0, label %BB.A, label %BB.B
334 %ptr = phi ptr [ %A, %loop.then ], [ %ptr.2, %BB.B ]
338 %ptr.2 = phi ptr [ %ptr, %BB.A ], [ %B, %loop.then ]
339 br i1 %c.1, label %loop.latch, label %BB.A
342 %ptr.3 = phi ptr [ %ptr.2, %BB.B ], [ %C, %loop.header ]
343 store double %mul16, ptr %ptr.3, align 8
344 %exitcond.not = icmp eq i64 %iv.next, 32000
345 br i1 %exitcond.not, label %exit, label %loop.header
347 exit: ; preds = %loop.latch
351 define i32 @store_with_pointer_phi_outside_loop_select(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
352 ; CHECK-LABEL: 'store_with_pointer_phi_outside_loop_select'
353 ; CHECK-NEXT: loop.header:
354 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop.
355 ; CHECK-NEXT: Unknown data dependence.
356 ; CHECK-NEXT: Dependences:
357 ; CHECK-NEXT: Unknown:
358 ; CHECK-NEXT: %v8 = load double, ptr %arrayidx, align 8 ->
359 ; CHECK-NEXT: store double %mul16, ptr %ptr, align 8
362 br i1 %c.0, label %if.then, label %if.else
368 %ptr.select = select i1 %c.1, ptr %C, ptr %B
372 %ptr = phi ptr [ %A, %if.then ], [ %ptr.select, %if.else ]
373 br label %loop.header
375 loop.header: ; preds = %loop.latch, %entry
376 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
377 %iv.next = add nuw nsw i64 %iv, 1
378 %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
379 %v8 = load double, ptr %arrayidx, align 8
380 %mul16 = fmul double 3.0, %v8
381 store double %mul16, ptr %ptr, align 8
382 %exitcond.not = icmp eq i64 %iv.next, 32000
383 br i1 %exitcond.not, label %exit, label %loop.header
385 exit: ; preds = %loop.latch
389 define i32 @store_with_pointer_phi_in_same_bb_use_other_phi(ptr %A, ptr %B, ptr %C, ptr %D, i1 %c.0, i1 %c.1) {
390 ; CHECK-LABEL: Loop access info in function 'store_with_pointer_phi_in_same_bb_use_other_phi':
391 ; CHECK-NEXT: loop.header:
392 ; CHECK-NEXT: Report: cannot identify array bounds
393 ; CHECK-NEXT: Dependences:
394 ; CHECK-NEXT: Run-time memory checks:
395 ; CHECK-NEXT: Grouped accesses:
399 br label %loop.header
401 loop.header: ; preds = %loop.latch, %entry
402 %ptr.0 = phi ptr [ %C, %entry ], [ %D, %loop.header ]
403 %ptr.1 = phi ptr [ %B, %entry ], [ %ptr.0, %loop.header ]
404 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.header ]
405 %iv.next = add nuw nsw i64 %iv, 1
406 %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
407 %v8 = load double, ptr %arrayidx, align 8
408 %mul16 = fmul double 3.0, %v8
409 store double %mul16, ptr %ptr.1, align 8
410 %exitcond.not = icmp eq i64 %iv.next, 32000
411 br i1 %exitcond.not, label %exit, label %loop.header
413 exit: ; preds = %loop.latch
417 define void @phi_load_store_memdep_check(i1 %c, ptr %A, ptr %B, ptr %C) {
418 ; CHECK-LABEL: Loop access info in function 'phi_load_store_memdep_check':
419 ; CHECK-NEXT: for.body:
420 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
421 ; CHECK-NEXT: Unknown data dependence.
422 ; CHECK-NEXT: Dependences:
423 ; CHECK-NEXT: Unknown:
424 ; CHECK-NEXT: %lv3 = load i16, ptr %c.sink, align 2 ->
425 ; CHECK-NEXT: store i16 %add, ptr %c.sink, align 1
427 ; CHECK-NEXT: Unknown:
428 ; CHECK-NEXT: %lv3 = load i16, ptr %c.sink, align 2 ->
429 ; CHECK-NEXT: store i16 %add, ptr %c.sink, align 1
431 ; CHECK-NEXT: Unknown:
432 ; CHECK-NEXT: %lv = load i16, ptr %A, align 1 ->
433 ; CHECK-NEXT: store i16 %lv, ptr %A, align 1
435 ; CHECK-NEXT: Unknown:
436 ; CHECK-NEXT: store i16 %lv, ptr %A, align 1 ->
437 ; CHECK-NEXT: %lv2 = load i16, ptr %A, align 1
439 ; CHECK-NEXT: Run-time memory checks:
440 ; CHECK-NEXT: Check 0:
441 ; CHECK-NEXT: Comparing group ([[GROUP_A:.+]]):
444 ; CHECK-NEXT: Against group ([[GROUP_C:.+]]):
447 ; CHECK-NEXT: Check 1:
448 ; CHECK-NEXT: Comparing group ([[GROUP_A]]):
451 ; CHECK-NEXT: Against group ([[GROUP_B:.+]]):
454 ; CHECK-NEXT: Check 2:
455 ; CHECK-NEXT: Comparing group ([[GROUP_C]]):
458 ; CHECK-NEXT: Against group ([[GROUP_B]]):
461 ; CHECK-NEXT: Grouped accesses:
462 ; CHECK-NEXT: Group [[GROUP_A]]
463 ; CHECK-NEXT: (Low: %A High: (2 + %A))
464 ; CHECK-NEXT: Member: %A
465 ; CHECK-NEXT: Member: %A
466 ; CHECK-NEXT: Group [[GROUP_C]]
467 ; CHECK-NEXT: (Low: %C High: (2 + %C))
468 ; CHECK-NEXT: Member: %C
469 ; CHECK-NEXT: Member: %C
470 ; CHECK-NEXT: Group [[GROUP_B]]
471 ; CHECK-NEXT: (Low: %B High: (2 + %B))
472 ; CHECK-NEXT: Member: %B
473 ; CHECK-NEXT: Member: %B
479 for.body: ; preds = %if.end, %entry
480 %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
481 %lv = load i16, ptr %A, align 1
482 store i16 %lv, ptr %A, align 1
483 br i1 %c, label %if.then, label %if.end
485 if.then: ; preds = %for.body
486 %lv2 = load i16, ptr %A, align 1
489 if.end: ; preds = %if.then, %for.body
490 %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
491 %lv3 = load i16, ptr %c.sink
492 %add = add i16 %lv3, 10
493 store i16 %add, ptr %c.sink, align 1
494 %iv.next = add nuw nsw i16 %iv, 1
495 %tobool.not = icmp eq i16 %iv.next, 1000
496 br i1 %tobool.not, label %for.end.loopexit, label %for.body
498 for.end.loopexit: ; preds = %if.end