// RUN: mlir-opt %s --transform-interpreter | FileCheck %s
// CHECK-LABEL: func @nop_shape_cast
// CHECK-SAME: %[[A:.*]]: vector<16xf32>
// CHECK: return %[[A]] : vector<16xf32>
func.func @nop_shape_cast(%arg0: vector<16xf32>) -> vector<16xf32> {
%0 = vector.shape_cast %arg0 : vector<16xf32> to vector<16xf32>
return %0 : vector<16xf32>
}
// CHECK-LABEL: func @cancel_shape_cast
// CHECK-SAME: %[[A:.*]]: vector<16xf32>
// CHECK: return %[[A]] : vector<16xf32>
func.func @cancel_shape_cast(%arg0: vector<16xf32>) -> vector<16xf32> {
%0 = vector.shape_cast %arg0 : vector<16xf32> to vector<4x4xf32>
%1 = vector.shape_cast %0 : vector<4x4xf32> to vector<16xf32>
return %1 : vector<16xf32>
}
// Collapse 2-D to 1-D.
// CHECK-LABEL: func @shape_cast_2d1d
// CHECK-SAME: %[[A:.*]]: vector<2x2xf32>) -> vector<4xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<4xf32>
//
// CHECK: %[[EX0:.*]] = vector.extract %[[A]][0] : vector<2xf32> from vector<2x2xf32>
// CHECK: %[[IN0:.*]] = vector.insert_strided_slice %[[EX0]], %[[UB]]
// CHECK-SAME: {offsets = [0], strides = [1]} : vector<2xf32> into vector<4xf32>
//
// CHECK: %[[EX1:.*]] = vector.extract %{{.*}}[1] : vector<2xf32> from vector<2x2xf32>
// CHECK: %[[IN2:.*]] = vector.insert_strided_slice %[[EX1]], %[[IN0]]
// CHECK-SAME: {offsets = [2], strides = [1]} : vector<2xf32> into vector<4xf32>
// CHECK: return %[[IN2]] : vector<4xf32>
func.func @shape_cast_2d1d(%a: vector<2x2xf32>) -> (vector<4xf32>) {
%0 = vector.shape_cast %a : vector<2x2xf32> to vector<4xf32>
return %0 : vector<4xf32>
}
// Collapse 3-D to 1-D.
// CHECK-LABEL: func @shape_cast_3d1d
// CHECK-SAME: %[[A:.*]]: vector<1x3x2xf32>
// CHECK: %[[UB:.*]] = ub.poison : vector<6xf32>
//
// CHECK: %[[T0:.*]] = vector.extract %[[A]][0, 0] : vector<2xf32> from vector<1x3x2xf32>
// CHECK: %[[T1:.*]] = vector.insert_strided_slice %[[T0]], %[[UB]]
// CHECK-SAME: {offsets = [0], strides = [1]} : vector<2xf32> into vector<6xf32>
//
// CHECK: %[[T2:.*]] = vector.extract %[[A]][0, 1] : vector<2xf32> from vector<1x3x2xf32>
// CHECK: %[[T3:.*]] = vector.insert_strided_slice %[[T2]], %[[T1]]
// CHECK-SAME: {offsets = [2], strides = [1]} : vector<2xf32> into vector<6xf32>
//
// CHECK: %[[T4:.*]] = vector.extract %[[A]][0, 2] : vector<2xf32> from vector<1x3x2xf32>
// CHECK: %[[T5:.*]] = vector.insert_strided_slice %[[T4]], %[[T3]]
// CHECK-SAME: {offsets = [4], strides = [1]} : vector<2xf32> into vector<6xf32>
// CHECK: return %[[T5]] : vector<6xf32>
func.func @shape_cast_3d1d(%arg0 : vector<1x3x2xf32>) -> vector<6xf32> {
%s = vector.shape_cast %arg0 : vector<1x3x2xf32> to vector<6xf32>
return %s : vector<6xf32>
}
// Expand 1-D to 2-D.
// CHECK-LABEL: func.func @shape_cast_1d2d(
// CHECK-SAME: %[[A:.*]]: vector<4xf32>) -> vector<2x2xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<2x2xf32>
//
// CHECK: %[[SS0:.*]] = vector.extract_strided_slice %[[A]]
// CHECK-SAME: {offsets = [0], sizes = [2], strides = [1]} :
// CHECK-SAME: vector<4xf32> to vector<2xf32>
// CHECK: %[[res0:.*]] = vector.insert %[[SS0]], %[[UB]] [0] :
// CHECK-SAME: vector<2xf32> into vector<2x2xf32>
//
// CHECK: %[[SS2:.*]] = vector.extract_strided_slice %[[A]]
// CHECK-SAME: {offsets = [2], sizes = [2], strides = [1]} :
// CHECK-SAME: vector<4xf32> to vector<2xf32>
// CHECK: %[[res1:.*]] = vector.insert %[[SS2]], %[[res0]] [1] :
// CHECK-SAME: vector<2xf32> into vector<2x2xf32>
// CHECK: return %[[res1]] : vector<2x2xf32>
func.func @shape_cast_1d2d(%a: vector<4xf32>) -> (vector<2x2xf32>) {
%1 = vector.shape_cast %a: vector<4xf32> to vector<2x2xf32>
return %1 : vector<2x2xf32>
}
// Expand 1-D to 3-D.
// CHECK-LABEL: func @shape_cast_1d3d
// CHECK-SAME: %[[A:.*]]: vector<6xf32>
// CHECK: %[[UB:.*]] = ub.poison : vector<2x1x3xf32>
//
// CHECK: %[[T0:.*]] = vector.extract_strided_slice %[[A]]
// CHECK-SAME: {offsets = [0], sizes = [3], strides = [1]} :
// CHECK-SAME: vector<6xf32> to vector<3xf32>
// CHECK: %[[T1:.*]] = vector.insert %[[T0]], %[[UB]] [0, 0] :
// CHECK-SAME: vector<3xf32> into vector<2x1x3xf32>
//
// CHECK: %[[T2:.*]] = vector.extract_strided_slice %[[A]]
// CHECK-SAME: {offsets = [3], sizes = [3], strides = [1]} :
// CHECK-SAME: vector<6xf32> to vector<3xf32>
// CHECK: %[[T3:.*]] = vector.insert %[[T2]], %[[T1]] [1, 0] :
// CHECK-SAME: vector<3xf32> into vector<2x1x3xf32>
// CHECK: return %[[T3]] : vector<2x1x3xf32>
func.func @shape_cast_1d3d(%arg0 : vector<6xf32>) -> vector<2x1x3xf32> {
%s = vector.shape_cast %arg0 : vector<6xf32> to vector<2x1x3xf32>
return %s : vector<2x1x3xf32>
}
// 2-D to 2-D where the inner-most dimensions have no common factors. This
// case requires scalar element by element extraction and insertion.
// CHECK-LABEL: func @shape_cast_2d2d
// CHECK-SAME: %[[A:.*]]: vector<3x2xf32>
// CHECK: %[[UB:.*]] = ub.poison : vector<2x3xf32>
//
// CHECK: %[[T0:.*]] = vector.extract %[[A]][0, 0] : f32 from vector<3x2xf32>
// CHECK: %[[T1:.*]] = vector.insert %[[T0]], %[[UB]] [0, 0] :
//
// CHECK: %[[T2:.*]] = vector.extract %[[A]][0, 1] : f32 from vector<3x2xf32>
// CHECK: %[[T3:.*]] = vector.insert %[[T2]], %[[T1]] [0, 1] :
//
// CHECK: %[[T4:.*]] = vector.extract %[[A]][1, 0] : f32 from vector<3x2xf32>
// CHECK: %[[T5:.*]] = vector.insert %[[T4]], %[[T3]] [0, 2] :
//
// CHECK: %[[T6:.*]] = vector.extract %[[A]][1, 1] : f32 from vector<3x2xf32>
// CHECK: %[[T7:.*]] = vector.insert %[[T6]], %[[T5]] [1, 0] :
//
// CHECK: %[[T8:.*]] = vector.extract %[[A]][2, 0] : f32 from vector<3x2xf32>
// CHECK: %[[T9:.*]] = vector.insert %[[T8]], %[[T7]] [1, 1] :
//
// CHECK: %[[T10:.*]] = vector.extract %[[A]][2, 1] : f32 from vector<3x2xf32>
// CHECK: %[[T11:.*]] = vector.insert %[[T10]], %[[T9]] [1, 2] :
//
// CHECK: return %[[T11]] : vector<2x3xf32>
func.func @shape_cast_2d2d(%arg0 : vector<3x2xf32>) -> vector<2x3xf32> {
%s = vector.shape_cast %arg0: vector<3x2xf32> to vector<2x3xf32>
return %s : vector<2x3xf32>
}
// CHECK-LABEL: func.func @shape_cast_0d1d(
// CHECK-SAME: %[[A:.*]]: vector<f32>) -> vector<1xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<1xf32>
//
// CHECK: %[[EXTRACT0:.*]] = vector.extract %[[A]][] : f32 from vector<f32>
// CHECK: %[[RES:.*]] = vector.insert %[[EXTRACT0]], %[[UB]] [0] :
// CHECK: return %[[RES]] : vector<1xf32>
func.func @shape_cast_0d1d(%arg0 : vector<f32>) -> vector<1xf32> {
%s = vector.shape_cast %arg0 : vector<f32> to vector<1xf32>
return %s : vector<1xf32>
}
// CHECK-LABEL: func.func @shape_cast_1d0d(
// CHECK-SAME: %[[A:.*]]: vector<1xf32>) -> vector<f32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<f32>
//
// CHECK: %[[EXTRACT0:.*]] = vector.extract %[[A]][0] : f32 from vector<1xf32>
// CHECK: %[[RES:.*]] = vector.insert %[[EXTRACT0]], %[[UB]] [] :
// CHECK: return %[[RES]] : vector<f32>
func.func @shape_cast_1d0d(%arg0 : vector<1xf32>) -> vector<f32> {
%s = vector.shape_cast %arg0 : vector<1xf32> to vector<f32>
return %s : vector<f32>
}
// The shapes have 2 inner dimension sizes in common, so the extract result is rank-2.
// CHECK-LABEL: func.func @squeeze_out_prefix_unit_dim(
// CHECK-SAME: %[[A:.*]]: vector<1x2x3xf32>) -> vector<2x3xf32> {
//
// CHECK: %[[EXTRACTED:.*]] = vector.extract %[[A]][0] :
// CHECK-SAME: vector<2x3xf32> from vector<1x2x3xf32>
// CHECK: return %[[EXTRACTED]] : vector<2x3xf32>
func.func @squeeze_out_prefix_unit_dim(%arg0 : vector<1x2x3xf32>) -> vector<2x3xf32> {
%s = vector.shape_cast %arg0 : vector<1x2x3xf32> to vector<2x3xf32>
return %s : vector<2x3xf32>
}
// The shapes have 1 inner dimension size in common, so the extract results are rank-1.
// CHECK-LABEL: func.func @squeeze_out_middle_unit_dim(
// CHECK-SAME: %[[A:.*]]: vector<2x1x3xf32>) -> vector<2x3xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<2x3xf32>
//
// CHECK: %[[E0:.*]] = vector.extract %[[A]][0, 0] : vector<3xf32>
// CHECK: %[[I0:.*]] = vector.insert %[[E0]], %[[UB]] [0] :
//
// CHECK: %[[E1:.*]] = vector.extract %[[A]][1, 0] : vector<3xf32>
// CHECK: %[[I1:.*]] = vector.insert %[[E1]], %[[I0]] [1] :
// CHECK: return %[[I1]] : vector<2x3xf32>
func.func @squeeze_out_middle_unit_dim(%arg0 : vector<2x1x3xf32>) -> vector<2x3xf32> {
%s = vector.shape_cast %arg0 : vector<2x1x3xf32> to vector<2x3xf32>
return %s : vector<2x3xf32>
}
// CHECK-LABEL: func.func @prepend_unit_dim(
// CHECK-SAME: %[[A:.*]]: vector<2x3xf32>) -> vector<1x2x3xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<1x2x3xf32>
//
// CHECK: %[[I0:.*]] = vector.insert %[[A]], %[[UB]] [0]
// CHECK: return %[[I0]] : vector<1x2x3xf32>
func.func @prepend_unit_dim(%arg0 : vector<2x3xf32>) -> vector<1x2x3xf32> {
%s = vector.shape_cast %arg0 : vector<2x3xf32> to vector<1x2x3xf32>
return %s : vector<1x2x3xf32>
}
// CHECK-LABEL: func.func @insert_middle_unit_dim(
// CHECK-SAME: %[[A:.*]]: vector<2x3xf32>) -> vector<2x1x3xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<2x1x3xf32>
//
// CHECK: %[[E0:.*]] = vector.extract %[[A]][0] : vector<3xf32>
// CHECK: %[[I0:.*]] = vector.insert %[[E0]], %[[UB]] [0, 0] : vector<3xf32>
//
// CHECK: %[[E1:.*]] = vector.extract %[[A]][1] : vector<3xf32>
// CHECK: %[[I1:.*]] = vector.insert %[[E1]], %[[I0]] [1, 0] : vector<3xf32>
// CHECK: return %[[I1]] : vector<2x1x3xf32>
func.func @insert_middle_unit_dim(%arg0 : vector<2x3xf32>) -> vector<2x1x3xf32> {
%s = vector.shape_cast %arg0 : vector<2x3xf32> to vector<2x1x3xf32>
return %s : vector<2x1x3xf32>
}
// CHECK-LABEL: func.func @postpend_unit_dims(
// CHECK-SAME: %[[A:.*]]: vector<4xf32>) -> vector<4x1x1xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<4x1x1xf32>
// CHECK: %[[E0:.*]] = vector.extract %[[A]][0] : f32 from vector<4xf32>
// CHECK: %[[I0:.*]] = vector.insert %[[E0]], %[[UB]] [0, 0, 0] : f32 into vector<4x1x1xf32>
// CHECK: %[[E1:.*]] = vector.extract %[[A]][1] : f32 from vector<4xf32>
// CHECK: %[[I1:.*]] = vector.insert %[[E1]], %[[I0]] [1, 0, 0] : f32 into vector<4x1x1xf32>
// CHECK: vector.extract %[[A]][2]
// CHECK: vector.insert {{.*}} [2, 0, 0]
// CHECK: vector.extract %[[A]][3]
// CHECK: vector.insert {{.*}} [3, 0, 0]
// CHECK: return
func.func @postpend_unit_dims(%arg0 : vector<4xf32>) -> vector<4x1x1xf32> {
%s = vector.shape_cast %arg0 : vector<4xf32> to vector<4x1x1xf32>
return %s : vector<4x1x1xf32>
}
// CHECK-LABEL: func.func @expand_inner_dims(
// CHECK-SAME: %[[A:.*]]: vector<2x10xf32>) -> vector<2x2x5xf32> {
// CHECK: %[[UB:.*]] = ub.poison : vector<2x2x5xf32>
//
// CHECK: %[[E0:.*]] = vector.extract %[[A]][0] : vector<10xf32>
// CHECK: %[[S0:.*]] = vector.extract_strided_slice %[[E0]]
// CHECK-SAME: {offsets = [0], sizes = [5], {{.*}} to vector<5xf32>
// CHECK: %[[I0:.*]] = vector.insert %[[S0]], %[[UB]] [0, 0]
//
// CHECK: %[[S1:.*]] = vector.extract_strided_slice %[[E0]]
// CHECK-SAME: {offsets = [5], sizes = [5], {{.*}} to vector<5xf32>
// CHECK: %[[I1:.*]] = vector.insert %[[S1]], %[[I0]] [0, 1]
//
// CHECK: %[[E1:.*]] = vector.extract %[[A]][1] : vector<10xf32>
// CHECK: %[[S2:.*]] = vector.extract_strided_slice %[[E1]]
// CHECK-SAME: {offsets = [0], sizes = [5], {{.*}} to vector<5xf32>
// CHECK: %[[I2:.*]] = vector.insert %[[S2]], %[[I1]] [1, 0]
//
// CHECK: %[[S3:.*]] = vector.extract_strided_slice %[[E1]]
// CHECK-SAME: {offsets = [5], sizes = [5], {{.*}} to vector<5xf32>
// CHECK: %[[I3:.*]] = vector.insert %[[S3]], %[[I2]] [1, 1]
// CHECK: return %[[I3]] : vector<2x2x5xf32>
func.func @expand_inner_dims(%arg0 : vector<2x10xf32>) -> vector<2x2x5xf32> {
%s = vector.shape_cast %arg0 : vector<2x10xf32> to vector<2x2x5xf32>
return %s : vector<2x2x5xf32>
}
// Some pseudocode describing how this function is lowered:
//
// func collapse_inner_dims(A : vector<2x2x5xi8>) -> vector<1x2x1x10xi8> {
// v0 = empty of shape (10)
// v1 = empty of shape (1,2,1,10)
// v0[0:5] = A[0,0,:]
// v0[5:10] = A[0,1,:]
// v1[0,0,0,:] = v0
// v0[0:5] = A[1,0,:]
// v0[5:10] = A[1,1,:]
// v1[0,1,0,:] = v0
// return v1;
// }
// CHECK-LABEL: func.func @collapse_inner_dims(
// CHECK-SAME: %[[A:.*]]: vector<2x2x5xi8>) -> vector<1x2x1x10xi8> {
// CHECK-DAG: %[[UBSMALL:.*]] = ub.poison : vector<10xi8>
// CHECK-DAG: %[[UBLARGE:.*]] = ub.poison : vector<1x2x1x10xi8>
//
// CHECK: %[[EX0:.*]] = vector.extract %[[A]][0, 0]
// CHECK: %[[IN0:.*]] = vector.insert_strided_slice %[[EX0]], %[[UBSMALL]]
// CHECK-SAME: {offsets = [0], {{.*}}
// CHECK: %[[EX1:.*]] = vector.extract %[[A]][0, 1]
// CHECK: %[[IN1:.*]] = vector.insert_strided_slice %[[EX1]], %[[IN0]]
// CHECK-SAME: {offsets = [5], {{.*}}
// CHECK: %[[IN2:.*]] = vector.insert %[[IN1]], %[[UBLARGE]] [0, 0, 0]
//
// CHECK: %[[EX2:.*]] = vector.extract %[[A]][1, 0]
// CHECK: %[[IN3:.*]] = vector.insert_strided_slice %[[EX2]], %[[UBSMALL]]
// CHECK-SAME: {offsets = [0], {{.*}}
// CHECK: %[[EX3:.*]] = vector.extract %[[A]][1, 1]
// CHECK: %[[IN4:.*]] = vector.insert_strided_slice %[[EX3]], %[[IN3]]
// CHECK-SAME: {offsets = [5], {{.*}}
// CHECK: %[[IN5:.*]] = vector.insert %[[IN4]], %[[IN2]] [0, 1, 0]
// CHECK: return %[[IN5]] : vector<1x2x1x10xi8>
func.func @collapse_inner_dims(%arg0 : vector<2x2x5xi8>) -> vector<1x2x1x10xi8> {
%s = vector.shape_cast %arg0 : vector<2x2x5xi8> to vector<1x2x1x10xi8>
return %s : vector<1x2x1x10xi8>
}
// Some alternative pseudocode describing how this function is lowered:
//
// func non_dividing_gcd_decreasing(A : vector<2x15xi8>) -> vector<3x10xi8> {
// v0 = empty of shape (10)
// v1 = empty of shape (3,10)
// e0 = A[0,:]
// v0[0:5] = e0[0:5]
// v0[5:10] = e0[5:10]
// v1[0,:] = v0
// v0[0,0:5] = e0[10:15]
// e1 = A[1,:]
// v0[0,5:10] = e1[0:5]
// v1[1,:] = v0
// v0[0,0:5] = e1[5:10]
// v0[0,5:10] = e1[10:15]
// v1[2,:] = v0
// return v1;
// }
// CHECK-LABEL: func.func @non_dividing_gcd_decreasing(
// CHECK-SAME: %[[A:.*]]: vector<2x15xi8>) -> vector<3x10xi8> {
// CHECK-DAG: %[[UB0:.*]] = ub.poison : vector<10xi8>
// CHECK-DAG: %[[UB1:.*]] = ub.poison : vector<3x10xi8>
//
// First 10 elements:
// CHECK: %[[EX0:.*]] = vector.extract %[[A]][0] : vector<15xi8> from vector<2x15xi8>
// CHECK: %[[SS0:.*]] = vector.extract_strided_slice %[[EX0]]
// CHECK-SAME: {offsets = [0], {{.*}} to vector<5xi8>
// CHECK: %[[IN0:.*]] = vector.insert_strided_slice %[[SS0]], %[[UB0]]
// CHECK-SAME: {offsets = [0], {{.*}}
// CHECK: %[[SS1:.*]] = vector.extract_strided_slice %[[EX0]]
// CHECK-SAME: {offsets = [5], {{.*}} to vector<5xi8>
// CHECK: %[[IN1:.*]] = vector.insert_strided_slice %[[SS1]], %[[IN0]]
// CHECK-SAME: {offsets = [5], {{.*}}
// CHECK: %[[IN2:.*]] = vector.insert %[[IN1]], %[[UB1]] [0] : vector<10xi8> into vector<3x10xi8>
//
// Next 10 elements:
// CHECK: %[[SS2:.*]] = vector.extract_strided_slice %[[EX0]]
// CHECK-SAME: {offsets = [10], {{.*}} to vector<5xi8>
// CHECK: %[[IN3:.*]] = vector.insert_strided_slice %[[SS2]], %[[UB0]]
// CHECK-SAME: {offsets = [0], {{.*}}
// CHECK: %[[EX1:.*]] = vector.extract %[[A]][1] : vector<15xi8> from vector<2x15xi8>
// CHECK: %[[SS3:.*]] = vector.extract_strided_slice %[[EX1]]
// CHECK-SAME: {offsets = [0], {{.*}} to vector<5xi8>
// CHECK: %[[IN4:.*]] = vector.insert_strided_slice %[[SS3]], %[[IN3]]
// CHECK-SAME: {offsets = [5], {{.*}}
// CHECK: %[[IN5:.*]] = vector.insert %[[IN4]], %[[IN2]] [1] : vector<10xi8> into vector<3x10xi8>
//
// Final 10 elements:
// CHECK: %[[SS4:.*]] = vector.extract_strided_slice %[[EX1]]
// CHECK-SAME: {offsets = [5], {{.*}} to vector<5xi8>
// CHECK: %[[IN6:.*]] = vector.insert_strided_slice %[[SS4]], %[[UB0]]
// CHECK-SAME: {offsets = [0], {{.*}}
// CHECK: %[[SS5:.*]] = vector.extract_strided_slice %[[EX1]]
// CHECK-SAME: {offsets = [10], {{.*}} to vector<5xi8>
// CHECK: %[[IN7:.*]] = vector.insert_strided_slice %[[SS5]], %[[IN6]]
// CHECK-SAME: {offsets = [5], {{.*}}
// CHECK: %[[IN8:.*]] = vector.insert %[[IN7]], %[[IN5]] [2] : vector<10xi8> into vector<3x10xi8>
// CHECK: return %[[IN8]] : vector<3x10xi8>
func.func @non_dividing_gcd_decreasing(%arg0 : vector<2x15xi8>) -> vector<3x10xi8> {
%0 = vector.shape_cast %arg0 : vector<2x15xi8> to vector<3x10xi8>
return %0 : vector<3x10xi8>
}
// CHECK-LABEL: func.func @non_dividing_gcd_increasing(
// CHECK-SAME: %[[A:.*]]: vector<3x10xi8>) -> vector<2x15xi8> {
//
// CHECK-DAG: ub.poison : vector<15xi8>
// CHECK-DAG: ub.poison : vector<2x15xi8>
//
// Collect the first 15 elements, and insert into the first row of the result.
// CHECK: vector.extract %[[A]][0]
// CHECK: extract_strided_slice
// CHECK: insert_strided_slice
// CHECK: extract_strided_slice
// CHECK: insert_strided_slice
// CHECK: vector.extract %[[A]][1]
// CHECK: extract_strided_slice
// CHECK: insert_strided_slice
// CHECK: vector.insert {{.*}} [0] : vector<15xi8> into vector<2x15xi8>
//
// Collect the next 15 elements, and insert into the second row of the result.
// CHECK: extract_strided_slice
// CHECK: insert_strided_slice
// CHECK: vector.extract %[[A]][2]
// CHECK: extract_strided_slice
// CHECK: insert_strided_slice
// CHECK: extract_strided_slice
// CHECK: insert_strided_slice
// CHECK: vector.insert {{.*}} [1] : vector<15xi8> into vector<2x15xi8>
func.func @non_dividing_gcd_increasing(%arg0 : vector<3x10xi8>) -> vector<2x15xi8> {
%0 = vector.shape_cast %arg0 : vector<3x10xi8> to vector<2x15xi8>
return %0 : vector<2x15xi8>
}
module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {
%f = transform.structured.match ops{["func.func"]} in %module_op
: (!transform.any_op) -> !transform.any_op
transform.apply_patterns to %f {
transform.apply_patterns.vector.lower_shape_cast
} : !transform.any_op
transform.yield
}
}