1; RUN: opt -loop-accesses -analyze -enable-new-pm=0 < %s | FileCheck %s
2; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output  < %s 2>&1 | FileCheck %s
3
4%s1 = type { [32000 x double], [32000 x double], [32000 x double] }
5
6define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) {
7; CHECK-LABEL: load_with_pointer_phi_no_runtime_checks
8; CHECK-NEXT:  loop.header:
9; CHECK-NEXT:    Report: cannot identify array bounds
10;
11entry:
12  br label %loop.header
13
14loop.header:                                        ; preds = %loop.latch, %entry
15  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
16  %iv.next = add nuw nsw i64 %iv, 1
17  %cmp5 = icmp ult i64 %iv, 15999
18  %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv
19  br i1 %cmp5, label %if.then, label %if.else
20
21if.then:                                          ; preds = %loop.header
22  %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv
23  br label %loop.latch
24
25if.else:                                          ; preds = %loop.header
26  %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv
27  br label %loop.latch
28
29loop.latch:                                          ; preds = %if.else, %if.then
30  %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
31  %v8 = load double, double* %gep.2.sink, align 8
32  %mul16 = fmul double 3.0, %v8
33  store double %mul16, double* %arrayidx, align 8
34  %exitcond.not = icmp eq i64 %iv.next, 32000
35  br i1 %exitcond.not, label %exit, label %loop.header
36
37exit:                                             ; preds = %loop.latch
38  ret i32 10
39}
40
41define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) {
42; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks'
43; CHECK-NEXT:  loop.header:
44; CHECK-NEXT:    Report: cannot identify array bounds
45;
46entry:
47  br label %loop.header
48
49loop.header:                                        ; preds = %loop.latch, %entry
50  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
51  %iv.next = add nuw nsw i64 %iv, 1
52  %cmp5 = icmp ult i64 %iv, 15999
53  %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv
54  br i1 %cmp5, label %if.then, label %if.else
55
56if.then:                                          ; preds = %loop.header
57  %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv
58  br label %loop.latch
59
60if.else:                                          ; preds = %loop.header
61  %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv
62  br label %loop.latch
63
64loop.latch:                                          ; preds = %if.else, %if.then
65  %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
66  %v8 = load double, double* %arrayidx, align 8
67  %mul16 = fmul double 3.0, %v8
68  store double %mul16, double* %gep.2.sink, align 8
69  %exitcond.not = icmp eq i64 %iv.next, 32000
70  br i1 %exitcond.not, label %exit, label %loop.header
71
72exit:                                             ; preds = %loop.latch
73  ret i32 10
74}
75
76define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) {
77; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks'
78; CHECK-NEXT:  loop.header:
79; CHECK-NEXT:    Report: cannot identify array bounds
80;
81entry:
82  br label %loop.header
83
84loop.header:                                        ; preds = %loop.latch, %entry
85  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
86  %iv.next = add nuw nsw i64 %iv, 1
87  %cmp5 = icmp ult i64 %iv, 15999
88  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
89  br i1 %cmp5, label %if.then, label %if.else
90
91if.then:                                          ; preds = %loop.header
92  %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
93  br label %loop.latch
94
95if.else:                                          ; preds = %loop.header
96  %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
97  br label %loop.latch
98
99loop.latch:                                          ; preds = %if.else, %if.then
100  %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
101  %v8 = load double, double* %arrayidx, align 8
102  %mul16 = fmul double 3.0, %v8
103  store double %mul16, double* %gep.2.sink, align 8
104  %exitcond.not = icmp eq i64 %iv.next, 32000
105  br i1 %exitcond.not, label %exit, label %loop.header
106
107exit:                                             ; preds = %loop.latch
108  ret i32 10
109}
110
111define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
112; CHECK-LABEL: 'load_with_pointer_phi_outside_loop'
113; CHECK-NEXT:  loop.header:
114; CHECK-NEXT:    Report: unsafe dependent memory operations in loop
115; CHECK-NEXT:    Dependences:
116; CHECK-NEXT:      Unknown:
117; CHECK-NEXT:          %v8 = load double, double* %ptr, align 8 ->
118; CHECK-NEXT:          store double %mul16, double* %arrayidx, align 8
119;
120entry:
121  br i1 %c.0, label %if.then, label %if.else
122
123if.then:
124  br label %loop.ph
125
126if.else:
127  %ptr.select = select i1 %c.1, double* %C, double* %B
128  br label %loop.ph
129
130loop.ph:
131  %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
132  br label %loop.header
133
134loop.header:                                        ; preds = %loop.latch, %entry
135  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
136  %iv.next = add nuw nsw i64 %iv, 1
137  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
138  %v8 = load double, double* %ptr, align 8
139  %mul16 = fmul double 3.0, %v8
140  store double %mul16, double* %arrayidx, align 8
141  %exitcond.not = icmp eq i64 %iv.next, 32000
142  br i1 %exitcond.not, label %exit, label %loop.header
143
144exit:                                             ; preds = %loop.latch
145  ret i32 10
146}
147
148define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
149; CHECK-LABEL: 'store_with_pointer_phi_outside_loop'
150; CHECK-NEXT:  loop.header:
151; CHECK-NEXT:    Report: unsafe dependent memory operations in loop.
152; CHECK-NEXT:    Dependences:
153; CHECK-NEXT:      Unknown:
154; CHECK-NEXT:          %v8 = load double, double* %arrayidx, align 8 ->
155; CHECK-NEXT:          store double %mul16, double* %ptr, align 8
156;
157entry:
158  br i1 %c.0, label %if.then, label %if.else
159
160if.then:
161  br label %loop.ph
162
163if.else:
164  %ptr.select = select i1 %c.1, double* %C, double* %B
165  br label %loop.ph
166
167loop.ph:
168  %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
169  br label %loop.header
170
171loop.header:                                        ; preds = %loop.latch, %entry
172  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
173  %iv.next = add nuw nsw i64 %iv, 1
174  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
175  %v8 = load double, double* %arrayidx, align 8
176  %mul16 = fmul double 3.0, %v8
177  store double %mul16, double* %ptr, align 8
178  %exitcond.not = icmp eq i64 %iv.next, 32000
179  br i1 %exitcond.not, label %exit, label %loop.header
180
181exit:                                             ; preds = %loop.latch
182  ret i32 10
183}
184