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. 7 8// ----- 9 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)> 17 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]]) 26func.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 35} 36 37// ----- 38 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)> 46 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]]) 55func.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 64} 65 66// ----- 67 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)> 71 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)> 74func.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 84} 85 86// ----- 87 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)> 91 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)> 94func.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 104} 105 106// ----- 107 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)> 114 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)> 124func.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 133} 134 135// ----- 136 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)> 142 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]]] 156func.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>> 170} 171 172// ----- 173 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)> 177 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]] 191func.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 209} 210 211// ----- 212 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)> 216 217// CHECK: func @tile_using_loop_upper_bounds_in_two_symbols([[ARG0:%arg[0-9]+]]: index{{.*}}){{.*}} 218func.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 228} 229 230// ----- 231 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)> 237 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]]{{.*}} 243func.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 250} 251 252// ----- 253 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)> 259 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{{.*}} 266func.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 273} 274 275// ----- 276 277func.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 287} 288 289// ----- 290 291func.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 301} 302