xref: /llvm-project/mlir/test/Dialect/Affine/loop-fusion-slice-computation.mlir (revision 608a663c8ee485c42637d021d554c8d264d556b1)
1// RUN: mlir-opt %s -test-loop-fusion=test-loop-fusion-slice-computation -split-input-file -verify-diagnostics | FileCheck %s
2
3// -----
4
5// CHECK-LABEL: func @slice_depth1_loop_nest() {
6func.func @slice_depth1_loop_nest() {
7  %0 = memref.alloc() : memref<100xf32>
8  %cst = arith.constant 7.000000e+00 : f32
9  affine.for %i0 = 0 to 16 {
10    // expected-remark@-1 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 1 : insert point: (1, 1) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] )}}
11    affine.store %cst, %0[%i0] : memref<100xf32>
12  }
13  affine.for %i1 = 0 to 5 {
14    // expected-remark@-1 {{slice ( src loop: 0, dst loop: 1, depth: 1 : insert point: (1, 0) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] )}}
15    %1 = affine.load %0[%i1] : memref<100xf32>
16  }
17  return
18}
19
20// -----
21
22// CHECK-LABEL: func @forward_slice_slice_depth1_loop_nest() {
23func.func @forward_slice_slice_depth1_loop_nest() {
24  %0 = memref.alloc() : memref<100xf32>
25  %cst = arith.constant 7.000000e+00 : f32
26  affine.for %i0 = 0 to 5 {
27    // expected-remark@-1 {{slice ( src loop: 1, dst loop: 0, depth: 1 : insert point: (1, 1) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] )}}
28    affine.store %cst, %0[%i0] : memref<100xf32>
29  }
30  affine.for %i1 = 0 to 16 {
31    // expected-remark@-1 {{Incorrect slice ( src loop: 0, dst loop: 1, depth: 1 : insert point: (1, 0) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] )}}
32    %1 = affine.load %0[%i1] : memref<100xf32>
33  }
34  return
35}
36
37// -----
38
39// Loop %i0 writes to locations [2, 17] and loop %i0 reads from locations [3, 6]
40// Slice loop bounds should be adjusted such that the load/store are for the
41// same location.
42// CHECK-LABEL: func @slice_depth1_loop_nest_with_offsets() {
43func.func @slice_depth1_loop_nest_with_offsets() {
44  %0 = memref.alloc() : memref<100xf32>
45  %cst = arith.constant 7.000000e+00 : f32
46  affine.for %i0 = 0 to 16 {
47    // expected-remark@-1 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 1 : insert point: (1, 2) loop bounds: [(d0) -> (d0 + 3), (d0) -> (d0 + 4)] )}}
48    %a0 = affine.apply affine_map<(d0) -> (d0 + 2)>(%i0)
49    affine.store %cst, %0[%a0] : memref<100xf32>
50  }
51  affine.for %i1 = 4 to 8 {
52    // expected-remark@-1 {{slice ( src loop: 0, dst loop: 1, depth: 1 : insert point: (1, 0) loop bounds: [(d0) -> (d0 - 3), (d0) -> (d0 - 2)] )}}
53    %a1 = affine.apply affine_map<(d0) -> (d0 - 1)>(%i1)
54    %1 = affine.load %0[%a1] : memref<100xf32>
55  }
56  return
57}
58
59// -----
60
61// Slices at loop depth 1 should only slice the loop bounds of the first scf.
62// Slices at loop depth 2 should slice loop bounds of both loops.
63// CHECK-LABEL: func @slice_depth2_loop_nest() {
64func.func @slice_depth2_loop_nest() {
65  %0 = memref.alloc() : memref<100x100xf32>
66  %cst = arith.constant 7.000000e+00 : f32
67  affine.for %i0 = 0 to 16 {
68    // expected-remark@-1 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 1 : insert point: (1, 1) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (8)] )}}
69    // expected-remark@-2 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 2 : insert point: (2, 1) loop bounds: [(d0, d1) -> (d0), (d0, d1) -> (d0 + 1)] [(d0, d1) -> (d1), (d0, d1) -> (d1 + 1)] )}}
70    affine.for %i1 = 0 to 16 {
71      affine.store %cst, %0[%i0, %i1] : memref<100x100xf32>
72    }
73  }
74  affine.for %i2 = 0 to 10 {
75    // expected-remark@-1 {{slice ( src loop: 0, dst loop: 1, depth: 1 : insert point: (1, 0) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (8)] )}}
76    // expected-remark@-2 {{slice ( src loop: 0, dst loop: 1, depth: 2 : insert point: (2, 0) loop bounds: [(d0, d1) -> (d0), (d0, d1) -> (d0 + 1)] [(d0, d1) -> (d1), (d0, d1) -> (d1 + 1)] )}}
77    affine.for %i3 = 0 to 8 {
78      %1 = affine.load %0[%i2, %i3] : memref<100x100xf32>
79    }
80  }
81  return
82}
83
84// -----
85
86// The load at depth 1 in loop nest %i2 prevents slicing loop nest %i0 at depths
87// greater than 1. However, loop nest %i2 can be sliced into loop nest %i0 at
88// depths 1 and 2 because the dependent store in loop nest %i0 is at depth 2.
89// CHECK-LABEL: func @slice_depth2_loop_nest_two_loads() {
90func.func @slice_depth2_loop_nest_two_loads() {
91  %0 = memref.alloc() : memref<100x100xf32>
92  %c0 = arith.constant 0 : index
93  %cst = arith.constant 7.000000e+00 : f32
94  affine.for %i0 = 0 to 16 {
95    // expected-remark@-1 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 1 : insert point: (1, 1) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (8)] )}}
96    // expected-remark@-2 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 2 : insert point: (2, 1) loop bounds: [(d0, d1) -> (d0), (d0, d1) -> (d0 + 1)] [(d0, d1) -> (0), (d0, d1) -> (16)] )}}
97    affine.for %i1 = 0 to 16 {
98      affine.store %cst, %0[%i0, %i1] : memref<100x100xf32>
99    }
100  }
101  affine.for %i2 = 0 to 10 {
102    // expected-remark@-1 {{slice ( src loop: 0, dst loop: 1, depth: 1 : insert point: (1, 0) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (8)] )}}
103    affine.for %i3 = 0 to 8 {
104      %1 = affine.load %0[%i2, %i3] : memref<100x100xf32>
105    }
106    %2 = affine.load %0[%i2, %c0] : memref<100x100xf32>
107  }
108  return
109}
110
111// -----
112
113// The store at depth 1 in loop nest %i0 prevents slicing loop nest %i2 at
114// depths greater than 1 into loop nest %i0. However, loop nest %i0 can be
115// sliced into loop nest %i2 at depths 1 and 2 because the dependent load in
116// loop nest %i2 is at depth 2.
117// CHECK-LABEL: func @slice_depth2_loop_nest_two_stores() {
118func.func @slice_depth2_loop_nest_two_stores() {
119  %0 = memref.alloc() : memref<100x100xf32>
120  %c0 = arith.constant 0 : index
121  %cst = arith.constant 7.000000e+00 : f32
122  affine.for %i0 = 0 to 16 {
123    // expected-remark@-1 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 1 : insert point: (1, 2) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (8)] )}}
124    affine.for %i1 = 0 to 16 {
125      affine.store %cst, %0[%i0, %i1] : memref<100x100xf32>
126    }
127    affine.store %cst, %0[%i0, %c0] : memref<100x100xf32>
128  }
129  affine.for %i2 = 0 to 10 {
130    // expected-remark@-1 {{slice ( src loop: 0, dst loop: 1, depth: 1 : insert point: (1, 0) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (16)] )}}
131    // expected-remark@-2 {{slice ( src loop: 0, dst loop: 1, depth: 2 : insert point: (2, 0) loop bounds: [(d0, d1) -> (d0), (d0, d1) -> (d0 + 1)] [(d0, d1) -> (0), (d0, d1) -> (16)] )}}
132    affine.for %i3 = 0 to 8 {
133      %1 = affine.load %0[%i2, %i3] : memref<100x100xf32>
134    }
135  }
136  return
137}
138
139// -----
140
141// Test loop nest which has a smaller outer trip count than its inner scf.
142// CHECK-LABEL: func @slice_loop_nest_with_smaller_outer_trip_count() {
143func.func @slice_loop_nest_with_smaller_outer_trip_count() {
144  %0 = memref.alloc() : memref<100x100xf32>
145  %c0 = arith.constant 0 : index
146  %cst = arith.constant 7.000000e+00 : f32
147  affine.for %i0 = 0 to 16 {
148    // expected-remark@-1 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 1 : insert point: (1, 1) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (10)] )}}
149    // expected-remark@-2 {{Incorrect slice ( src loop: 1, dst loop: 0, depth: 2 : insert point: (2, 1) loop bounds: [(d0, d1) -> (d0), (d0, d1) -> (d0 + 1)] [(d0, d1) -> (d1), (d0, d1) -> (d1 + 1)] )}}
150    affine.for %i1 = 0 to 16 {
151      affine.store %cst, %0[%i0, %i1] : memref<100x100xf32>
152    }
153  }
154  affine.for %i2 = 0 to 8 {
155    // expected-remark@-1 {{slice ( src loop: 0, dst loop: 1, depth: 1 : insert point: (1, 0) loop bounds: [(d0) -> (d0), (d0) -> (d0 + 1)] [(d0) -> (0), (d0) -> (10)] )}}
156    // expected-remark@-2 {{slice ( src loop: 0, dst loop: 1, depth: 2 : insert point: (2, 0) loop bounds: [(d0, d1) -> (d0), (d0, d1) -> (d0 + 1)] [(d0, d1) -> (d1), (d0, d1) -> (d1 + 1)] )}}
157    affine.for %i3 = 0 to 10 {
158      %1 = affine.load %0[%i2, %i3] : memref<100x100xf32>
159    }
160  }
161  return
162}
163