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:    Memory dependences are safe
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:    Memory dependences are safe
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:    Memory dependences are safe with run-time checks
80; CHECK:         Run-time memory checks:
81; CHECK-NEXT:    Check 0:
82; CHECK-NEXT:      Comparing group ([[GROUP_C:.+]]):
83; CHECK-NEXT:        %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
84; CHECK-NEXT:      Against group ([[GROUP_B:.+]]):
85; CHECK-NEXT:        %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
86; CHECK-NEXT:    Check 1:
87; CHECK-NEXT:      Comparing group ([[GROUP_C]]):
88; CHECK-NEXT:        %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
89; CHECK-NEXT:      Against group ([[GROUP_A:.+]]):
90; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
91; CHECK-NEXT:    Check 2:
92; CHECK-NEXT:      Comparing group ([[GROUP_B]]):
93; CHECK-NEXT:        %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
94; CHECK-NEXT:      Against group ([[GROUP_A]]):
95; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
96;
97entry:
98  br label %loop.header
99
100loop.header:                                        ; preds = %loop.latch, %entry
101  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
102  %iv.next = add nuw nsw i64 %iv, 1
103  %cmp5 = icmp ult i64 %iv, 15999
104  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
105  br i1 %cmp5, label %if.then, label %if.else
106
107if.then:                                          ; preds = %loop.header
108  %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
109  br label %loop.latch
110
111if.else:                                          ; preds = %loop.header
112  %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
113  br label %loop.latch
114
115loop.latch:                                          ; preds = %if.else, %if.then
116  %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
117  %v8 = load double, double* %arrayidx, align 8
118  %mul16 = fmul double 3.0, %v8
119  store double %mul16, double* %gep.2.sink, align 8
120  %exitcond.not = icmp eq i64 %iv.next, 32000
121  br i1 %exitcond.not, label %exit, label %loop.header
122
123exit:                                             ; preds = %loop.latch
124  ret i32 10
125}
126
127define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
128; CHECK-LABEL: 'load_with_pointer_phi_outside_loop'
129; CHECK-NEXT:  loop.header:
130; CHECK-NEXT:    Report: unsafe dependent memory operations in loop
131; CHECK-NEXT:    Dependences:
132; CHECK-NEXT:      Unknown:
133; CHECK-NEXT:          %v8 = load double, double* %ptr, align 8 ->
134; CHECK-NEXT:          store double %mul16, double* %arrayidx, align 8
135;
136entry:
137  br i1 %c.0, label %if.then, label %if.else
138
139if.then:
140  br label %loop.ph
141
142if.else:
143  %ptr.select = select i1 %c.1, double* %C, double* %B
144  br label %loop.ph
145
146loop.ph:
147  %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
148  br label %loop.header
149
150loop.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, double* %A, i64 %iv
154  %v8 = load double, double* %ptr, align 8
155  %mul16 = fmul double 3.0, %v8
156  store double %mul16, double* %arrayidx, align 8
157  %exitcond.not = icmp eq i64 %iv.next, 32000
158  br i1 %exitcond.not, label %exit, label %loop.header
159
160exit:                                             ; preds = %loop.latch
161  ret i32 10
162}
163
164define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %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:    Dependences:
169; CHECK-NEXT:      Unknown:
170; CHECK-NEXT:          %v8 = load double, double* %arrayidx, align 8 ->
171; CHECK-NEXT:          store double %mul16, double* %ptr, align 8
172;
173entry:
174  br i1 %c.0, label %if.then, label %if.else
175
176if.then:
177  br label %loop.ph
178
179if.else:
180  %ptr.select = select i1 %c.1, double* %C, double* %B
181  br label %loop.ph
182
183loop.ph:
184  %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
185  br label %loop.header
186
187loop.header:                                        ; preds = %loop.latch, %entry
188  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
189  %iv.next = add nuw nsw i64 %iv, 1
190  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
191  %v8 = load double, double* %arrayidx, align 8
192  %mul16 = fmul double 3.0, %v8
193  store double %mul16, double* %ptr, align 8
194  %exitcond.not = icmp eq i64 %iv.next, 32000
195  br i1 %exitcond.not, label %exit, label %loop.header
196
197exit:                                             ; preds = %loop.latch
198  ret i32 10
199}
200