[libc][test] Adjust header paths in tests (#119623)
[llvm-project.git] / mlir / test / Dialect / Affine / loop-tiling-parametric.mlir
blobc06f3af3431b13747d00d68bc28542b6ba3890d1
1 // RUN: mlir-opt %s -split-input-file -test-affine-parametric-tile -verify-diagnostics | FileCheck %s
2 // Test cases to test the utility introduced to tile affine for loops using
3 // SSA values as tiling parameters(tile sizes). The tile sizes are expected
4 // to be passed as input arguments(before any other argument) to the function
5 // enclosing the loop nest. Currently hyper-rectangular loop nests with constant
6 // lower bounds are supported.
8 // -----
10 // CHECK-DAG: [[LBI:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
11 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0, 256)>
12 // CHECK-DAG: [[UBI1:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0, 512)>
13 // CHECK-DAG: [[UBI2:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0, 1024)>
14 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0] -> (256 ceildiv s0)>
15 // CHECK-DAG: [[UBO1:#map[0-9]*]] = affine_map<()[s0] -> (512 ceildiv s0)>
16 // CHECK-DAG: [[UBO2:#map[0-9]*]] = affine_map<()[s0] -> (1024 ceildiv s0)>
18 // CHECK: func @loop_tiling_3d([[ARG0:%arg[0-9]+]]: index, [[ARG1:%arg[0-9]+]]: index, [[ARG2:%arg[0-9]+]]: index)
19 // CHECK-NEXT:   affine.for [[ARG3:%arg[0-9]+]] = 0 to [[UBO0]](){{.*}}[[ARG0]]
20 // CHECK-NEXT:     affine.for [[ARG4:%arg[0-9]+]] = 0 to [[UBO1]](){{.*}}[[ARG1]]
21 // CHECK-NEXT:       affine.for [[ARG5:%arg[0-9]+]] = 0 to [[UBO2]](){{.*}}[[ARG2]]
22 // CHECK-NEXT:         affine.for %[[I:.*]] = [[LBI]]{{.*}}[[ARG3]]{{.*}}[[ARG0]]{{.*}} to min [[UBI0]]{{.*}}[[ARG3]]{{.*}}[[ARG0]]
23 // CHECK-NEXT:          affine.for %[[J:.*]] = [[LBI]]{{.*}}[[ARG4]]{{.*}}[[ARG1]]{{.*}} to min [[UBI1]]{{.*}}[[ARG4]]{{.*}}[[ARG1]]
24 // CHECK-NEXT:            affine.for %[[K:.*]] = [[LBI]]{{.*}}[[ARG5]]{{.*}}[[ARG2]]{{.*}} to min [[UBI2]]{{.*}}[[ARG5]]{{.*}}[[ARG2]]
25 // CHECK-NEXT:              "test.foo"(%[[I]], %[[J]], %[[K]])
26 func.func @loop_tiling_3d(%t0 : index, %t1 : index, %t2 : index) {
27   affine.for %i = 0 to 256 {
28     affine.for %j = 0 to 512 {
29       affine.for %k = 0 to 1024 {
30         "test.foo"(%i, %j, %k) : (index, index, index) -> ()
31       }
32     }
33   }
34   return
37 // -----
39 // CHECK-DAG: [[LBI:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
40 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0 * 4, 256)>
41 // CHECK-DAG: [[UBI1:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0 * 3, 512)>
42 // CHECK-DAG: [[UBI2:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0 * 2, 1024)>
43 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0] -> (256 ceildiv s0)>
44 // CHECK-DAG: [[UBO1:#map[0-9]*]] = affine_map<()[s0] -> (512 ceildiv s0)>
45 // CHECK-DAG: [[UBO2:#map[0-9]*]] = affine_map<()[s0] -> (1024 ceildiv s0)>
47 // CHECK: func @loop_tiling_non_unit_step([[ARG0:%arg[0-9]+]]: index, [[ARG1:%arg[0-9]+]]: index, [[ARG2:%arg[0-9]+]]: index)
48 // CHECK-NEXT:  affine.for [[ARG3:%arg[0-9]+]] = 0 to [[UBO0]](){{.*}}[[ARG0]]{{.*}}step 4
49 // CHECK-NEXT:    affine.for [[ARG4:%arg[0-9]+]] = 0 to [[UBO1]](){{.*}}[[ARG1]]{{.*}} step 3
50 // CHECK-NEXT:       affine.for [[ARG5:%arg[0-9]+]] = 0 to [[UBO2]](){{.*}}[[ARG2]]{{.*}} step 2
51 // CHECK-NEXT:         affine.for %[[I:.*]] = [[LBI]]{{.*}}[[ARG3]]{{.*}}[[ARG0]]{{.*}} to min [[UBI0]]{{.*}}[[ARG3]]{{.*}}[[ARG0]]{{.*}} step 4
52 // CHECK-NEXT:          affine.for %[[J:.*]] = [[LBI]]{{.*}}[[ARG4]]{{.*}}[[ARG1]]{{.*}} to min [[UBI1]]{{.*}}[[ARG4]]{{.*}}[[ARG1]]{{.*}} step 3
53 // CHECK-NEXT:            affine.for %[[K:.*]] = [[LBI]]{{.*}}[[ARG5]]{{.*}}[[ARG2]]{{.*}} to min [[UBI2]]{{.*}}[[ARG5]]{{.*}}[[ARG2]]{{.*}} step 2
54 // CHECK-NEXT:              "test.foo"(%[[I]], %[[J]], %[[K]])
55 func.func @loop_tiling_non_unit_step(%t0: index, %t1: index, %t2: index){
56   affine.for %i = 0 to 256 step 4 {
57     affine.for %j = 0 to 512  step 3 {
58       affine.for %k = 0 to 1024 step 2 {
59         "test.foo"(%i, %j, %k) : (index, index, index) -> ()
60       }
61     }
62   }
63   return
66 // -----
68 // CHECK-DAG: [[LBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
69 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0, s1, s2] -> (d0 * s2 + s2, s0, 4096 floordiv s1)>
70 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0, s1, s2] -> (s0 ceildiv s2, (4096 floordiv s1) ceildiv s2)>
72 // CHECK: func @tile_loop_with_div_in_upper_bound([[ARG0:%arg[0-9]+]]: index, %{{.*}}: memref<?xi32>, %{{.*}}: index, %{{.*}}: index)
73 #ub = affine_map<()[s0, s1] -> (s0, 4096 floordiv s1)>
74 func.func @tile_loop_with_div_in_upper_bound(%t5 : index, %A : memref<? x i32>, %L : index, %U : index) {
75   %c0 = arith.constant 0 : index
76   %M = memref.dim %A, %c0 : memref<? x i32>
77   affine.for %i = 0 to min #ub()[%M, %U] {
78     arith.addi %i, %i : index
79   }
80   // CHECK:  affine.for [[ARG1:%arg[0-9]+]] = 0 to min [[UBO0]]()[%{{.*}}, %{{.*}}, [[ARG0]]]
81   // CHECK-NEXT:    affine.for %[[I:.*]] = [[LBI0]]([[ARG1]]){{.*}}[[ARG0]]{{.*}} to min [[UBI0]]({{.*}})[{{.*}}, {{.*}}, [[ARG0]]]
82   // CHECK-NEXT:      arith.addi %[[I]], %[[I]]
83   return
86 // -----
88 // CHECK-DAG: [[LBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
89 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0, s1, s2] -> (d0 * s2 + s2 * 4, s0, 4096 floordiv s1)>
90 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0, s1, s2] -> (s0 ceildiv s2, (4096 floordiv s1) ceildiv s2)>
92 // CHECK: func @tile_loop_with_div_in_upper_bound_non_unit_step([[ARG0:%arg[0-9]+]]: index, %{{.*}}: memref<?xi32>, %{{.*}}: index, %{{.*}}: index)
93 #ub = affine_map<()[s0, s1] -> (s0, 4096 floordiv s1)>
94 func.func @tile_loop_with_div_in_upper_bound_non_unit_step(%t5 : index, %A : memref<? x i32>, %L : index, %U : index) {
95   %c0 = arith.constant 0 : index
96   %M = memref.dim %A, %c0 : memref<? x i32>
97   affine.for %i = 0 to min #ub()[%M, %U] step 4 {
98     arith.addi %i, %i : index
99   }
100   // CHECK: affine.for [[ARG1:%arg[0-9]+]] = 0 to min [[UBO0]]()[%{{.*}}, %{{.*}}, [[ARG0]]]{{.*}} step 4{{.*}}
101   // CHECK-NEXT:    affine.for %[[I:.*]] = [[LBI0]]([[ARG1]]){{.*}}[[ARG0]]{{.*}} to min [[UBI0]]({{.*}})[{{.*}}, {{.*}}, [[ARG0]]]{{.*}} step 4{{.*}}
102   // CHECK-NEXT:      arith.addi %[[I]], %[[I]]
103   return
106 // -----
108 // CHECK-DAG: [[LBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> ((d0 - 8) * s0 + 8)>
109 // CHECK-DAG: [[UBI2:#map[0-9]*]] = affine_map<(d0)[s0, s1] -> ((d0 - 8) * s1 + s1 * 4 + 8, s0 + 16)>
110 // CHECK-DAG: [[UBI1:#map[0-9]*]] = affine_map<(d0)[s0, s1] -> ((d0 - 8) * s1 + s1 + 8, s0 + 16)>
111 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> ((d0 - 8) * s0 + s0 + 8, 256)>
112 // CHECK-DAG: [[UBO1:#map[0-9]*]] = affine_map<()[s0, s1] -> ((s0 + 8) ceildiv s1 + 8)>
113 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0] -> (248 ceildiv s0 + 8)>
115 // CHECK: func @tile_loop_with_non_zero_lb([[ARG0:%arg[0-9]+]]: index, [[ARG1:%arg[0-9]+]]: index, [[ARG2:%arg[0-9]+]]: index, %{{.*}}: index)
116 // CHECK-NEXT:  affine.for [[ARG3:%arg[0-9+]]] = 8 to [[UBO0]]{{.*}}[[ARG0]]{{.*}}
117 // CHECK-NEXT:    affine.for [[ARG4:%arg[0-9+]]] = 8 to [[UBO1]]{{.*}}[[ARG1]]{{.*}}
118 // CHECK-NEXT:      affine.for [[ARG5:%arg[0-9+]]] = 8 to [[UBO1]]{{.*}}[[ARG2]]{{.*}} step 4
119 // CHECK-NEXT:        affine.for %[[I:.*]] = [[LBI0]]([[ARG3]]){{.*}}[[ARG0]]{{.*}} to min [[UBI0]]([[ARG3]]){{.*}}[[ARG0]]{{.*}}
120 // CHECK-NEXT:          affine.for %[[J:.*]] = [[LBI0]]([[ARG4]]){{.*}}[[ARG1]]{{.*}} to min [[UBI1]]([[ARG4]]){{.*}}[[ARG1]]{{.*}}
121 // CHECK-NEXT:            affine.for %[[K:.*]] = [[LBI0]]([[ARG5]]){{.*}}[[ARG2]]{{.*}} to min [[UBI2]]([[ARG5]]){{.*}}[[ARG2]]{{.*}}step 4{{.*}}
122 // CHECK-NEXT:              "test.foo"(%[[I]], %[[J]], %[[K]]) : (index, index, index) -> ()
123 #ubi = affine_map<()[s0] -> (s0 + 16)>
124 func.func @tile_loop_with_non_zero_lb(%t0: index, %t1: index, %t2: index, %U: index){
125   affine.for %i = 8 to 256 {
126     affine.for %j = 8 to #ubi()[%U] {
127       affine.for %k = 8 to #ubi()[%U] step 4 {
128         "test.foo"(%i, %j, %k) : (index, index, index) -> ()
129       }
130     }
131   }
132   return
135 // -----
137 // CHECK-DAG: [[LBI:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
138 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0, 256)>
139 // CHECK-DAG: [[UBI1:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0 + s0, 250)>
140 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0] -> (256 ceildiv s0)>
141 // CHECK-DAG: [[UBO1:#map[0-9]*]] = affine_map<()[s0] -> (250 ceildiv s0)>
143 // CHECK: func @simple_matmul([[ARG0:%arg[0-9]+]]: index, [[ARG1:%arg[0-9]+]]: index, [[ARG2:%arg[0-9]+]]: index{{.*}})
144 // CHECK-NEXT:   affine.for [[ARG3:%arg[0-9]+]] = 0 to [[UBO0]](){{.*}}[[ARG0]]{{.*}}
145 // CHECK-NEXT:     affine.for [[ARG4:%arg[0-9]+]] = 0 to [[UBO0]](){{.*}}[[ARG1]]{{.*}}
146 // CHECK-NEXT:       affine.for [[ARG5:%arg[0-9]+]] = 0 to [[UBO1]](){{.*}}[[ARG2]]{{.*}}
147 // CHECK-NEXT:         affine.for %[[I:.*]] = [[LBI]]{{.*}}[[ARG3]]{{.*}}[[ARG0]]{{.*}} to min [[UBI0]]{{.*}}[[ARG3]]{{.*}}[[ARG0]]{{.*}}
148 // CHECK-NEXT:          affine.for %[[J:.*]] = [[LBI]]{{.*}}[[ARG4]]{{.*}}[[ARG1]]{{.*}} to min [[UBI0]]{{.*}}[[ARG4]]{{.*}}[[ARG1]]{{.*}}
149 // CHECK-NEXT:            affine.for %[[K:.*]] = [[LBI]]{{.*}}[[ARG5]]{{.*}}[[ARG2]]{{.*}} to min [[UBI1]]{{.*}}[[ARG5]]{{.*}}[[ARG2]]{{.*}}
150 // CHECK-NEXT:                 affine.load %{{.*}}[%[[I]], %[[K]]]
151 // CHECK-NEXT:                 affine.load %{{.*}}[%[[K]], %[[J]]]
152 // CHECK-NEXT:                 affine.load %{{.*}}[%[[I]], %[[J]]]
153 // CHECK-NEXT:                 arith.mulf %{{.*}}
154 // CHECK-NEXT:                 arith.addf %{{.*}}
155 // CHECK-NEXT:                 affine.store %{{.*}}[%[[I]], %[[J]]]
156 func.func @simple_matmul(%t6 : index, %t7 : index, %t8 : index, %arg0: memref<256x256xvector<64xf32>>, %arg1: memref<256x256xvector<64xf32>>, %arg2: memref<256x256xvector<64xf32>>) -> memref<256x256xvector<64xf32>> {
157   affine.for %i = 0 to 256 {
158     affine.for %j = 0 to 256 {
159       affine.for %k = 0 to 250 {
160         %l = affine.load %arg0[%i, %k] : memref<256x256xvector<64xf32>>
161         %r = affine.load %arg1[%k, %j] : memref<256x256xvector<64xf32>>
162         %o = affine.load %arg2[%i, %j] : memref<256x256xvector<64xf32>>
163         %m = arith.mulf %l, %r : vector<64xf32>
164         %a = arith.addf %o, %m : vector<64xf32>
165         affine.store %a, %arg2[%i, %j] : memref<256x256xvector<64xf32>>
166       }
167     }
168   }
169   return %arg2 : memref<256x256xvector<64xf32>>
172 // -----
174 // CHECK-DAG: [[LBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
175 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0, s1] -> (d0 * s1 + s1, s0)>
176 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0, s1] -> (s0 ceildiv s1)>
178 // CHECK: func @tile_using_symbolic_loop_upper_bounds([[ARG0:%arg[0-9]+]]: index, [[ARG1:%arg[0-9]+]]: index{{.*}}){{.*}}
179 // CHECK:        affine.for [[ARG2:%arg[0-9]+]] = 0 to [[UBO0]](){{.*}}[[ARG0]]{{.*}}
180 // CHECK-NEXT:     affine.for [[ARG3:%arg[0-9]+]] = 0 to [[UBO0]](){{.*}}[[ARG1]]{{.*}}
181 // CHECK-NEXT:       affine.for %[[I0:.*]] = [[LBI0]]{{.*}}[[ARG2]]{{.*}}[[ARG0]]{{.*}} to min [[UBI0]]{{.*}}[[ARG2]]{{.*}}[[ARG0]]{{.*}}
182 // CHECK-NEXT:         affine.for %[[I1:.*]] = [[LBI0]]{{.*}}[[ARG3]]{{.*}}[[ARG1]]{{.*}} to min [[UBI0]]{{.*}}[[ARG3]]{{.*}}[[ARG1]]{{.*}}
183 // CHECK-NEXT:           affine.store %{{.*}}, %{{.*}}[%[[I0]], %[[I1]]] : memref<?x?xf32>
184 // CHECK-NEXT:           affine.for %[[I2:.*]] = 0 to %{{.*}} {
185 // CHECK-NEXT:             affine.load %{{.*}}%[[I0]], %[[I2]]
186 // CHECK-NEXT:             affine.load %{{.*}}%[[I2]], %[[I1]]
187 // CHECK-NEXT:             arith.mulf
188 // CHECK-NEXT:             affine.load %{{.*}}%[[I0]], %[[I1]]
189 // CHECK-NEXT:             arith.addf
190 // CHECK-NEXT:             affine.store %{{.*}}%[[I0]], %[[I1]]
191 func.func @tile_using_symbolic_loop_upper_bounds(%t9 : index, %t10: index, %arg0: memref<?x?xf32>, %arg1: memref<?x?xf32>, %arg2: memref<?x?xf32>) {
192   %cst = arith.constant 0.000000e+00 : f32
193   %c0 = arith.constant 0 : index
194   %0 = memref.dim %arg0, %c0 : memref<?x?xf32>
195   affine.for %i0 = 0 to %0 {
196     affine.for %i1 = 0 to %0 {
197       affine.store %cst, %arg2[%i0, %i1] : memref<?x?xf32>
198       affine.for %i2 = 0 to %0 {
199         %1 = affine.load %arg0[%i0, %i2] : memref<?x?xf32>
200         %2 = affine.load %arg1[%i2, %i1] : memref<?x?xf32>
201         %3 = arith.mulf %1, %2 : f32
202         %4 = affine.load %arg2[%i0, %i1] : memref<?x?xf32>
203         %5 = arith.addf %4, %3 : f32
204         affine.store %5, %arg2[%i0, %i1] : memref<?x?xf32>
205       }
206     }
207   }
208   return
211 // -----
213 // CHECK-DAG: [[LBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
214 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0)[s0, s1, s2] -> (d0 * s2 + s2, s0 + s1)>
215 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<()[s0, s1, s2] -> ((s0 + s1) ceildiv s2)>
217 // CHECK: func @tile_using_loop_upper_bounds_in_two_symbols([[ARG0:%arg[0-9]+]]: index{{.*}}){{.*}}
218 func.func @tile_using_loop_upper_bounds_in_two_symbols(%t11 : index, %arg0: memref<?xf32>, %limit: index) {
219   %c0 = arith.constant 0 : index
220   %dim0 = memref.dim %arg0, %c0 : memref<?xf32>
221   affine.for %i0 = 0 to affine_map<()[s0, s1] -> (s0 + s1)> ()[%dim0, %limit] {
222     %v0 = affine.load %arg0[%i0] : memref<?xf32>
223   }
224   // CHECK:  affine.for [[ARG1:%arg[0-9]+]] = 0 to [[UBO0]]()[%{{.*}}, %{{.*}}, [[ARG0]]]
225   // CHECK-NEXT:    affine.for %[[I:.*]] = [[LBI0]]([[ARG1]]){{.*}}[[ARG0]]{{.*}} to min [[UBI0]]([[ARG1]])[{{.*}}, {{.*}}, [[ARG0]]]
226   // CHECK-NEXT:      affine.load %{{.*}}[%[[I]]]
227   return
230 // -----
232 // CHECK-DAG: [[LBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
233 // CHECK-DAG: [[UBI1:#map[0-9]*]] = affine_map<(d0, d1)[s0, s1] -> (d1 * s1 + s1, d0 + s0 + 4)>
234 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0, d1)[s0, s1] -> (d1 * s1 + s1, d0 + s0 + 2)>
235 // CHECK-DAG: [[UBO1:#map[0-9]*]] = affine_map<(d0)[s0, s1] -> ((d0 + s0 + 4) ceildiv s1)>
236 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<(d0)[s0, s1] -> ((d0 + s0 + 2) ceildiv s1)>
238 // CHECK: func @tile_using_upper_bounds_in_dimensions_and_symbols([[ARG0:%arg[0-9]+]]: index, [[ARG1:%arg[0-9]+]]: index, [[ARG2:%arg[0-9]+]]: index, [[ARG3:%arg[0-9]+]]: index{{.*}}){{.*}}
239 // CHECK-NEXT: affine.for [[ARG4:%arg[0-9]+]] = 0 to [[UBO0]]({{.*}}){{.*}}[[ARG0]]
240 // CHECK-NEXT:   affine.for [[ARG5:%arg[0-9]+]] = 0 to [[UBO1]]({{.*}}){{.*}}[[ARG1]]
241 // CHECK-NEXT:     affine.for {{.*}} = [[LBI0]]([[ARG4]]){{.*}}[[ARG0]]{{.*}} to min [[UBI0]]({{.*}}, [[ARG4]]){{.*}}[[ARG0]]{{.*}}
242 // CHECK-NEXT:       affine.for {{.*}} = [[LBI0]]([[ARG5]]){{.*}}[[ARG1]]{{.*}} to min [[UBI1]]({{.*}}, [[ARG5]]){{.*}}[[ARG1]]{{.*}}
243 func.func @tile_using_upper_bounds_in_dimensions_and_symbols(%t12 : index, %t13 :index, %M: index, %N:  index, %K: index) {
244   affine.for %i = 0 to affine_map<(d0)[s0] -> (d0 + s0 + 2)>(%M)[%K] {
245     affine.for %j = 0 to affine_map<(d0)[s0] -> (d0 + s0 + 4)>(%N)[%K] {
246       "test.foo" () : () -> ()
247     }
248   }
249   return
252 // -----
254 // CHECK-DAG: [[LBI0:#map[0-9]*]] = affine_map<(d0)[s0] -> (d0 * s0)>
255 // CHECK-DAG: [[UBI1:#map[0-9]*]] = affine_map<(d0, d1)[s0, s1] -> (d1 * s1 + s1 * 4, d0 + s0 + 4)>
256 // CHECK-DAG: [[UBI0:#map[0-9]*]] = affine_map<(d0, d1)[s0, s1] -> (d1 * s1 + s1 * 2, d0 + s0 + 2)>
257 // CHECK-DAG: [[UBO1:#map[0-9]*]] = affine_map<(d0)[s0, s1] -> ((d0 + s0 + 4) ceildiv s1)>
258 // CHECK-DAG: [[UBO0:#map[0-9]*]] = affine_map<(d0)[s0, s1] -> ((d0 + s0 + 2) ceildiv s1)>
260 // CHECK: func @tile_using_upper_bounds_in_dimensions_and_symbols_non_unit_steps
261 // CHECK-SAME: ([[ARG0:%arg[0-9]+]]: index, [[ARG1:%arg[0-9]+]]: index, [[ARG2:%arg[0-9]+]]: index, [[ARG3:%arg[0-9]+]]: index{{.*}}){{.*}}
262 // CHECK-NEXT: affine.for [[ARG4:%arg[0-9]+]] = 0 to [[UBO0]]({{.*}}){{.*}}[[ARG0]]{{.*}} step 2{{.*}}
263 // CHECK-NEXT:   affine.for [[ARG5:%arg[0-9]+]] = 0 to [[UBO1]]({{.*}}){{.*}}[[ARG1]]{{.*}} step 4{{.*}}
264 // CHECK-NEXT:     affine.for {{.*}} = [[LBI0]]([[ARG4]]){{.*}}[[ARG0]]{{.*}} to min [[UBI0]]({{.*}}, [[ARG4]]){{.*}}[[ARG0]]{{.*}} step 2{{.*}}
265 // CHECK-NEXT:       affine.for {{.*}} = [[LBI0]]([[ARG5]]){{.*}}[[ARG1]]{{.*}} to min [[UBI1]]({{.*}}, [[ARG5]]){{.*}}[[ARG1]]{{.*}} step 4{{.*}}
266 func.func @tile_using_upper_bounds_in_dimensions_and_symbols_non_unit_steps(%t12 : index, %t13 :index, %M: index, %N :  index, %K: index) {
267   affine.for %i = 0 to affine_map<(d0)[s0] -> (d0 + s0 + 2)>(%M)[%K] step 2 {
268     affine.for %j = 0 to affine_map<(d0)[s0] -> (d0 + s0 + 4)>(%N)[%K] step 4 {
269       "test.foo" () : () -> ()
270     }
271   }
272   return
275 // -----
277 func.func @too_few_tile_size_params() {
278   // expected-error@+1 {{too few tile sizes provided in the argument list of the function which contains the current band}}
279   affine.for %i = 0 to 256 {
280     affine.for %j = 0 to 512 {
281       affine.for %k = 0 to 1024 {
282         "test.foo"(%i, %j, %k) : (index, index, index) -> ()
283       }
284     }
285   }
286   return
289 // -----
291 func.func @invalid_type_for_tile_size_params(%arg0: f32, %arg1: f32, %arg2: f32) {
292   // expected-error@+1 {{expected tiling parameters to be of index type}}
293   affine.for %i = 0 to 256 {
294     affine.for %j = 0 to 512 {
295       affine.for %k = 0 to 1024 {
296         "test.foo"(%i, %j, %k) : (index, index, index) -> ()
297       }
298     }
299   }
300   return