• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// RUN: mlir-opt %s -test-memref-dependence-check  -split-input-file -verify-diagnostics | FileCheck %s
2
3// -----
4
5#set0 = affine_set<(d0) : (1 == 0)>
6
7// CHECK-LABEL: func @store_may_execute_before_load() {
8func @store_may_execute_before_load() {
9  %m = alloc() : memref<10xf32>
10  %cf7 = constant 7.0 : f32
11  %c0 = constant 4 : index
12  // There is no dependence from store 0 to load 1 at depth if we take into account
13  // the constraint introduced by the following `affine.if`, which indicates that
14  // the store 0 will never be executed.
15  affine.if #set0(%c0) {
16    affine.for %i0 = 0 to 10 {
17      affine.store %cf7, %m[%i0] : memref<10xf32>
18      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
19      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
20      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
21    }
22  }
23  affine.for %i1 = 0 to 10 {
24    %v0 = affine.load %m[%i1] : memref<10xf32>
25    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
26    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
27    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
28  }
29  return
30}
31
32// -----
33
34// CHECK-LABEL: func @dependent_loops() {
35func @dependent_loops() {
36  %0 = alloc() : memref<10xf32>
37  %cst = constant 7.000000e+00 : f32
38  // There is a dependence from 0 to 1 at depth 1 (common surrounding loops 0)
39  // because the first loop with the store dominates the second scf.
40  affine.for %i0 = 0 to 10 {
41    affine.store %cst, %0[%i0] : memref<10xf32>
42    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
43    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
44    // expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
45  }
46  affine.for %i1 = 0 to 10 {
47    %1 = affine.load %0[%i1] : memref<10xf32>
48    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
49    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
50    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
51  }
52  return
53}
54
55// -----
56// CHECK-LABEL: func @different_memrefs() {
57func @different_memrefs() {
58  %m.a = alloc() : memref<100xf32>
59  %m.b = alloc() : memref<100xf32>
60  %c0 = constant 0 : index
61  %c1 = constant 1.0 : f32
62  affine.store %c1, %m.a[%c0] : memref<100xf32>
63  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
64  // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
65  %v0 = affine.load %m.b[%c0] : memref<100xf32>
66  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
67  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
68  return
69}
70
71// -----
72// CHECK-LABEL: func @store_load_different_elements() {
73func @store_load_different_elements() {
74  %m = alloc() : memref<100xf32>
75  %c0 = constant 0 : index
76  %c1 = constant 1 : index
77  %c7 = constant 7.0 : f32
78  affine.store %c7, %m[%c0] : memref<100xf32>
79  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
80  // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
81  %v0 = affine.load %m[%c1] : memref<100xf32>
82  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
83  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
84  return
85}
86
87// -----
88// CHECK-LABEL: func @load_store_different_elements() {
89func @load_store_different_elements() {
90  %m = alloc() : memref<100xf32>
91  %c0 = constant 0 : index
92  %c1 = constant 1 : index
93  %c7 = constant 7.0 : f32
94  %v0 = affine.load %m[%c1] : memref<100xf32>
95  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
96  // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
97  affine.store %c7, %m[%c0] : memref<100xf32>
98  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
99  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
100  return
101}
102
103// -----
104// CHECK-LABEL: func @store_load_same_element() {
105func @store_load_same_element() {
106  %m = alloc() : memref<100xf32>
107  %c11 = constant 11 : index
108  %c7 = constant 7.0 : f32
109  affine.store %c7, %m[%c11] : memref<100xf32>
110  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
111  // expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
112  %v0 = affine.load %m[%c11] : memref<100xf32>
113  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
114  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
115  return
116}
117
118// -----
119// CHECK-LABEL: func @load_load_same_element() {
120func @load_load_same_element() {
121  %m = alloc() : memref<100xf32>
122  %c11 = constant 11 : index
123  %c7 = constant 7.0 : f32
124  %v0 = affine.load %m[%c11] : memref<100xf32>
125  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
126  // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
127  %v1 = affine.load %m[%c11] : memref<100xf32>
128  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
129  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
130  return
131}
132
133// -----
134// CHECK-LABEL: func @store_load_same_symbol(%arg0: index) {
135func @store_load_same_symbol(%arg0: index) {
136  %m = alloc() : memref<100xf32>
137  %c7 = constant 7.0 : f32
138  affine.store %c7, %m[%arg0] : memref<100xf32>
139  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
140  // expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
141  %v0 = affine.load %m[%arg0] : memref<100xf32>
142  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
143  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
144  return
145}
146
147// -----
148// CHECK-LABEL: func @store_load_different_symbols(%arg0: index, %arg1: index) {
149func @store_load_different_symbols(%arg0: index, %arg1: index) {
150  %m = alloc() : memref<100xf32>
151  %c7 = constant 7.0 : f32
152  affine.store %c7, %m[%arg0] : memref<100xf32>
153  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
154  // expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
155  %v0 = affine.load %m[%arg1] : memref<100xf32>
156  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
157  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
158  return
159}
160
161// -----
162// CHECK-LABEL: func @store_load_diff_element_affine_apply_const() {
163func @store_load_diff_element_affine_apply_const() {
164  %m = alloc() : memref<100xf32>
165  %c1 = constant 1 : index
166  %c8 = constant 8.0 : f32
167  %a0 = affine.apply affine_map<(d0) -> (d0)> (%c1)
168  affine.store %c8, %m[%a0] : memref<100xf32>
169  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
170  // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
171  %a1 = affine.apply affine_map<(d0) -> (d0 + 1)> (%c1)
172  %v0 = affine.load %m[%a1] : memref<100xf32>
173  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
174  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
175  return
176}
177
178// -----
179// CHECK-LABEL: func @store_load_same_element_affine_apply_const() {
180func @store_load_same_element_affine_apply_const() {
181  %m = alloc() : memref<100xf32>
182  %c7 = constant 7.0 : f32
183  %c9 = constant 9 : index
184  %c11 = constant 11 : index
185  %a0 = affine.apply affine_map<(d0) -> (d0 + 1)> (%c9)
186  affine.store %c7, %m[%a0] : memref<100xf32>
187  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
188  // expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
189  %a1 = affine.apply affine_map<(d0) -> (d0 - 1)> (%c11)
190  %v0 = affine.load %m[%a1] : memref<100xf32>
191  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
192  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
193  return
194}
195
196// -----
197// CHECK-LABEL: func @store_load_affine_apply_symbol(%arg0: index) {
198func @store_load_affine_apply_symbol(%arg0: index) {
199  %m = alloc() : memref<100xf32>
200  %c7 = constant 7.0 : f32
201  %a0 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
202  affine.store %c7, %m[%a0] : memref<100xf32>
203  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
204  // expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
205  %a1 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
206  %v0 = affine.load %m[%a1] : memref<100xf32>
207  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
208  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
209  return
210}
211
212// -----
213// CHECK-LABEL: func @store_load_affine_apply_symbol_offset(%arg0: index) {
214func @store_load_affine_apply_symbol_offset(%arg0: index) {
215  %m = alloc() : memref<100xf32>
216  %c7 = constant 7.0 : f32
217  %a0 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
218  affine.store %c7, %m[%a0] : memref<100xf32>
219  // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
220  // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
221  %a1 = affine.apply affine_map<(d0) -> (d0 + 1)> (%arg0)
222  %v0 = affine.load %m[%a1] : memref<100xf32>
223  // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
224  // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
225  return
226}
227
228// -----
229// CHECK-LABEL: func @store_range_load_after_range() {
230func @store_range_load_after_range() {
231  %m = alloc() : memref<100xf32>
232  %c7 = constant 7.0 : f32
233  %c10 = constant 10 : index
234  affine.for %i0 = 0 to 10 {
235    %a0 = affine.apply affine_map<(d0) -> (d0)> (%i0)
236    affine.store %c7, %m[%a0] : memref<100xf32>
237    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
238    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
239    // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
240    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
241    %a1 = affine.apply affine_map<(d0) -> (d0)> (%c10)
242    %v0 = affine.load %m[%a1] : memref<100xf32>
243    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
244    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
245    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
246    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
247  }
248  return
249}
250
251// -----
252// CHECK-LABEL: func @store_load_func_symbol(%arg0: index, %arg1: index) {
253func @store_load_func_symbol(%arg0: index, %arg1: index) {
254  %m = alloc() : memref<100xf32>
255  %c7 = constant 7.0 : f32
256  %c10 = constant 10 : index
257  affine.for %i0 = 0 to %arg1 {
258    %a0 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
259    affine.store %c7, %m[%a0] : memref<100xf32>
260    // expected-remark@above {{dependence from 0 to 0 at depth 1 = [1, +inf]}}
261    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
262    // expected-remark@above {{dependence from 0 to 1 at depth 1 = [1, +inf]}}
263    // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
264    %a1 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
265    %v0 = affine.load %m[%a1] : memref<100xf32>
266    // expected-remark@above {{dependence from 1 to 0 at depth 1 = [1, +inf]}}
267    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
268    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
269    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
270  }
271  return
272}
273
274// -----
275// CHECK-LABEL: func @store_range_load_last_in_range() {
276func @store_range_load_last_in_range() {
277  %m = alloc() : memref<100xf32>
278  %c7 = constant 7.0 : f32
279  %c10 = constant 10 : index
280  affine.for %i0 = 0 to 10 {
281    %a0 = affine.apply affine_map<(d0) -> (d0)> (%i0)
282    // For dependence from 0 to 1, we do not have a loop carried dependence
283    // because only the final write in the loop accesses the same element as the
284    // load, so this dependence appears only at depth 2 (loop independent).
285    affine.store %c7, %m[%a0] : memref<100xf32>
286    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
287    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
288    // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
289    // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
290    %a1 = affine.apply affine_map<(d0) -> (d0 - 1)> (%c10)
291    // For dependence from 1 to 0, we have write-after-read (WAR) dependences
292    // for all loads in the loop to the store on the last iteration.
293    %v0 = affine.load %m[%a1] : memref<100xf32>
294    // expected-remark@above {{dependence from 1 to 0 at depth 1 = [1, 9]}}
295    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
296    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
297    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
298  }
299  return
300}
301
302// -----
303// CHECK-LABEL: func @store_range_load_before_range() {
304func @store_range_load_before_range() {
305  %m = alloc() : memref<100xf32>
306  %c7 = constant 7.0 : f32
307  %c0 = constant 0 : index
308  affine.for %i0 = 1 to 11 {
309    %a0 = affine.apply affine_map<(d0) -> (d0)> (%i0)
310    affine.store %c7, %m[%a0] : memref<100xf32>
311    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
312    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
313    // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
314    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
315    %a1 = affine.apply affine_map<(d0) -> (d0)> (%c0)
316    %v0 = affine.load %m[%a1] : memref<100xf32>
317    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
318    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
319    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
320    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
321  }
322  return
323}
324
325// -----
326// CHECK-LABEL: func @store_range_load_first_in_range() {
327func @store_range_load_first_in_range() {
328  %m = alloc() : memref<100xf32>
329  %c7 = constant 7.0 : f32
330  %c0 = constant 0 : index
331  affine.for %i0 = 1 to 11 {
332    %a0 = affine.apply affine_map<(d0) -> (d0)> (%i0)
333    // Dependence from 0 to 1 at depth 1 is a range because all loads at
334    // constant index zero are reads after first store at index zero during
335    // first iteration of the scf.
336    affine.store %c7, %m[%a0] : memref<100xf32>
337    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
338    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
339    // expected-remark@above {{dependence from 0 to 1 at depth 1 = [1, 9]}}
340    // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
341    %a1 = affine.apply affine_map<(d0) -> (d0 + 1)> (%c0)
342    %v0 = affine.load %m[%a1] : memref<100xf32>
343    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
344    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
345    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
346    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
347  }
348  return
349}
350
351// -----
352// CHECK-LABEL: func @store_plus_3() {
353func @store_plus_3() {
354  %m = alloc() : memref<100xf32>
355  %c7 = constant 7.0 : f32
356  affine.for %i0 = 1 to 11 {
357    %a0 = affine.apply affine_map<(d0) -> (d0 + 3)> (%i0)
358    affine.store %c7, %m[%a0] : memref<100xf32>
359    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
360    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
361    // expected-remark@above {{dependence from 0 to 1 at depth 1 = [3, 3]}}
362    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
363    %a1 = affine.apply affine_map<(d0) -> (d0)> (%i0)
364    %v0 = affine.load %m[%a1] : memref<100xf32>
365    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
366    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
367    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
368    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
369  }
370  return
371}
372
373// -----
374// CHECK-LABEL: func @load_minus_2() {
375func @load_minus_2() {
376  %m = alloc() : memref<100xf32>
377  %c7 = constant 7.0 : f32
378  affine.for %i0 = 2 to 11 {
379    %a0 = affine.apply affine_map<(d0) -> (d0)> (%i0)
380    affine.store %c7, %m[%a0] : memref<100xf32>
381    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
382    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
383    // expected-remark@above {{dependence from 0 to 1 at depth 1 = [2, 2]}}
384    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
385    %a1 = affine.apply affine_map<(d0) -> (d0 - 2)> (%i0)
386    %v0 = affine.load %m[%a1] : memref<100xf32>
387    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
388    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
389    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
390    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
391  }
392  return
393}
394
395// -----
396// CHECK-LABEL: func @perfectly_nested_loops_loop_independent() {
397func @perfectly_nested_loops_loop_independent() {
398  %m = alloc() : memref<10x10xf32>
399  %c7 = constant 7.0 : f32
400  affine.for %i0 = 0 to 11 {
401    affine.for %i1 = 0 to 11 {
402      // Dependence from access 0 to 1 is loop independent at depth = 3.
403      %a00 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
404      %a01 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
405      affine.store %c7, %m[%a00, %a01] : memref<10x10xf32>
406      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
407      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
408      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
409      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
410      // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
411      // expected-remark@above {{dependence from 0 to 1 at depth 3 = true}}
412      %a10 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
413      %a11 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
414      %v0 = affine.load %m[%a10, %a11] : memref<10x10xf32>
415      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
416      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
417      // expected-remark@above {{dependence from 1 to 0 at depth 3 = false}}
418      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
419      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
420      // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
421    }
422  }
423  return
424}
425
426// -----
427// CHECK-LABEL: func @perfectly_nested_loops_loop_carried_at_depth1() {
428func @perfectly_nested_loops_loop_carried_at_depth1() {
429  %m = alloc() : memref<10x10xf32>
430  %c7 = constant 7.0 : f32
431  affine.for %i0 = 0 to 9 {
432    affine.for %i1 = 0 to 9 {
433      // Dependence from access 0 to 1 is loop carried at depth 1.
434      %a00 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
435      %a01 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
436      affine.store %c7, %m[%a00, %a01] : memref<10x10xf32>
437      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
438      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
439      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
440      // expected-remark@above {{dependence from 0 to 1 at depth 1 = [2, 2][0, 0]}}
441      // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
442      // expected-remark@above {{dependence from 0 to 1 at depth 3 = false}}
443      %a10 = affine.apply affine_map<(d0, d1) -> (d0 - 2)> (%i0, %i1)
444      %a11 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
445      %v0 = affine.load %m[%a10, %a11] : memref<10x10xf32>
446      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
447      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
448      // expected-remark@above {{dependence from 1 to 0 at depth 3 = false}}
449      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
450      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
451      // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
452    }
453  }
454  return
455}
456
457// -----
458// CHECK-LABEL: func @perfectly_nested_loops_loop_carried_at_depth2() {
459func @perfectly_nested_loops_loop_carried_at_depth2() {
460  %m = alloc() : memref<10x10xf32>
461  %c7 = constant 7.0 : f32
462  affine.for %i0 = 0 to 10 {
463    affine.for %i1 = 0 to 10 {
464      // Dependence from access 0 to 1 is loop carried at depth 2.
465      %a00 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
466      %a01 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
467      affine.store %c7, %m[%a00, %a01] : memref<10x10xf32>
468      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
469      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
470      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
471      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
472      // expected-remark@above {{dependence from 0 to 1 at depth 2 = [0, 0][3, 3]}}
473      // expected-remark@above {{dependence from 0 to 1 at depth 3 = false}}
474      %a10 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
475      %a11 = affine.apply affine_map<(d0, d1) -> (d1 - 3)> (%i0, %i1)
476      %v0 = affine.load %m[%a10, %a11] : memref<10x10xf32>
477      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
478      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
479      // expected-remark@above {{dependence from 1 to 0 at depth 3 = false}}
480      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
481      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
482      // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
483    }
484  }
485  return
486}
487
488// -----
489// CHECK-LABEL: func @one_common_loop() {
490func @one_common_loop() {
491  %m = alloc() : memref<10x10xf32>
492  %c7 = constant 7.0 : f32
493  // There is a loop-independent dependence from access 0 to 1 at depth 2.
494  affine.for %i0 = 0 to 10 {
495    affine.for %i1 = 0 to 10 {
496      %a00 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
497      %a01 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
498      affine.store %c7, %m[%a00, %a01] : memref<10x10xf32>
499      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
500      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
501      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
502      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
503      // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
504    }
505    affine.for %i2 = 0 to 9 {
506      %a10 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i2)
507      %a11 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i2)
508      %v0 = affine.load %m[%a10, %a11] : memref<10x10xf32>
509      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
510      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
511      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
512      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
513      // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
514    }
515  }
516  return
517}
518
519// -----
520// CHECK-LABEL: func @dependence_cycle() {
521func @dependence_cycle() {
522  %m.a = alloc() : memref<100xf32>
523  %m.b = alloc() : memref<100xf32>
524
525  // Dependences:
526  // *) loop-independent dependence from access 1 to 2 at depth 2.
527  // *) loop-carried dependence from access 3 to 0 at depth 1.
528  affine.for %i0 = 0 to 9 {
529    %a0 = affine.apply affine_map<(d0) -> (d0)> (%i0)
530    %v0 = affine.load %m.a[%a0] : memref<100xf32>
531    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
532    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
533    // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
534    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
535    // expected-remark@above {{dependence from 0 to 2 at depth 1 = false}}
536    // expected-remark@above {{dependence from 0 to 2 at depth 2 = false}}
537    // expected-remark@above {{dependence from 0 to 3 at depth 1 = false}}
538    // expected-remark@above {{dependence from 0 to 3 at depth 2 = false}}
539    %a1 = affine.apply affine_map<(d0) -> (d0)> (%i0)
540    affine.store %v0, %m.b[%a1] : memref<100xf32>
541    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
542    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
543    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
544    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
545    // expected-remark@above {{dependence from 1 to 2 at depth 1 = false}}
546    // expected-remark@above {{dependence from 1 to 2 at depth 2 = true}}
547    // expected-remark@above {{dependence from 1 to 3 at depth 1 = false}}
548    // expected-remark@above {{dependence from 1 to 3 at depth 2 = false}}
549    %a2 = affine.apply affine_map<(d0) -> (d0)> (%i0)
550    %v1 = affine.load %m.b[%a2] : memref<100xf32>
551    // expected-remark@above {{dependence from 2 to 0 at depth 1 = false}}
552    // expected-remark@above {{dependence from 2 to 0 at depth 2 = false}}
553    // expected-remark@above {{dependence from 2 to 1 at depth 1 = false}}
554    // expected-remark@above {{dependence from 2 to 1 at depth 2 = false}}
555    // expected-remark@above {{dependence from 2 to 2 at depth 1 = false}}
556    // expected-remark@above {{dependence from 2 to 2 at depth 2 = false}}
557    // expected-remark@above {{dependence from 2 to 3 at depth 1 = false}}
558    // expected-remark@above {{dependence from 2 to 3 at depth 2 = false}}
559    %a3 = affine.apply affine_map<(d0) -> (d0 + 1)> (%i0)
560    affine.store %v1, %m.a[%a3] : memref<100xf32>
561    // expected-remark@above {{dependence from 3 to 0 at depth 1 = [1, 1]}}
562    // expected-remark@above {{dependence from 3 to 0 at depth 2 = false}}
563    // expected-remark@above {{dependence from 3 to 1 at depth 1 = false}}
564    // expected-remark@above {{dependence from 3 to 1 at depth 2 = false}}
565    // expected-remark@above {{dependence from 3 to 2 at depth 1 = false}}
566    // expected-remark@above {{dependence from 3 to 2 at depth 2 = false}}
567    // expected-remark@above {{dependence from 3 to 3 at depth 1 = false}}
568    // expected-remark@above {{dependence from 3 to 3 at depth 2 = false}}
569  }
570  return
571}
572
573// -----
574// CHECK-LABEL: func @negative_and_positive_direction_vectors(%arg0: index, %arg1: index) {
575func @negative_and_positive_direction_vectors(%arg0: index, %arg1: index) {
576  %m = alloc() : memref<10x10xf32>
577  %c7 = constant 7.0 : f32
578  affine.for %i0 = 0 to %arg0 {
579    affine.for %i1 = 0 to %arg1 {
580      %a00 = affine.apply affine_map<(d0, d1) -> (d0 - 1)> (%i0, %i1)
581      %a01 = affine.apply affine_map<(d0, d1) -> (d1 + 1)> (%i0, %i1)
582      %v0 = affine.load %m[%a00, %a01] : memref<10x10xf32>
583      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
584      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
585      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
586      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
587      // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
588      // expected-remark@above {{dependence from 0 to 1 at depth 3 = false}}
589      %a10 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
590      %a11 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
591      affine.store %c7, %m[%a10, %a11] : memref<10x10xf32>
592      // expected-remark@above {{dependence from 1 to 0 at depth 1 = [1, 1][-1, -1]}}
593      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
594      // expected-remark@above {{dependence from 1 to 0 at depth 3 = false}}
595      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
596      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
597      // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
598    }
599  }
600  return
601}
602
603// -----
604// CHECK-LABEL: func @war_raw_waw_deps() {
605func @war_raw_waw_deps() {
606  %m = alloc() : memref<100xf32>
607  %c7 = constant 7.0 : f32
608  affine.for %i0 = 0 to 10 {
609    affine.for %i1 = 0 to 10 {
610      %a0 = affine.apply affine_map<(d0) -> (d0 + 1)> (%i1)
611      %v0 = affine.load %m[%a0] : memref<100xf32>
612      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
613      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
614      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
615      // expected-remark@above {{dependence from 0 to 1 at depth 1 = [1, 9][1, 1]}}
616      // expected-remark@above {{dependence from 0 to 1 at depth 2 = [0, 0][1, 1]}}
617      // expected-remark@above {{dependence from 0 to 1 at depth 3 = false}}
618      %a1 = affine.apply affine_map<(d0) -> (d0)> (%i1)
619      affine.store %c7, %m[%a1] : memref<100xf32>
620      // expected-remark@above {{dependence from 1 to 0 at depth 1 = [1, 9][-1, -1]}}
621      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
622      // expected-remark@above {{dependence from 1 to 0 at depth 3 = false}}
623      // expected-remark@above {{dependence from 1 to 1 at depth 1 = [1, 9][0, 0]}}
624      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
625      // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
626    }
627  }
628  return
629}
630
631// -----
632// CHECK-LABEL: func @mod_deps() {
633func @mod_deps() {
634  %m = alloc() : memref<100xf32>
635  %c7 = constant 7.0 : f32
636  affine.for %i0 = 0 to 10 {
637    %a0 = affine.apply affine_map<(d0) -> (d0 mod 2)> (%i0)
638    // Results are conservative here since we currently don't have a way to
639    // represent strided sets in FlatAffineConstraints.
640    %v0 = affine.load %m[%a0] : memref<100xf32>
641    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
642    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
643    // expected-remark@above {{dependence from 0 to 1 at depth 1 = [1, 9]}}
644    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
645    %a1 = affine.apply affine_map<(d0) -> ( (d0 + 1) mod 2)> (%i0)
646    affine.store %c7, %m[%a1] : memref<100xf32>
647    // expected-remark@above {{dependence from 1 to 0 at depth 1 = [1, 9]}}
648    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
649    // expected-remark@above {{dependence from 1 to 1 at depth 1 = [2, 9]}}
650    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
651  }
652  return
653}
654
655// -----
656// CHECK-LABEL: func @loop_nest_depth() {
657func @loop_nest_depth() {
658  %0 = alloc() : memref<100x100xf32>
659  %c7 = constant 7.0 : f32
660
661  affine.for %i0 = 0 to 128 {
662    affine.for %i1 = 0 to 8 {
663      affine.store %c7, %0[%i0, %i1] : memref<100x100xf32>
664      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
665      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
666      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
667      // expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
668    }
669  }
670  affine.for %i2 = 0 to 8 {
671    affine.for %i3 = 0 to 8 {
672      affine.for %i4 = 0 to 8 {
673        affine.for %i5 = 0 to 16 {
674          %8 = affine.apply affine_map<(d0, d1) -> (d0 * 16 + d1)>(%i4, %i5)
675          %9 = affine.load %0[%8, %i3] : memref<100x100xf32>
676          // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
677          // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
678          // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
679          // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
680          // expected-remark@above {{dependence from 1 to 1 at depth 4 = false}}
681          // expected-remark@above {{dependence from 1 to 1 at depth 5 = false}}
682        }
683      }
684    }
685  }
686  return
687}
688
689// -----
690// Test case to exercise sanity when flattening multiple expressions involving
691// mod/div's successively.
692// CHECK-LABEL: func @mod_div_3d() {
693func @mod_div_3d() {
694  %M = alloc() : memref<2x2x2xi32>
695  %c0 = constant 0 : i32
696  affine.for %i0 = 0 to 8 {
697    affine.for %i1 = 0 to 8 {
698      affine.for %i2 = 0 to 8 {
699        %idx0 = affine.apply affine_map<(d0, d1, d2) -> (d0 floordiv 4)> (%i0, %i1, %i2)
700        %idx1 = affine.apply affine_map<(d0, d1, d2) -> (d1 mod 2)> (%i0, %i1, %i2)
701        %idx2 = affine.apply affine_map<(d0, d1, d2) -> (d2 floordiv 4)> (%i0, %i1, %i2)
702        affine.store %c0, %M[%idx0, %idx1, %idx2] : memref<2 x 2 x 2 x i32>
703        // expected-remark@above {{dependence from 0 to 0 at depth 1 = [1, 3][-7, 7][-3, 3]}}
704        // expected-remark@above {{dependence from 0 to 0 at depth 2 = [0, 0][2, 7][-3, 3]}}
705        // expected-remark@above {{dependence from 0 to 0 at depth 3 = [0, 0][0, 0][1, 3]}}
706        // expected-remark@above {{dependence from 0 to 0 at depth 4 = false}}
707      }
708    }
709  }
710  return
711}
712
713// -----
714// This test case arises in the context of a 6-d to 2-d reshape.
715// CHECK-LABEL: func @delinearize_mod_floordiv
716func @delinearize_mod_floordiv() {
717  %c0 = constant 0 : index
718  %val = constant 0 : i32
719  %in = alloc() : memref<2x2x3x3x16x1xi32>
720  %out = alloc() : memref<64x9xi32>
721
722  affine.for %i0 = 0 to 2 {
723    affine.for %i1 = 0 to 2 {
724      affine.for %i2 = 0 to 3 {
725        affine.for %i3 = 0 to 3 {
726          affine.for %i4 = 0 to 16 {
727            affine.for %i5 = 0 to 1 {
728              affine.store %val, %in[%i0, %i1, %i2, %i3, %i4, %i5] : memref<2x2x3x3x16x1xi32>
729// expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
730// expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
731// expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
732// expected-remark@above {{dependence from 0 to 0 at depth 4 = false}}
733// expected-remark@above {{dependence from 0 to 0 at depth 5 = false}}
734// expected-remark@above {{dependence from 0 to 0 at depth 6 = false}}
735// expected-remark@above {{dependence from 0 to 0 at depth 7 = false}}
736// expected-remark@above {{dependence from 0 to 1 at depth 1 = true}}
737// expected-remark@above {{dependence from 0 to 2 at depth 1 = false}}
738            }
739          }
740        }
741      }
742    }
743  }
744
745  affine.for %ii = 0 to 64 {
746    affine.for %jj = 0 to 9 {
747      %a0 = affine.apply affine_map<(d0, d1) -> (d0 * (9 * 1024) + d1 * 128)> (%ii, %jj)
748      %a10 = affine.apply affine_map<(d0) ->
749        (d0 floordiv (2 * 3 * 3 * 128 * 128))> (%a0)
750      %a11 = affine.apply affine_map<(d0) ->
751        ((d0 mod 294912) floordiv (3 * 3 * 128 * 128))> (%a0)
752      %a12 = affine.apply affine_map<(d0) ->
753        ((((d0 mod 294912) mod 147456) floordiv 1152) floordiv 8)> (%a0)
754      %a13 = affine.apply affine_map<(d0) ->
755        ((((d0 mod 294912) mod 147456) mod 1152) floordiv 384)> (%a0)
756      %a14 = affine.apply affine_map<(d0) ->
757        (((((d0 mod 294912) mod 147456) mod 1152) mod 384) floordiv 128)> (%a0)
758      %a15 = affine.apply affine_map<(d0) ->
759        ((((((d0 mod 294912) mod 147456) mod 1152) mod 384) mod 128)
760          floordiv 128)> (%a0)
761      %v0 = affine.load %in[%a10, %a11, %a13, %a14, %a12, %a15] : memref<2x2x3x3x16x1xi32>
762// expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
763// expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
764// expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
765// expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
766// expected-remark@above {{dependence from 1 to 2 at depth 1 = false}}
767// expected-remark@above {{dependence from 1 to 2 at depth 2 = false}}
768// expected-remark@above {{dependence from 1 to 2 at depth 3 = false}}
769// TODO: the dep tester shouldn't be printing out these messages
770// below; they are redundant.
771      affine.store %v0, %out[%ii, %jj] : memref<64x9xi32>
772// expected-remark@above {{dependence from 2 to 0 at depth 1 = false}}
773// expected-remark@above {{dependence from 2 to 1 at depth 1 = false}}
774// expected-remark@above {{dependence from 2 to 1 at depth 2 = false}}
775// expected-remark@above {{dependence from 2 to 1 at depth 3 = false}}
776// expected-remark@above {{dependence from 2 to 2 at depth 1 = false}}
777// expected-remark@above {{dependence from 2 to 2 at depth 2 = false}}
778// expected-remark@above {{dependence from 2 to 2 at depth 3 = false}}
779    }
780  }
781  return
782}
783
784// TODO: add more test cases involving mod's/div's.
785
786// -----
787
788// Load and store ops access the same elements in strided scf.
789// CHECK-LABEL: func @strided_loop_with_dependence_at_depth2
790func @strided_loop_with_dependence_at_depth2() {
791  %0 = alloc() : memref<10xf32>
792  %cf0 = constant 0.0 : f32
793  affine.for %i0 = 0 to 8 step 2 {
794    affine.store %cf0, %0[%i0] : memref<10xf32>
795    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
796    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
797    // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
798    // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
799    %v0 = affine.load %0[%i0] : memref<10xf32>
800    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
801    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
802    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
803    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
804  }
805  return
806}
807
808// -----
809
810// Load and store ops access alternating memref elements: no dependence.
811// CHECK-LABEL: func @strided_loop_with_no_dependence
812func @strided_loop_with_no_dependence() {
813  %0 = alloc() : memref<10xf32>
814  %cf0 = constant 0.0 : f32
815  affine.for %i0 = 0 to 8 step 2 {
816    %a0 = affine.apply affine_map<(d0) -> (d0 + 1)>(%i0)
817    affine.store %cf0, %0[%a0] : memref<10xf32>
818    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
819    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
820    // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
821    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
822    %v0 = affine.load %0[%i0] : memref<10xf32>
823    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
824    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
825    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
826    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
827  }
828  return
829}
830
831// -----
832
833// Affine.Store op accesses memref elements at offset causing loop-carried dependence.
834// CHECK-LABEL: func @strided_loop_with_loop_carried_dependence_at_depth1
835func @strided_loop_with_loop_carried_dependence_at_depth1() {
836  %0 = alloc() : memref<10xf32>
837  %cf0 = constant 0.0 : f32
838  affine.for %i0 = 0 to 8 step 2 {
839    %a0 = affine.apply affine_map<(d0) -> (d0 + 4)>(%i0)
840    affine.store %cf0, %0[%a0] : memref<10xf32>
841    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
842    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
843    // expected-remark@above {{dependence from 0 to 1 at depth 1 = [4, 4]}}
844    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
845    %v0 = affine.load %0[%i0] : memref<10xf32>
846    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
847    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
848    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
849    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
850  }
851  return
852}
853
854// -----
855
856// Test that the loop carried dependence from load to store on '%i0' is
857// properly computed when the load and store are at different loop depths.
858// CHECK-LABEL: func @test_dep_store_depth1_load_depth2
859func @test_dep_store_depth1_load_depth2() {
860  %0 = alloc() : memref<100xf32>
861  %cst = constant 7.000000e+00 : f32
862  affine.for %i0 = 0 to 10 {
863    %a0 = affine.apply affine_map<(d0) -> (d0 - 1)>(%i0)
864    affine.store %cst, %0[%a0] : memref<100xf32>
865    // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
866    // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
867    // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
868    // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
869    affine.for %i1 = affine_map<(d0) -> (d0)>(%i0) to affine_map<(d0) -> (d0 + 1)>(%i0) {
870      %1 = affine.load %0[%i1] : memref<100xf32>
871      // expected-remark@above {{dependence from 1 to 0 at depth 1 = [1, 1]}}
872      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
873      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
874      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
875      // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
876    }
877  }
878  return
879}
880
881// -----
882
883// Test that the loop carried dependence from store to load on '%i0' is
884// properly computed when the load and store are at different loop depths.
885// CHECK-LABEL: func @test_dep_store_depth2_load_depth1
886func @test_dep_store_depth2_load_depth1() {
887  %0 = alloc() : memref<100xf32>
888  %cst = constant 7.000000e+00 : f32
889  affine.for %i0 = 0 to 10 {
890    affine.for %i1 = affine_map<(d0) -> (d0)>(%i0) to affine_map<(d0) -> (d0 + 1)>(%i0) {
891      affine.store %cst, %0[%i1] : memref<100xf32>
892      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
893      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
894      // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
895      // expected-remark@above {{dependence from 0 to 1 at depth 1 = [2, 2]}}
896      // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
897    }
898    %a0 = affine.apply affine_map<(d0) -> (d0 - 2)>(%i0)
899    %1 = affine.load %0[%a0] : memref<100xf32>
900    // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
901    // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
902    // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
903    // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
904  }
905  return
906}
907
908// -----
909
910// Test the case that `affine.if` changes the domain for both load/store simultaneously.
911#set = affine_set<(d0): (d0 - 50 >= 0)>
912
913// CHECK-LABEL: func @test_affine_for_if_same_block() {
914func @test_affine_for_if_same_block() {
915  %0 = alloc() : memref<100xf32>
916  %cf7 = constant 7.0 : f32
917
918  affine.for %i0 = 0 to 100 {
919    affine.if #set(%i0) {
920      %1 = affine.load %0[%i0] : memref<100xf32>
921      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
922      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
923      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
924      // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
925      affine.store %cf7, %0[%i0] : memref<100xf32>
926      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
927      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
928      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
929      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
930    }
931  }
932
933  return
934}
935
936// -----
937
938// Test the case that the domain that load/store access is completedly separated by `affine.if`.
939#set = affine_set<(d0): (d0 - 50 >= 0)>
940
941// CHECK-LABEL: func @test_affine_for_if_separated() {
942func @test_affine_for_if_separated() {
943  %0 = alloc() : memref<100xf32>
944  %cf7 = constant 7.0 : f32
945
946  affine.for %i0 = 0 to 10 {
947    affine.if #set(%i0) {
948      %1 = affine.load %0[%i0] : memref<100xf32>
949      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
950      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
951      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
952      // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
953    } else {
954      affine.store %cf7, %0[%i0] : memref<100xf32>
955      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
956      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
957      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
958      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
959    }
960  }
961
962  return
963}
964
965// -----
966
967// Test the case that the domain that load/store access has non-empty union set.
968#set1 = affine_set<(d0): (  d0 - 25 >= 0)>
969#set2 = affine_set<(d0): (- d0 + 75 >= 0)>
970
971// CHECK-LABEL: func @test_affine_for_if_partially_joined() {
972func @test_affine_for_if_partially_joined() {
973  %0 = alloc() : memref<100xf32>
974  %cf7 = constant 7.0 : f32
975
976  affine.for %i0 = 0 to 100 {
977    affine.if #set1(%i0) {
978      %1 = affine.load %0[%i0] : memref<100xf32>
979      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
980      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
981      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
982      // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
983    }
984    affine.if #set2(%i0) {
985      affine.store %cf7, %0[%i0] : memref<100xf32>
986      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
987      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
988      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
989      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
990    }
991  }
992
993  return
994}
995
996// -----
997
998// Test whether interleaved affine.for/affine.if can be properly handled.
999#set1 = affine_set<(d0): (d0 - 50 >= 0)>
1000#set2 = affine_set<(d0, d1): (d0 - 75 >= 0, d1 - 50 >= 0)>
1001
1002// CHECK-LABEL: func @test_interleaved_affine_for_if() {
1003func @test_interleaved_affine_for_if() {
1004  %0 = alloc() : memref<100x100xf32>
1005  %cf7 = constant 7.0 : f32
1006
1007  affine.for %i0 = 0 to 100 {
1008    affine.if #set1(%i0) {
1009      affine.for %i1 = 0 to 100 {
1010        %1 = affine.load %0[%i0, %i1] : memref<100x100xf32>
1011        // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
1012        // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
1013        // expected-remark@above {{dependence from 0 to 0 at depth 3 = false}}
1014        // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
1015        // expected-remark@above {{dependence from 0 to 1 at depth 2 = false}}
1016        // expected-remark@above {{dependence from 0 to 1 at depth 3 = true}}
1017
1018        affine.if #set2(%i0, %i1) {
1019          affine.store %cf7, %0[%i0, %i1] : memref<100x100xf32>
1020          // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
1021          // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
1022          // expected-remark@above {{dependence from 1 to 0 at depth 3 = false}}
1023          // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
1024          // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
1025          // expected-remark@above {{dependence from 1 to 1 at depth 3 = false}}
1026        }
1027      }
1028    }
1029  }
1030
1031  return
1032}
1033
1034// -----
1035
1036// Test whether symbols can be handled .
1037#set1 = affine_set<(d0)[s0]: (  d0 - s0 floordiv 2 >= 0)>
1038#set2 = affine_set<(d0):     (- d0 +            51 >= 0)>
1039
1040// CHECK-LABEL: func @test_interleaved_affine_for_if() {
1041func @test_interleaved_affine_for_if() {
1042  %0 = alloc() : memref<101xf32>
1043  %c0 = constant 0 : index
1044  %N = dim %0, %c0 : memref<101xf32>
1045  %cf7 = constant 7.0 : f32
1046
1047  affine.for %i0 = 0 to 101 {
1048    affine.if #set1(%i0)[%N] {
1049      %1 = affine.load %0[%i0] : memref<101xf32>
1050      // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}}
1051      // expected-remark@above {{dependence from 0 to 0 at depth 2 = false}}
1052      // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}}
1053      // expected-remark@above {{dependence from 0 to 1 at depth 2 = true}}
1054    }
1055
1056    affine.if #set2(%i0) {
1057      affine.store %cf7, %0[%i0] : memref<101xf32>
1058      // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}}
1059      // expected-remark@above {{dependence from 1 to 0 at depth 2 = false}}
1060      // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}}
1061      // expected-remark@above {{dependence from 1 to 1 at depth 2 = false}}
1062    }
1063  }
1064
1065  return
1066}
1067