1// RUN: mlir-opt %s -convert-linalg-to-llvm | FileCheck %s 2 3func @range(%arg0: index) { 4 %c0 = constant 0 : index 5 %c1 = constant 1 : index 6 %R = linalg.range %c0:%arg0:%c1 : !linalg.range 7 return 8} 9// CHECK-LABEL: func @range(%{{.*}}: !llvm.i64) { 10// CHECK: llvm.mlir.constant(0 : index) : !llvm.i64 11// CHECK-NEXT: llvm.mlir.constant(1 : index) : !llvm.i64 12// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(i64, i64, i64)> 13// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(i64, i64, i64)> 14// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(i64, i64, i64)> 15// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm.struct<(i64, i64, i64)> 16 17func @slice(%arg0: memref<?xf32, offset: ?, strides: [1]>, %arg1: !linalg.range) { 18 %1 = linalg.slice %arg0[%arg1] : memref<?xf32, offset: ?, strides: [1]>, !linalg.range, memref<?xf32, offset: ?, strides: [1]> 19 return 20} 21// CHECK-LABEL: func @slice 22// insert data ptr for slice op 23// CHECK: llvm.extractvalue %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 24// CHECK-NEXT: llvm.extractvalue %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 25// CHECK-NEXT: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(i64, i64, i64)> 26// CHECK-NEXT: llvm.mul %{{.*}}, %{{.*}} : !llvm.i64 27// CHECK-NEXT: llvm.add %{{.*}}, %{{.*}} : !llvm.i64 28// insert offset 29// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 30// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 31// CHECK-NEXT: llvm.mlir.constant(0 : index) 32// CHECK-NEXT: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(i64, i64, i64)> 33// CHECK-NEXT: llvm.extractvalue %{{.*}}[1] : !llvm.struct<(i64, i64, i64)> 34// CHECK-NEXT: llvm.extractvalue %{{.*}}[2] : !llvm.struct<(i64, i64, i64)> 35// get size[0] from parent view 36// CHECK-NEXT: llvm.extractvalue %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 37// CHECK-NEXT: llvm.icmp "slt" %{{.*}}, %{{.*}} : !llvm.i64 38// CHECK-NEXT: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : !llvm.i1, !llvm.i64 39// compute size[0] bounded by parent view's size[0] 40// CHECK-NEXT: llvm.sub %{{.*}}, %{{.*}} : !llvm.i64 41// bound below by 0 42// CHECK-NEXT: llvm.icmp "slt" %{{.*}}, %{{.*}} : !llvm.i64 43// CHECK-NEXT: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : !llvm.i1, !llvm.i64 44// compute stride[0] using bounded size 45// CHECK-NEXT: llvm.mul %{{.*}}, %{{.*}} : !llvm.i64 46// insert size and stride 47// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 48// CHECK-NEXT: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<1 x i64>, array<1 x i64>)> 49 50func @slice_with_range_and_index(%arg0: memref<?x?xf64, offset: ?, strides: [?, 1]>) { 51 %c0 = constant 0 : index 52 %c1 = constant 1 : index 53 %R = linalg.range %c0:%c1:%c1 : !linalg.range 54 scf.for %i0 = %c0 to %c1 step %c1 { 55 %1 = linalg.slice %arg0[%i0, %R] : memref<?x?xf64, offset: ?, strides: [?, 1]>, index, !linalg.range, memref<?xf64, offset: ?, strides: [1]> 56 } 57 return 58} 59// CHECK-LABEL: func @slice_with_range_and_index 60// loop-body. 61// CHECK: llvm.mlir.undef : !llvm.struct<(ptr<double>, ptr<double>, i64, array<1 x i64>, array<1 x i64>)> 62// CHECK: llvm.extractvalue %{{.*}}[4, 0] : !llvm.struct<(ptr<double>, ptr<double>, i64, array<2 x i64>, array<2 x i64>)> 63// CHECK: llvm.extractvalue %{{.*}}[4, 1] : !llvm.struct<(ptr<double>, ptr<double>, i64, array<2 x i64>, array<2 x i64>)> 64// CHECK: llvm.extractvalue %{{.*}}[2] : !llvm.struct<(ptr<double>, ptr<double>, i64, array<2 x i64>, array<2 x i64>)> 65// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr<double>, ptr<double>, i64, array<1 x i64>, array<1 x i64>)> 66// CHECK: llvm.insertvalue %{{.*}}[2] : !llvm.struct<(ptr<double>, ptr<double>, i64, array<1 x i64>, array<1 x i64>)> 67// CHECK: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(i64, i64, i64)> 68// CHECK: llvm.extractvalue %{{.*}}[1] : !llvm.struct<(i64, i64, i64)> 69// CHECK: llvm.insertvalue %{{.*}}[3, 0] : !llvm.struct<(ptr<double>, ptr<double>, i64, array<1 x i64>, array<1 x i64>)> 70// CHECK: llvm.insertvalue %{{.*}}[4, 0] : !llvm.struct<(ptr<double>, ptr<double>, i64, array<1 x i64>, array<1 x i64>)> 71 72func @reshape_static_expand(%arg0: memref<3x4x5xf32>) -> memref<1x3x4x1x5xf32> { 73 // Reshapes that expand a contiguous tensor with some 1's. 74 %0 = linalg.reshape %arg0 [affine_map<(i, j, k, l, m) -> (i, j)>, 75 affine_map<(i, j, k, l, m) -> (k)>, 76 affine_map<(i, j, k, l, m) -> (l, m)>] : 77 memref<3x4x5xf32> into memref<1x3x4x1x5xf32> 78 return %0 : memref<1x3x4x1x5xf32> 79} 80// CHECK-LABEL: func @reshape_static_expand 81// CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 82// CHECK: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 83// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 84// CHECK: llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 85// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 86// CHECK: llvm.extractvalue %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 87// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 88// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 89// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 90// CHECK: llvm.mlir.constant(3 : index) : !llvm.i64 91// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 92// CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 93// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 94// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 95// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 3] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 96// CHECK: llvm.mlir.constant(5 : index) : !llvm.i64 97// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 4] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 98// CHECK: llvm.mlir.constant(60 : index) : !llvm.i64 99// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 100// CHECK: llvm.mlir.constant(20 : index) : !llvm.i64 101// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 102// CHECK: llvm.mlir.constant(5 : index) : !llvm.i64 103// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 104// CHECK: llvm.mlir.constant(5 : index) : !llvm.i64 105// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 3] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 106// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 107// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 4] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 108 109func @reshape_static_collapse(%arg0: memref<1x3x4x1x5xf32>) -> memref<3x4x5xf32> { 110 %0 = linalg.reshape %arg0 [affine_map<(i, j, k, l, m) -> (i, j)>, 111 affine_map<(i, j, k, l, m) -> (k)>, 112 affine_map<(i, j, k, l, m) -> (l, m)>] : 113 memref<1x3x4x1x5xf32> into memref<3x4x5xf32> 114 return %0 : memref<3x4x5xf32> 115} 116// CHECK-LABEL: func @reshape_static_collapse 117// CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 118// CHECK: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 119// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 120// CHECK: llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 121// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 122// CHECK: llvm.extractvalue %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<5 x i64>, array<5 x i64>)> 123// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 124// CHECK: llvm.mlir.constant(3 : index) : !llvm.i64 125// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 126// CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 127// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 128// CHECK: llvm.mlir.constant(5 : index) : !llvm.i64 129// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 130// CHECK: llvm.mlir.constant(20 : index) : !llvm.i64 131// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 132// CHECK: llvm.mlir.constant(5 : index) : !llvm.i64 133// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 134// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 135// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<3 x i64>, array<3 x i64>)> 136 137func @reshape_fold_zero_dim(%arg0 : memref<1x1xf32>) -> memref<f32> { 138 %0 = linalg.reshape %arg0 [] : memref<1x1xf32> into memref<f32> 139 return %0 : memref<f32> 140} 141// CHECK-LABEL: func @reshape_fold_zero_dim 142// CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64)> 143// CHECK: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 144// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 145// CHECK: llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 146// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 147// CHECK: llvm.extractvalue %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 148// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 149 150func @reshape_expand_zero_dim(%arg0 : memref<f32>) -> memref<1x1xf32> { 151 %0 = linalg.reshape %arg0 [] : memref<f32> into memref<1x1xf32> 152 return %0 : memref<1x1xf32> 153} 154// CHECK-LABEL: func @reshape_expand_zero_dim 155// CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 156// CHECK: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 157// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 158// CHECK: llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 159// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 160// CHECK: llvm.extractvalue %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64)> 161// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 162// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 163// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 164// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 165// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 166// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 167// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 168// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 169// CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 170