1// RUN: mlir-opt %s -test-linalg-transform-patterns=test-patterns | FileCheck %s 2 3// CHECK-DAG: #[[$STRIDED_1D:.*]] = affine_map<(d0)[s0] -> (d0 + s0)> 4// Map corresponding to a 2D memory access where the stride along the last dim is known to be 1. 5// CHECK-DAG: #[[$STRIDED_2D_u_1:.*]] = affine_map<(d0, d1)[s0, s1] -> (d0 * s1 + s0 + d1)> 6// Map corresponding to a 2D memory access where the stride along all dims are unknown. 7// CHECK-DAG: #[[$STRIDED_2D:.*]] = affine_map<(d0, d1)[s0, s1, s2] -> (d0 * s1 + s0 + d1 * s2)> 8// CHECK-DAG: #[[$kn:.*]] = affine_map<(d0, d1, d2) -> (d2, d1)> 9// CHECK-DAG: #[[$nm:.*]] = affine_map<(d0, d1, d2) -> (d1, d0)> 10// CHECK-DAG: #[[$km:.*]] = affine_map<(d0, d1, d2) -> (d2, d0)> 11 12func @dot(%x: memref<?xf32, offset: ?, strides: [1]>, 13 %y: memref<?xf32, offset: ?, strides: [1]>, 14 %v: memref<f32>) { 15 linalg.dot { __internal_linalg_transform__ = "MEM" } 16 ins(%x, %y: memref<?xf32, offset: ?, strides: [1]>, 17 memref<?xf32, offset: ?, strides: [1]>) 18 outs(%v: memref<f32>) 19 20 return 21} 22// CHECK-LABEL: func @dot 23// CHECK-DAG: %[[c0:.*]] = constant 0 : index 24// CHECK-DAG: %[[c1:.*]] = constant 1 : index 25// CHECK-DAG: %[[c8000:.*]] = constant 8000 : index 26// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c8000]] { 27// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c1]] { 28// CHECK: load 29// CHECK: load 30// CHECK: load 31// CHECK: mulf 32// CHECK: addf 33// CHECK: store 34 35func @matvec(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 36 %x: memref<?xf32, offset: ?, strides: [1]>, 37 %y: memref<?xf32, offset: ?, strides: [1]>) { 38 linalg.matvec 39 ins(%A, %x: memref<?x?xf32, offset: ?, strides: [?, 1]>, 40 memref<?xf32, offset: ?, strides: [1]>) 41 outs(%y: memref<?xf32, offset: ?, strides: [1]>) 42 return 43} 44// CHECK-LABEL: func @matvec 45// CHECK-DAG: %[[c0:.*]] = constant 0 : index 46// CHECK-DAG: %[[c5:.*]] = constant 5 : index 47// CHECK-DAG: %[[c6:.*]] = constant 6 : index 48// CHECK: scf.parallel {{.*}} step (%[[c5]]) 49// CHECK: scf.for {{.*}} step %[[c6]] 50// CHECK: linalg.matvec 51// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>) 52// CHECK: outs({{.*}}: memref<?xf32, #[[$STRIDED_1D]]>) 53 54func @matmul(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 55 %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 56 %C: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 57 linalg.matmul { __internal_linalg_transform__ = "MEM" } 58 ins(%A, %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 59 memref<?x?xf32, offset: ?, strides: [?, 1]>) 60 outs(%C: memref<?x?xf32, offset: ?, strides: [?, 1]>) 61 return 62} 63// CHECK-LABEL: func @matmul 64// CHECK-DAG: %[[c0:.*]] = constant 0 : index 65// CHECK-DAG: %[[c2:.*]] = constant 2 : index 66// CHECK-DAG: %[[c3:.*]] = constant 3 : index 67// CHECK-DAG: %[[c4:.*]] = constant 4 : index 68// CHECK-DAG: %[[c20:.*]] = constant 20 : index 69// CHECK-DAG: %[[c30:.*]] = constant 30 : index 70// CHECK-DAG: %[[c40:.*]] = constant 40 : index 71// CHECK-DAG: %[[c200:.*]] = constant 200 : index 72// CHECK-DAG: %[[c300:.*]] = constant 300 : index 73// CHECK-DAG: %[[c400:.*]] = constant 400 : index 74// CHECK-DAG: %[[c2000:.*]] = constant 2000 : index 75// CHECK-DAG: %[[c3000:.*]] = constant 3000 : index 76// CHECK-DAG: %[[c4000:.*]] = constant 4000 : index 77// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 78// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 79// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 80// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c200]] { 81// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c300]] { 82// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c400]] { 83// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c20]] { 84// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c30]] { 85// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c40]] { 86// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2]] { 87// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3]] { 88// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4]] { 89// CHECK: linalg.matmul 90// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 91// CHECK: outs({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 92 93#matmul_accesses = [ 94 affine_map<(m, n, k) -> (m, k)>, 95 affine_map<(m, n, k) -> (k, n)>, 96 affine_map<(m, n, k) -> (m, n)> 97] 98#generic_matmul_trait = { 99 args_in = 2, 100 args_out = 1, 101 indexing_maps = #matmul_accesses, 102 library_call = "linalg_matmul", 103 iterator_types = ["parallel", "parallel", "reduction"] 104} 105func @permute_generic(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 106 %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 107 %C: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 108 linalg.generic #generic_matmul_trait 109 ins(%A, %B : memref<?x?xf32, offset: ?, strides: [?, 1]>, 110 memref<?x?xf32, offset: ?, strides: [?, 1]>) 111 outs(%C : memref<?x?xf32, offset: ?, strides: [?, 1]>) { 112 ^bb(%a: f32, %b: f32, %c: f32): 113 %d = mulf %a, %b: f32 114 %e = addf %c, %d: f32 115 linalg.yield %e: f32 116 } 117 return 118} 119// CHECK-LABEL: func @permute_generic 120// CHECK: linalg.generic { 121// CHECK-SAME: indexing_maps = [#[[$kn]], #[[$nm]], #[[$km]]], 122// CHECK-SAME: iterator_types = ["parallel", "reduction", "parallel"], 123// CHECK-SAME: library_call = "linalg_matmul"} 124// CHECK: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, 125// CHECK-SAME: memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 126// CHECK-SAME: memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 127 128#indexed_matmul_trait = { 129 args_in = 2, 130 args_out = 1, 131 indexing_maps = #matmul_accesses, 132 library_call = "linalg_matmul_indexed", 133 iterator_types = ["parallel", "parallel", "reduction"] 134} 135func @permute_generic_indexed( 136 %A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 137 %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 138 %C: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 139 linalg.indexed_generic #indexed_matmul_trait 140 ins(%A, %B : memref<?x?xf32, offset: ?, strides: [?, 1]>, 141 memref<?x?xf32, offset: ?, strides: [?, 1]>) 142 outs(%C : memref<?x?xf32, offset: ?, strides: [?, 1]>) { 143 ^bb(%i: index, %j: index, %k: index, %a: f32, %b: f32, %c: f32): 144 %d = mulf %a, %b: f32 145 %e = addf %c, %d: f32 146 linalg.yield %e: f32 147 } 148 return 149} 150// CHECK-LABEL: func @permute_generic_indexed 151// CHECK: linalg.indexed_generic { 152// CHECK-SAME: indexing_maps = [#[[$kn]], #[[$nm]], #[[$km]]], 153// CHECK-SAME: iterator_types = ["parallel", "reduction", "parallel"], 154// CHECK-SAME: library_call = "linalg_matmul_indexed"} 155// CHECK: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, 156// CHECK-SAME: memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 157// CHECK-SAME: memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 158 159func @matvec_perm(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 160 %x: memref<?xf32, offset: ?, strides: [1]>, 161 %y: memref<?xf32, offset: ?, strides: [1]>) { 162 linalg.matvec {__internal_linalg_transform__ = "__with_perm__"} 163 ins(%A, %x: memref<?x?xf32, offset: ?, strides: [?, 1]>, 164 memref<?xf32, offset: ?, strides: [1]>) 165 outs(%y: memref<?xf32, offset: ?, strides: [1]>) 166 return 167} 168// CHECK-LABEL: func @matvec_perm 169// CHECK-DAG: %[[c0:.*]] = constant 0 : index 170// CHECK-DAG: %[[c5:.*]] = constant 5 : index 171// CHECK-DAG: %[[c6:.*]] = constant 6 : index 172// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c6]] 173// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c5]] 174// CHECK: linalg.matvec 175// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>) 176// CHECK: outs({{.*}}: memref<?xf32, #[[$STRIDED_1D]]>) 177 178func @matmul_perm(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 179 %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 180 %C: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 181 linalg.matmul {__internal_linalg_transform__ = "__with_perm__"} 182 ins(%A, %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 183 memref<?x?xf32, offset: ?, strides: [?, 1]>) 184 outs(%C : memref<?x?xf32, offset: ?, strides: [?, 1]>) 185 return 186} 187// CHECK-LABEL: func @matmul_perm 188// CHECK-DAG: %[[c0:.*]] = constant 0 : index 189// CHECK-DAG: %[[c20:.*]] = constant 20 : index 190// CHECK-DAG: %[[c30:.*]] = constant 30 : index 191// CHECK-DAG: %[[c40:.*]] = constant 40 : index 192// CHECK-DAG: %[[c200:.*]] = constant 200 : index 193// CHECK-DAG: %[[c300:.*]] = constant 300 : index 194// CHECK-DAG: %[[c400:.*]] = constant 400 : index 195// CHECK-DAG: %[[c2000:.*]] = constant 2000 : index 196// CHECK-DAG: %[[c3000:.*]] = constant 3000 : index 197// CHECK-DAG: %[[c4000:.*]] = constant 4000 : index 198// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 199// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 200// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 201// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c300]] { 202// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c200]] { 203// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c400]] { 204// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c20]] { 205// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c30]] { 206// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c40]] { 207// CHECK: linalg.matmul 208// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 209// CHECK: outs({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 210 211func @promote_subview_matmul(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>, 212 %arg1: memref<?x?xf32, offset: ?, strides: [?, 1]>, 213 %arg2: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 214 %c2000 = constant 2000 : index 215 %c3000 = constant 3000 : index 216 %c4000 = constant 4000 : index 217 %c0 = constant 0 : index 218 %c1 = constant 1 : index 219 %0 = memref.dim %arg0, %c0 : memref<?x?xf32, offset: ?, strides: [?, 1]> 220 %1 = memref.dim %arg0, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 221 %2 = memref.dim %arg1, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 222 scf.for %arg3 = %c0 to %0 step %c2000 { 223 scf.for %arg4 = %c0 to %2 step %c3000 { 224 scf.for %arg5 = %c0 to %1 step %c4000 { 225 %3 = memref.subview %arg0[%arg3, %arg5][%c2000, %c4000][%c1, %c1] : 226 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 227 %4 = memref.subview %arg1[%arg5, %arg4][%c4000, %c3000][%c1, %c1] : 228 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 229 %5 = memref.subview %arg2[%arg3, %arg4][%c2000, %c3000][%c1, %c1] : 230 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 231 linalg.matmul {__internal_linalg_transform__ = "_promote_views_"} 232 ins(%3, %4: memref<?x?xf32, offset: ?, strides: [?, ?]>, 233 memref<?x?xf32, offset: ?, strides: [?, ?]>) 234 outs(%5: memref<?x?xf32, offset: ?, strides: [?, ?]>) 235 } 236 } 237 } 238 return 239} 240// CHECK-LABEL: func @promote_subview_matmul 241// CHECK-DAG: %[[c0:.*]] = constant 0 : index 242// CHECK-DAG: %[[c2000:.*]] = constant 2000 : index 243// CHECK-DAG: %[[c3000:.*]] = constant 3000 : index 244// CHECK-DAG: %[[c4000:.*]] = constant 4000 : index 245// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 246// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 247// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 248// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 249// CHECK: %[[s1:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 250// CHECK: %[[s2:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 251// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) : memref<?xi8> 252// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32> 253// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] 254// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 255// CHECK: %[[a1:.*]] = memref.alloc({{%.*}}) : memref<?xi8> 256// CHECK: %[[v1:.*]] = memref.view %[[a1]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32> 257// CHECK: %[[l1:.*]] = memref.subview %[[v1]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] 258// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 259// CHECK: %[[a2:.*]] = memref.alloc({{%.*}}) : memref<?xi8> 260// CHECK: %[[v2:.*]] = memref.view %[[a2]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32> 261// CHECK: %[[l2:.*]] = memref.subview %[[v2]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] 262// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 263// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}> 264// CHECK: linalg.copy(%[[s1]], %[[l1]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}> 265// CHECK: linalg.copy(%[[s2]], %[[l2]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}> 266// CHECK: linalg.matmul 267// CHECK-SAME: ins(%[[v0]], %[[v1]] : memref<?x?xf32>, memref<?x?xf32>) 268// CHECK-SAME: outs(%[[v2]] : memref<?x?xf32>) 269 270func @promote_first_subview_matmul(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>, 271 %arg1: memref<?x?xf32, offset: ?, strides: [?, 1]>, 272 %arg2: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 273 %c2000 = constant 2000 : index 274 %c3000 = constant 3000 : index 275 %c4000 = constant 4000 : index 276 %c0 = constant 0 : index 277 %c1 = constant 1 : index 278 %0 = memref.dim %arg0, %c0 : memref<?x?xf32, offset: ?, strides: [?, 1]> 279 %1 = memref.dim %arg0, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 280 %2 = memref.dim %arg1, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 281 scf.for %arg3 = %c0 to %0 step %c2000 { 282 scf.for %arg4 = %c0 to %2 step %c3000 { 283 scf.for %arg5 = %c0 to %1 step %c4000 { 284 %3 = memref.subview %arg0[%arg3, %arg5][%c2000, %c4000][%c1, %c1] : 285 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 286 %4 = memref.subview %arg1[%arg5, %arg4][%c4000, %c3000][%c1, %c1] : 287 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 288 %5 = memref.subview %arg2[%arg3, %arg4][%c2000, %c3000][%c1, %c1] : 289 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 290 linalg.matmul {__internal_linalg_transform__ = "_promote_first_view_"} 291 ins(%3, %4: memref<?x?xf32, offset: ?, strides: [?, ?]>, 292 memref<?x?xf32, offset: ?, strides: [?, ?]>) 293 outs(%5: memref<?x?xf32, offset: ?, strides: [?, ?]>) 294 } 295 } 296 } 297 return 298} 299// CHECK-LABEL: func @promote_first_subview_matmul 300// CHECK-DAG: %[[c0:.*]] = constant 0 : index 301// CHECK-DAG: %[[c2000:.*]] = constant 2000 : index 302// CHECK-DAG: %[[c3000:.*]] = constant 3000 : index 303// CHECK-DAG: %[[c4000:.*]] = constant 4000 : index 304// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 305// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 306// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 307// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 308// CHECK: %[[s1:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 309// CHECK: %[[s2:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 310// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) : memref<?xi8> 311// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32> 312// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 313// CHECK-NOT: %{{.*}} = memref.alloc({{%.*}}) : memref<?xi8> 314// CHECK-NOT: %{{.*}} = memref.view %{{.*}}[{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32> 315// CHECK-NOT: %{{.*}} = memref.subview %{{.*}}[0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 316// CHECK-NOT: %{{.*}} = memref.alloc({{%.*}}) : memref<?xi8> 317// CHECK-NOT: %{{.*}} = memref.view %{{.*}}[{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32> 318// CHECK-NOT: %{{.*}} = memref.subview %{{.*}}[0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 319// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}> 320// CHECK-NOT: linalg.copy(%[[s1]], %{{.*}}) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}> 321// CHECK-NOT: linalg.copy(%[[s2]], %{{.*}}) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}>^ 322// CHECK: linalg.matmul 323// CHECK-SAME: ins(%[[v0]], %[[s1]] : memref<?x?xf32>, memref<?x?xf32, #[[$STRIDED_2D]]>) 324// CHECK-SAME: outs(%[[s2]] : memref<?x?xf32, #[[$STRIDED_2D]]>) 325 326func @aligned_promote_fill(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 327 %c2000 = constant 2000 : index 328 %c4000 = constant 4000 : index 329 %c0 = constant 0 : index 330 %c1 = constant 1 : index 331 %cf = constant 1.0 : f32 332 %3 = memref.subview %arg0[%c0, %c0][%c2000, %c4000][%c1, %c1] : 333 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 334 linalg.fill(%3, %cf) { __internal_linalg_transform__ = "_promote_views_aligned_"} 335 : memref<?x?xf32, offset: ?, strides: [?, ?]>, f32 336 return 337} 338// CHECK-LABEL: func @aligned_promote_fill 339// CHECK: %[[cf:.*]] = constant {{.*}} : f32 340// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 341// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) {alignment = 32 : i64} : memref<?xi8> 342// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32> 343// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 344// CHECK: linalg.fill(%[[v0]], {{%.*}}) : memref<?x?xf32>, f32 345// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}> 346// CHECK: linalg.fill(%[[v0]], %[[cf]]) : memref<?x?xf32>, f32 347 348func @aligned_promote_fill_complex(%arg0: memref<?x?xcomplex<f32>, offset: ?, strides: [?, 1]>) { 349 %c2000 = constant 2000 : index 350 %c4000 = constant 4000 : index 351 %c0 = constant 0 : index 352 %c1 = constant 1 : index 353 %cf = constant 1.0 : f32 354 %cc = complex.create %cf, %cf : complex<f32> 355 %3 = memref.subview %arg0[%c0, %c0][%c2000, %c4000][%c1, %c1] : 356 memref<?x?xcomplex<f32>, offset: ?, strides: [?, 1]> to memref<?x?xcomplex<f32>, offset: ?, strides: [?, ?]> 357 linalg.fill(%3, %cc) { __internal_linalg_transform__ = "_promote_views_aligned_"} 358 : memref<?x?xcomplex<f32>, offset: ?, strides: [?, ?]>, complex<f32> 359 return 360} 361// CHECK-LABEL: func @aligned_promote_fill_complex 362// CHECK: %[[cc:.*]] = complex.create {{.*}} : complex<f32> 363// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xcomplex<f32>, #map{{.*}}> to memref<?x?xcomplex<f32>, #map{{.*}}> 364// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) {alignment = 32 : i64} : memref<?xi8> 365// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xcomplex<f32>> 366// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xcomplex<f32>> to memref<?x?xcomplex<f32>, #[[$STRIDED_2D_u_1]]> 367// CHECK: linalg.fill(%[[v0]], {{%.*}}) : memref<?x?xcomplex<f32>>, complex<f32> 368// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xcomplex<f32>, #map{{.*}}>, memref<?x?xcomplex<f32>, #map{{.*}}> 369// CHECK: linalg.fill(%[[v0]], %[[cc]]) : memref<?x?xcomplex<f32>>, complex<f32> 370 371func @tile_permute_parallel_loop(%arg0: memref<?x?xf32>, 372 %arg1: memref<?x?xf32>, 373 %arg2: memref<?x?xf32>) { 374 linalg.matmul {__internal_linalg_transform__ = "par__with_perm__"} 375 ins(%arg0, %arg1: memref<?x?xf32>, memref<?x?xf32>) 376 outs(%arg2: memref<?x?xf32>) 377 return 378} 379// CHECK-LABEL: func @tile_permute_parallel_loop 380// CHECK-SAME: %[[ARG0:[a-zA-Z0-9_]+]]: memref<?x?xf32> 381// CHECK-SAME: %[[ARG1:[a-zA-Z0-9_]+]]: memref<?x?xf32> 382// CHECK-SAME: %[[ARG2:[a-zA-Z0-9_]+]]: memref<?x?xf32> 383// CHECK-DAG: %[[C16:.*]] = constant 16 : index 384// CHECK-DAG: %[[C8:.*]] = constant 8 : index 385// CHECK-DAG: %[[C4:.*]] = constant 4 : index 386// CHECK-DAG: %[[C0:.*]] = constant 0 : index 387// CHECK-DAG: %[[D0:.*]] = memref.dim %[[ARG0]], %c0 388// CHECK-DAG: %[[D1:.*]] = memref.dim %[[ARG0]], %c1 389// CHECK-DAG: %[[D2:.*]] = memref.dim %[[ARG1]], %c1 390// CHECK: scf.parallel (%{{.*}}) = (%[[C0]]) to (%[[D2]]) step (%[[C8]]) 391// CHECK: scf.for %{{.*}} = %[[C0]] to %[[D1]] step %[[C4]] 392// CHECK: scf.parallel (%{{.*}}) = (%[[C0]]) to (%[[D0]]) step (%[[C16]]) 393