1// RUN: mlir-opt %s -affine-loop-invariant-code-motion -split-input-file | FileCheck %s
2
3func @nested_loops_both_having_invariant_code() {
4  %m = alloc() : memref<10xf32>
5  %cf7 = constant 7.0 : f32
6  %cf8 = constant 8.0 : f32
7
8  affine.for %arg0 = 0 to 10 {
9    %v0 = addf %cf7, %cf8 : f32
10    affine.for %arg1 = 0 to 10 {
11      affine.store %v0, %m[%arg0] : memref<10xf32>
12    }
13  }
14
15  // CHECK: %0 = alloc() : memref<10xf32>
16  // CHECK-NEXT: %cst = constant 7.000000e+00 : f32
17  // CHECK-NEXT: %cst_0 = constant 8.000000e+00 : f32
18  // CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
19  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
20  // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
21
22  return
23}
24
25// -----
26
27// The store-load forwarding can see through affine apply's since it relies on
28// dependence information.
29// CHECK-LABEL: func @store_affine_apply
30func @store_affine_apply() -> memref<10xf32> {
31  %cf7 = constant 7.0 : f32
32  %m = alloc() : memref<10xf32>
33  affine.for %arg0 = 0 to 10 {
34      %t0 = affine.apply affine_map<(d1) -> (d1 + 1)>(%arg0)
35      affine.store %cf7, %m[%t0] : memref<10xf32>
36  }
37  return %m : memref<10xf32>
38// CHECK:       %cst = constant 7.000000e+00 : f32
39// CHECK-NEXT:  %0 = alloc() : memref<10xf32>
40// CHECK-NEXT:  affine.for %arg0 = 0 to 10 {
41// CHECK-NEXT:      %1 = affine.apply #map{{[0-9]*}}(%arg0)
42// CHECK-NEXT:      affine.store %cst, %0[%1] : memref<10xf32>
43// CHECK-NEXT:  }
44// CHECK-NEXT:  return %0 : memref<10xf32>
45}
46
47// -----
48
49func @nested_loops_code_invariant_to_both() {
50  %m = alloc() : memref<10xf32>
51  %cf7 = constant 7.0 : f32
52  %cf8 = constant 8.0 : f32
53
54  affine.for %arg0 = 0 to 10 {
55    affine.for %arg1 = 0 to 10 {
56      %v0 = addf %cf7, %cf8 : f32
57    }
58  }
59
60  // CHECK: %0 = alloc() : memref<10xf32>
61  // CHECK-NEXT: %cst = constant 7.000000e+00 : f32
62  // CHECK-NEXT: %cst_0 = constant 8.000000e+00 : f32
63  // CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
64
65  return
66}
67
68// -----
69
70func @single_loop_nothing_invariant() {
71  %m1 = alloc() : memref<10xf32>
72  %m2 = alloc() : memref<10xf32>
73  affine.for %arg0 = 0 to 10 {
74    %v0 = affine.load %m1[%arg0] : memref<10xf32>
75    %v1 = affine.load %m2[%arg0] : memref<10xf32>
76    %v2 = addf %v0, %v1 : f32
77    affine.store %v2, %m1[%arg0] : memref<10xf32>
78  }
79
80  // CHECK: %0 = alloc() : memref<10xf32>
81  // CHECK-NEXT: %1 = alloc() : memref<10xf32>
82  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
83  // CHECK-NEXT: %2 = affine.load %0[%arg0] : memref<10xf32>
84  // CHECK-NEXT: %3 = affine.load %1[%arg0] : memref<10xf32>
85  // CHECK-NEXT: %4 = addf %2, %3 : f32
86  // CHECK-NEXT: affine.store %4, %0[%arg0] : memref<10xf32>
87
88  return
89}
90
91// -----
92
93func @invariant_code_inside_affine_if() {
94  %m = alloc() : memref<10xf32>
95  %cf8 = constant 8.0 : f32
96
97  affine.for %arg0 = 0 to 10 {
98    %t0 = affine.apply affine_map<(d1) -> (d1 + 1)>(%arg0)
99    affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %t0) {
100        %cf9 = addf %cf8, %cf8 : f32
101        affine.store %cf9, %m[%arg0] : memref<10xf32>
102
103    }
104  }
105
106  // CHECK: %0 = alloc() : memref<10xf32>
107  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
108  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
109  // CHECK-NEXT: %1 = affine.apply #map{{[0-9]*}}(%arg0)
110  // CHECK-NEXT: affine.if #set(%arg0, %1) {
111  // CHECK-NEXT: %2 = addf %cst, %cst : f32
112  // CHECK-NEXT: affine.store %2, %0[%arg0] : memref<10xf32>
113  // CHECK-NEXT: }
114
115
116  return
117}
118
119// -----
120
121func @dependent_stores() {
122  %m = alloc() : memref<10xf32>
123  %cf7 = constant 7.0 : f32
124  %cf8 = constant 8.0 : f32
125
126  affine.for %arg0 = 0 to 10 {
127    %v0 = addf %cf7, %cf8 : f32
128    affine.for %arg1 = 0 to 10 {
129      %v1 = addf %cf7, %cf7 : f32
130      affine.store %v1, %m[%arg1] : memref<10xf32>
131      affine.store %v0, %m[%arg0] : memref<10xf32>
132    }
133  }
134
135  // CHECK: %0 = alloc() : memref<10xf32>
136  // CHECK-NEXT: %cst = constant 7.000000e+00 : f32
137  // CHECK-NEXT: %cst_0 = constant 8.000000e+00 : f32
138  // CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
139  // CHECK-NEXT: %2 = addf %cst, %cst : f32
140  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
141
142  // CHECK-NEXT: affine.for %arg1 = 0 to 10 {
143  // CHECK-NEXT:   affine.store %2, %0[%arg1] : memref<10xf32>
144  // CHECK-NEXT:   affine.store %1, %0[%arg0] : memref<10xf32>
145
146  return
147}
148
149// -----
150
151func @independent_stores() {
152  %m = alloc() : memref<10xf32>
153  %cf7 = constant 7.0 : f32
154  %cf8 = constant 8.0 : f32
155
156  affine.for %arg0 = 0 to 10 {
157    %v0 = addf %cf7, %cf8 : f32
158    affine.for %arg1 = 0 to 10 {
159      %v1 = addf %cf7, %cf7 : f32
160      affine.store %v0, %m[%arg0] : memref<10xf32>
161      affine.store %v1, %m[%arg1] : memref<10xf32>
162    }
163  }
164
165  // CHECK: %0 = alloc() : memref<10xf32>
166  // CHECK-NEXT: %cst = constant 7.000000e+00 : f32
167  // CHECK-NEXT: %cst_0 = constant 8.000000e+00 : f32
168  // CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
169  // CHECK-NEXT: %2 = addf %cst, %cst : f32
170  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
171  // CHECK-NEXT:   affine.for %arg1 = 0 to 10 {
172  // CHECK-NEXT:     affine.store %1, %0[%arg0] : memref<10xf32>
173  // CHECK-NEXT:     affine.store %2, %0[%arg1] : memref<10xf32>
174  // CHECK-NEXT:    }
175
176  return
177}
178
179// -----
180
181func @load_dependent_store() {
182  %m = alloc() : memref<10xf32>
183  %cf7 = constant 7.0 : f32
184  %cf8 = constant 8.0 : f32
185
186  affine.for %arg0 = 0 to 10 {
187    %v0 = addf %cf7, %cf8 : f32
188    affine.for %arg1 = 0 to 10 {
189      %v1 = addf %cf7, %cf7 : f32
190      affine.store %v0, %m[%arg1] : memref<10xf32>
191      %v2 = affine.load %m[%arg0] : memref<10xf32>
192    }
193  }
194
195  // CHECK: %0 = alloc() : memref<10xf32>
196  // CHECK-NEXT: %cst = constant 7.000000e+00 : f32
197  // CHECK-NEXT: %cst_0 = constant 8.000000e+00 : f32
198  // CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
199  // CHECK-NEXT: %2 = addf %cst, %cst : f32
200  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
201  // CHECK-NEXT: affine.for %arg1 = 0 to 10 {
202  // CHECK-NEXT:   affine.store %1, %0[%arg1] : memref<10xf32>
203  // CHECK-NEXT:   %3 = affine.load %0[%arg0] : memref<10xf32>
204
205  return
206}
207
208// -----
209
210func @load_after_load() {
211  %m = alloc() : memref<10xf32>
212  %cf7 = constant 7.0 : f32
213  %cf8 = constant 8.0 : f32
214
215  affine.for %arg0 = 0 to 10 {
216    %v0 = addf %cf7, %cf8 : f32
217    affine.for %arg1 = 0 to 10 {
218      %v1 = addf %cf7, %cf7 : f32
219      %v3 = affine.load %m[%arg1] : memref<10xf32>
220      %v2 = affine.load %m[%arg0] : memref<10xf32>
221    }
222  }
223
224  // CHECK: %0 = alloc() : memref<10xf32>
225  // CHECK-NEXT: %cst = constant 7.000000e+00 : f32
226  // CHECK-NEXT: %cst_0 = constant 8.000000e+00 : f32
227  // CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
228  // CHECK-NEXT: %2 = addf %cst, %cst : f32
229  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
230  // CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
231  // CHECK-NEXT: affine.for %arg1 = 0 to 10 {
232  // CHECK-NEXT: %4 = affine.load %0[%arg1] : memref<10xf32>
233
234  return
235}
236
237// -----
238
239func @invariant_affine_if() {
240  %m = alloc() : memref<10xf32>
241  %cf8 = constant 8.0 : f32
242  affine.for %arg0 = 0 to 10 {
243    affine.for %arg1 = 0 to 10 {
244      affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
245          %cf9 = addf %cf8, %cf8 : f32
246          affine.store %cf9, %m[%arg0] : memref<10xf32>
247
248      }
249    }
250  }
251
252  // CHECK: %0 = alloc() : memref<10xf32>
253  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
254  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
255  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
256  // CHECK-NEXT: %1 = addf %cst, %cst : f32
257  // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
258  // CHECK-NEXT: }
259
260
261  return
262}
263
264// -----
265
266func @invariant_affine_if2() {
267  %m = alloc() : memref<10xf32>
268  %cf8 = constant 8.0 : f32
269  affine.for %arg0 = 0 to 10 {
270    affine.for %arg1 = 0 to 10 {
271      affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
272          %cf9 = addf %cf8, %cf8 : f32
273          affine.store %cf9, %m[%arg1] : memref<10xf32>
274
275      }
276    }
277  }
278
279  // CHECK: %0 = alloc() : memref<10xf32>
280  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
281  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
282  // CHECK-NEXT: affine.for %arg1 = 0 to 10 {
283  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
284  // CHECK-NEXT: %1 = addf %cst, %cst : f32
285  // CHECK-NEXT: affine.store %1, %0[%arg1] : memref<10xf32>
286  // CHECK-NEXT: }
287  // CHECK-NEXT: }
288
289
290  return
291}
292
293// -----
294
295func @invariant_affine_nested_if() {
296  %m = alloc() : memref<10xf32>
297  %cf8 = constant 8.0 : f32
298  affine.for %arg0 = 0 to 10 {
299    affine.for %arg1 = 0 to 10 {
300      affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
301          %cf9 = addf %cf8, %cf8 : f32
302          affine.store %cf9, %m[%arg0] : memref<10xf32>
303          affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
304            affine.store %cf9, %m[%arg1] : memref<10xf32>
305          }
306      }
307    }
308  }
309
310  // CHECK: %0 = alloc() : memref<10xf32>
311  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
312  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
313  // CHECK-NEXT: affine.for %arg1 = 0 to 10 {
314  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
315  // CHECK-NEXT: %1 = addf %cst, %cst : f32
316  // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
317  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
318  // CHECK-NEXT: affine.store %1, %0[%arg1] : memref<10xf32>
319  // CHECK-NEXT: }
320  // CHECK-NEXT: }
321  // CHECK-NEXT: }
322
323
324  return
325}
326
327// -----
328
329func @invariant_affine_nested_if_else() {
330  %m = alloc() : memref<10xf32>
331  %cf8 = constant 8.0 : f32
332  affine.for %arg0 = 0 to 10 {
333    affine.for %arg1 = 0 to 10 {
334      affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
335          %cf9 = addf %cf8, %cf8 : f32
336          affine.store %cf9, %m[%arg0] : memref<10xf32>
337          affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
338            affine.store %cf9, %m[%arg0] : memref<10xf32>
339          } else {
340            affine.store %cf9, %m[%arg1] : memref<10xf32>
341          }
342      }
343    }
344  }
345
346  // CHECK: %0 = alloc() : memref<10xf32>
347  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
348  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
349  // CHECK-NEXT: affine.for %arg1 = 0 to 10 {
350  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
351  // CHECK-NEXT: %1 = addf %cst, %cst : f32
352  // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
353  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
354  // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
355  // CHECK-NEXT: } else {
356  // CHECK-NEXT: affine.store %1, %0[%arg1] : memref<10xf32>
357  // CHECK-NEXT: }
358  // CHECK-NEXT: }
359  // CHECK-NEXT: }
360
361
362  return
363}
364
365// -----
366
367func @invariant_affine_nested_if_else2() {
368  %m = alloc() : memref<10xf32>
369  %m2 = alloc() : memref<10xf32>
370  %cf8 = constant 8.0 : f32
371  affine.for %arg0 = 0 to 10 {
372    affine.for %arg1 = 0 to 10 {
373      affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
374          %cf9 = addf %cf8, %cf8 : f32
375          %tload1 = affine.load %m[%arg0] : memref<10xf32>
376          affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
377            affine.store %cf9, %m2[%arg0] : memref<10xf32>
378          } else {
379            %tload2 = affine.load %m[%arg0] : memref<10xf32>
380          }
381      }
382    }
383  }
384
385  // CHECK: %0 = alloc() : memref<10xf32>
386  // CHECK-NEXT: %1 = alloc() : memref<10xf32>
387  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
388  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
389  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
390  // CHECK-NEXT: %2 = addf %cst, %cst : f32
391  // CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
392  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
393  // CHECK-NEXT: affine.store %2, %1[%arg0] : memref<10xf32>
394  // CHECK-NEXT: } else {
395  // CHECK-NEXT: %4 = affine.load %0[%arg0] : memref<10xf32>
396  // CHECK-NEXT: }
397  // CHECK-NEXT: }
398
399
400  return
401}
402
403// -----
404
405func @invariant_affine_nested_if2() {
406  %m = alloc() : memref<10xf32>
407  %cf8 = constant 8.0 : f32
408  affine.for %arg0 = 0 to 10 {
409    affine.for %arg1 = 0 to 10 {
410      affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
411          %cf9 = addf %cf8, %cf8 : f32
412          %v1 = affine.load %m[%arg0] : memref<10xf32>
413          affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
414            %v2 = affine.load %m[%arg0] : memref<10xf32>
415          }
416      }
417    }
418  }
419
420  // CHECK: %0 = alloc() : memref<10xf32>
421  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
422  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
423  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
424  // CHECK-NEXT: %1 = addf %cst, %cst : f32
425  // CHECK-NEXT: %2 = affine.load %0[%arg0] : memref<10xf32>
426  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
427  // CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
428  // CHECK-NEXT: }
429  // CHECK-NEXT: }
430
431
432  return
433}
434
435// -----
436
437func @invariant_affine_for_inside_affine_if() {
438  %m = alloc() : memref<10xf32>
439  %cf8 = constant 8.0 : f32
440  affine.for %arg0 = 0 to 10 {
441    affine.for %arg1 = 0 to 10 {
442      affine.if affine_set<(d0, d1) : (d1 - d0 >= 0)> (%arg0, %arg0) {
443          %cf9 = addf %cf8, %cf8 : f32
444          affine.store %cf9, %m[%arg0] : memref<10xf32>
445          affine.for %arg2 = 0 to 10 {
446            affine.store %cf9, %m[%arg2] : memref<10xf32>
447          }
448      }
449    }
450  }
451
452  // CHECK: %0 = alloc() : memref<10xf32>
453  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
454  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
455  // CHECK-NEXT: affine.for %arg1 = 0 to 10 {
456  // CHECK-NEXT: affine.if #set(%arg0, %arg0) {
457  // CHECK-NEXT: %1 = addf %cst, %cst : f32
458  // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
459  // CHECK-NEXT: affine.for %arg2 = 0 to 10 {
460  // CHECK-NEXT: affine.store %1, %0[%arg2] : memref<10xf32>
461  // CHECK-NEXT: }
462  // CHECK-NEXT: }
463  // CHECK-NEXT: }
464
465
466  return
467}
468
469// -----
470
471func @invariant_constant_and_load() {
472  %m = alloc() : memref<100xf32>
473  %m2 = alloc() : memref<100xf32>
474  affine.for %arg0 = 0 to 5 {
475    %c0 = constant 0 : index
476    %v = affine.load %m2[%c0] : memref<100xf32>
477    affine.store %v, %m[%arg0] : memref<100xf32>
478  }
479
480  // CHECK: %0 = alloc() : memref<100xf32>
481  // CHECK-NEXT: %1 = alloc() : memref<100xf32>
482  // CHECK-NEXT: %c0 = constant 0 : index
483  // CHECK-NEXT: %2 = affine.load %1[%c0] : memref<100xf32>
484  // CHECK-NEXT: affine.for %arg0 = 0 to 5 {
485  // CHECK-NEXT:  affine.store %2, %0[%arg0] : memref<100xf32>
486
487
488  return
489}
490
491// -----
492
493func @nested_load_store_same_memref() {
494  %m = alloc() : memref<10xf32>
495  %cst = constant 8.0 : f32
496  %c0 = constant 0 : index
497   affine.for %arg0 = 0 to 10 {
498    %v0 = affine.load %m[%c0] : memref<10xf32>
499    affine.for %arg1 = 0 to 10 {
500      affine.store %cst, %m[%arg1] : memref<10xf32>
501    }
502  }
503
504  // CHECK: %0 = alloc() : memref<10xf32>
505  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
506  // CHECK-NEXT: %c0 = constant 0 : index
507  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
508  // CHECK-NEXT:  %1 = affine.load %0[%c0] : memref<10xf32>
509  // CHECK-NEXT:   affine.for %arg1 = 0 to 10 {
510  // CHECK-NEXT:    affine.store %cst, %0[%arg1] : memref<10xf32>
511
512
513  return
514}
515
516// -----
517
518func @nested_load_store_same_memref2() {
519  %m = alloc() : memref<10xf32>
520  %cst = constant 8.0 : f32
521  %c0 = constant 0 : index
522   affine.for %arg0 = 0 to 10 {
523     affine.store %cst, %m[%c0] : memref<10xf32>
524      affine.for %arg1 = 0 to 10 {
525        %v0 = affine.load %m[%arg0] : memref<10xf32>
526    }
527  }
528
529  // CHECK: %0 = alloc() : memref<10xf32>
530  // CHECK-NEXT: %cst = constant 8.000000e+00 : f32
531  // CHECK-NEXT: %c0 = constant 0 : index
532  // CHECK-NEXT: affine.for %arg0 = 0 to 10 {
533  // CHECK-NEXT:   affine.store %cst, %0[%c0] : memref<10xf32>
534  // CHECK-NEXT:   %1 = affine.load %0[%arg0] : memref<10xf32>
535
536
537  return
538}
539
540// -----
541
542// CHECK-LABEL:   func @do_not_hoist_dependent_side_effect_free_op
543func @do_not_hoist_dependent_side_effect_free_op(%arg0: memref<10x512xf32>) {
544  %0 = alloca() : memref<1xf32>
545  %cst = constant 8.0 : f32
546  affine.for %i = 0 to 512 {
547    affine.for %j = 0 to 10 {
548      %5 = affine.load %arg0[%i, %j] : memref<10x512xf32>
549      %6 = affine.load %0[0] : memref<1xf32>
550      %add = addf %5, %6 : f32
551      affine.store %add, %0[0] : memref<1xf32>
552    }
553    %3 = affine.load %0[0] : memref<1xf32>
554    %4 = mulf %3, %cst : f32 // It shouldn't be hoisted.
555  }
556  return
557}
558
559// CHECK:       affine.for
560// CHECK-NEXT:    affine.for
561// CHECK-NEXT:      affine.load
562// CHECK-NEXT:      affine.load
563// CHECK-NEXT:      addf
564// CHECK-NEXT:      affine.store
565// CHECK-NEXT:    }
566// CHECK-NEXT:    affine.load
567// CHECK-NEXT:    mulf
568// CHECK-NEXT:  }
569
570// -----
571
572// CHECK-LABEL: func @vector_loop_nothing_invariant
573func @vector_loop_nothing_invariant() {
574  %m1 = alloc() : memref<40xf32>
575  %m2 = alloc() : memref<40xf32>
576  affine.for %arg0 = 0 to 10 {
577    %v0 = affine.vector_load %m1[%arg0*4] : memref<40xf32>, vector<4xf32>
578    %v1 = affine.vector_load %m2[%arg0*4] : memref<40xf32>, vector<4xf32>
579    %v2 = addf %v0, %v1 : vector<4xf32>
580    affine.vector_store %v2, %m1[%arg0*4] : memref<40xf32>, vector<4xf32>
581  }
582  return
583}
584
585// CHECK:       affine.for
586// CHECK-NEXT:    affine.vector_load
587// CHECK-NEXT:    affine.vector_load
588// CHECK-NEXT:    addf
589// CHECK-NEXT:    affine.vector_store
590// CHECK-NEXT:  }
591
592// -----
593
594// CHECK-LABEL: func @vector_loop_all_invariant
595func @vector_loop_all_invariant() {
596  %m1 = alloc() : memref<4xf32>
597  %m2 = alloc() : memref<4xf32>
598  %m3 = alloc() : memref<4xf32>
599  affine.for %arg0 = 0 to 10 {
600    %v0 = affine.vector_load %m1[0] : memref<4xf32>, vector<4xf32>
601    %v1 = affine.vector_load %m2[0] : memref<4xf32>, vector<4xf32>
602    %v2 = addf %v0, %v1 : vector<4xf32>
603    affine.vector_store %v2, %m3[0] : memref<4xf32>, vector<4xf32>
604  }
605  return
606}
607
608// CHECK:       alloc()
609// CHECK-NEXT:  alloc()
610// CHECK-NEXT:  alloc()
611// CHECK-NEXT:  affine.vector_load
612// CHECK-NEXT:  affine.vector_load
613// CHECK-NEXT:  addf
614// CHECK-NEXT:  affine.vector_store
615// CHECK-NEXT:  affine.for
616