1// RUN: mlir-opt -legalize-std-for-spirv -verify-diagnostics %s -o - | FileCheck %s 2 3// CHECK-LABEL: @fold_static_stride_subview_with_load 4// CHECK-SAME: [[ARG0:%.*]]: memref<12x32xf32>, [[ARG1:%.*]]: index, [[ARG2:%.*]]: index, [[ARG3:%.*]]: index, [[ARG4:%.*]]: index 5func @fold_static_stride_subview_with_load(%arg0 : memref<12x32xf32>, %arg1 : index, %arg2 : index, %arg3 : index, %arg4 : index) -> f32 { 6 // CHECK-NOT: subview 7 // CHECK: [[C2:%.*]] = constant 2 : index 8 // CHECK: [[C3:%.*]] = constant 3 : index 9 // CHECK: [[STRIDE1:%.*]] = muli [[ARG3]], [[C2]] : index 10 // CHECK: [[INDEX1:%.*]] = addi [[ARG1]], [[STRIDE1]] : index 11 // CHECK: [[STRIDE2:%.*]] = muli [[ARG4]], [[C3]] : index 12 // CHECK: [[INDEX2:%.*]] = addi [[ARG2]], [[STRIDE2]] : index 13 // CHECK: load [[ARG0]]{{\[}}[[INDEX1]], [[INDEX2]]{{\]}} 14 %0 = subview %arg0[%arg1, %arg2][4, 4][2, 3] : memref<12x32xf32> to memref<4x4xf32, offset:?, strides: [64, 3]> 15 %1 = load %0[%arg3, %arg4] : memref<4x4xf32, offset:?, strides: [64, 3]> 16 return %1 : f32 17} 18 19// CHECK-LABEL: @fold_dynamic_stride_subview_with_load 20// CHECK-SAME: [[ARG0:%.*]]: memref<12x32xf32>, [[ARG1:%.*]]: index, [[ARG2:%.*]]: index, [[ARG3:%.*]]: index, [[ARG4:%.*]]: index, [[ARG5:%.*]]: index, [[ARG6:%.*]]: index 21func @fold_dynamic_stride_subview_with_load(%arg0 : memref<12x32xf32>, %arg1 : index, %arg2 : index, %arg3 : index, %arg4 : index, %arg5 : index, %arg6 : index) -> f32 { 22 // CHECK-NOT: subview 23 // CHECK: [[STRIDE1:%.*]] = muli [[ARG3]], [[ARG5]] : index 24 // CHECK: [[INDEX1:%.*]] = addi [[ARG1]], [[STRIDE1]] : index 25 // CHECK: [[STRIDE2:%.*]] = muli [[ARG4]], [[ARG6]] : index 26 // CHECK: [[INDEX2:%.*]] = addi [[ARG2]], [[STRIDE2]] : index 27 // CHECK: load [[ARG0]]{{\[}}[[INDEX1]], [[INDEX2]]{{\]}} 28 %0 = subview %arg0[%arg1, %arg2][4, 4][%arg5, %arg6] : 29 memref<12x32xf32> to memref<4x4xf32, offset:?, strides: [?, ?]> 30 %1 = load %0[%arg3, %arg4] : memref<4x4xf32, offset:?, strides: [?, ?]> 31 return %1 : f32 32} 33 34// CHECK-LABEL: @fold_static_stride_subview_with_store 35// CHECK-SAME: [[ARG0:%.*]]: memref<12x32xf32>, [[ARG1:%.*]]: index, [[ARG2:%.*]]: index, [[ARG3:%.*]]: index, [[ARG4:%.*]]: index, [[ARG5:%.*]]: f32 36func @fold_static_stride_subview_with_store(%arg0 : memref<12x32xf32>, %arg1 : index, %arg2 : index, %arg3 : index, %arg4 : index, %arg5 : f32) { 37 // CHECK-NOT: subview 38 // CHECK: [[C2:%.*]] = constant 2 : index 39 // CHECK: [[C3:%.*]] = constant 3 : index 40 // CHECK: [[STRIDE1:%.*]] = muli [[ARG3]], [[C2]] : index 41 // CHECK: [[INDEX1:%.*]] = addi [[ARG1]], [[STRIDE1]] : index 42 // CHECK: [[STRIDE2:%.*]] = muli [[ARG4]], [[C3]] : index 43 // CHECK: [[INDEX2:%.*]] = addi [[ARG2]], [[STRIDE2]] : index 44 // CHECK: store [[ARG5]], [[ARG0]]{{\[}}[[INDEX1]], [[INDEX2]]{{\]}} 45 %0 = subview %arg0[%arg1, %arg2][4, 4][2, 3] : 46 memref<12x32xf32> to memref<4x4xf32, offset:?, strides: [64, 3]> 47 store %arg5, %0[%arg3, %arg4] : memref<4x4xf32, offset:?, strides: [64, 3]> 48 return 49} 50 51// CHECK-LABEL: @fold_dynamic_stride_subview_with_store 52// CHECK-SAME: [[ARG0:%.*]]: memref<12x32xf32>, [[ARG1:%.*]]: index, [[ARG2:%.*]]: index, [[ARG3:%.*]]: index, [[ARG4:%.*]]: index, [[ARG5:%.*]]: index, [[ARG6:%.*]]: index, [[ARG7:%.*]]: f32 53func @fold_dynamic_stride_subview_with_store(%arg0 : memref<12x32xf32>, %arg1 : index, %arg2 : index, %arg3 : index, %arg4 : index, %arg5 : index, %arg6 : index, %arg7 : f32) { 54 // CHECK-NOT: subview 55 // CHECK: [[STRIDE1:%.*]] = muli [[ARG3]], [[ARG5]] : index 56 // CHECK: [[INDEX1:%.*]] = addi [[ARG1]], [[STRIDE1]] : index 57 // CHECK: [[STRIDE2:%.*]] = muli [[ARG4]], [[ARG6]] : index 58 // CHECK: [[INDEX2:%.*]] = addi [[ARG2]], [[STRIDE2]] : index 59 // CHECK: store [[ARG7]], [[ARG0]]{{\[}}[[INDEX1]], [[INDEX2]]{{\]}} 60 %0 = subview %arg0[%arg1, %arg2][4, 4][%arg5, %arg6] : 61 memref<12x32xf32> to memref<4x4xf32, offset:?, strides: [?, ?]> 62 store %arg7, %0[%arg3, %arg4] : memref<4x4xf32, offset:?, strides: [?, ?]> 63 return 64} 65 66// CHECK-LABEL: @fold_static_stride_subview_with_transfer_read 67// CHECK-SAME: [[ARG0:%.*]]: memref<12x32xf32>, [[ARG1:%.*]]: index, [[ARG2:%.*]]: index, [[ARG3:%.*]]: index, [[ARG4:%.*]]: index 68func @fold_static_stride_subview_with_transfer_read(%arg0 : memref<12x32xf32>, %arg1 : index, %arg2 : index, %arg3 : index, %arg4 : index) -> vector<4xf32> { 69 // CHECK-NOT: subview 70 // CHECK: [[F1:%.*]] = constant 1.000000e+00 : f32 71 // CHECK: [[C2:%.*]] = constant 2 : index 72 // CHECK: [[C3:%.*]] = constant 3 : index 73 // CHECK: [[STRIDE1:%.*]] = muli [[ARG3]], [[C2]] : index 74 // CHECK: [[INDEX1:%.*]] = addi [[ARG1]], [[STRIDE1]] : index 75 // CHECK: [[STRIDE2:%.*]] = muli [[ARG4]], [[C3]] : index 76 // CHECK: [[INDEX2:%.*]] = addi [[ARG2]], [[STRIDE2]] : index 77 // CHECK: vector.transfer_read [[ARG0]]{{\[}}[[INDEX1]], [[INDEX2]]{{\]}}, [[F1]] {masked = [false]} 78 %f1 = constant 1.0 : f32 79 %0 = subview %arg0[%arg1, %arg2][4, 4][2, 3] : memref<12x32xf32> to memref<4x4xf32, offset:?, strides: [64, 3]> 80 %1 = vector.transfer_read %0[%arg3, %arg4], %f1 {masked = [false]} : memref<4x4xf32, offset:?, strides: [64, 3]>, vector<4xf32> 81 return %1 : vector<4xf32> 82} 83 84// CHECK-LABEL: @fold_static_stride_subview_with_transfer_write 85// CHECK-SAME: [[ARG0:%.*]]: memref<12x32xf32>, [[ARG1:%.*]]: index, [[ARG2:%.*]]: index, [[ARG3:%.*]]: index, [[ARG4:%.*]]: index, [[ARG5:%.*]]: vector<4xf32> 86func @fold_static_stride_subview_with_transfer_write(%arg0 : memref<12x32xf32>, %arg1 : index, %arg2 : index, %arg3 : index, %arg4 : index, %arg5 : vector<4xf32>) { 87 // CHECK-NOT: subview 88 // CHECK: [[C2:%.*]] = constant 2 : index 89 // CHECK: [[C3:%.*]] = constant 3 : index 90 // CHECK: [[STRIDE1:%.*]] = muli [[ARG3]], [[C2]] : index 91 // CHECK: [[INDEX1:%.*]] = addi [[ARG1]], [[STRIDE1]] : index 92 // CHECK: [[STRIDE2:%.*]] = muli [[ARG4]], [[C3]] : index 93 // CHECK: [[INDEX2:%.*]] = addi [[ARG2]], [[STRIDE2]] : index 94 // CHECK: vector.transfer_write [[ARG5]], [[ARG0]]{{\[}}[[INDEX1]], [[INDEX2]]{{\]}} {masked = [false]} 95 %0 = subview %arg0[%arg1, %arg2][4, 4][2, 3] : 96 memref<12x32xf32> to memref<4x4xf32, offset:?, strides: [64, 3]> 97 vector.transfer_write %arg5, %0[%arg3, %arg4] {masked = [false]} : vector<4xf32>, memref<4x4xf32, offset:?, strides: [64, 3]> 98 return 99} 100