578 lines · plain
1// RUN: mlir-opt %s -test-vector-unrolling-patterns=unroll-based-on-type | FileCheck %s2// RUN: mlir-opt %s -test-vector-unrolling-patterns="unroll-based-on-type unroll-order=2,0,1" | FileCheck %s --check-prefix=ORDER3// RUN: mlir-opt %s -test-vector-unrolling-patterns="unroll-based-on-type unroll-order=0,3,1,2" | FileCheck %s --check-prefix=BATCHED4 5func.func @vector_contract_f32(%lhs : vector<8x4xf32>, %rhs : vector<8x4xf32>,6 %init : vector<8x8xf32>) -> vector<8x8xf32> {7 %0 = vector.contract8 {indexing_maps = [affine_map<(i, j, k) -> (i, k)>,9 affine_map<(i, j, k) -> (j, k)>,10 affine_map<(i, j, k) -> (i, j)>],11 iterator_types = ["parallel", "parallel", "reduction"]}12 %lhs, %rhs, %init : vector<8x4xf32>, vector<8x4xf32> into vector<8x8xf32>13 return %0 : vector<8x8xf32>14}15// CHECK-LABEL: func @vector_contract_f3216// CHECK-SAME: [[arg0:%.+]]: vector<8x4xf32>, [[arg1:%.+]]: vector<8x4xf32>, [[arg2:%.+]]: vector<8x8xf32>17 18// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]19// CHECK-SAME: offsets = [0, 0]20// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]21// CHECK-SAME: offsets = [0, 0]22// CHECK: [[c:%.+]] = vector.extract_strided_slice [[arg2]]23// CHECK-SAME: offsets = [0, 0]24// CHECK: [[accum1:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]25// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>26 27// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]28// CHECK-SAME: offsets = [0, 2]29// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]30// CHECK-SAME: offsets = [0, 2]31// CHECK: [[accum2:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum1]]32// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>33 34// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]35// CHECK-SAME: offsets = [0, 0]36// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]37// CHECK-SAME: offsets = [4, 0]38// CHECK: [[c:%.+]] = vector.extract_strided_slice [[arg2]]39// CHECK-SAME: offsets = [0, 4]40// CHECK: [[accum3:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]41// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>42 43// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]44// CHECK-SAME: offsets = [0, 2]45// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]46// CHECK-SAME: offsets = [4, 2]47// CHECK: [[accum4:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum3]]48// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>49 50// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]51// CHECK-SAME: offsets = [4, 0]52// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]53// CHECK-SAME: offsets = [0, 0]54// CHECK: [[c:%.+]] = vector.extract_strided_slice [[arg2]]55// CHECK-SAME: offsets = [4, 0]56// CHECK: [[accum5:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]57// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>58 59// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]60// CHECK-SAME: offsets = [4, 2]61// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]62// CHECK-SAME: offsets = [0, 2]63// CHECK: [[accum6:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum5]]64// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>65 66// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]67// CHECK-SAME: offsets = [4, 0]68// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]69// CHECK-SAME: offsets = [4, 0]70// CHECK: [[c:%.+]] = vector.extract_strided_slice [[arg2]]71// CHECK-SAME: offsets = [4, 4]72// CHECK: [[accum7:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]73// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>74 75// CHECK: [[a:%.+]] = vector.extract_strided_slice [[arg0]]76// CHECK-SAME: offsets = [4, 2]77// CHECK: [[b:%.+]] = vector.extract_strided_slice [[arg1]]78// CHECK-SAME: offsets = [4, 2]79// CHECK: [[accum8:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum7]]80// CHECK-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>81 82// CHECK: return83 84// ORDER-LABEL: func @vector_contract_f3285// ORDER-SAME: [[arg0:%.+]]: vector<8x4xf32>, [[arg1:%.+]]: vector<8x4xf32>, [[arg2:%.+]]: vector<8x8xf32>86 87// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]88// ORDER-SAME: offsets = [0, 0]89// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]90// ORDER-SAME: offsets = [0, 0]91// ORDER: [[c:%.+]] = vector.extract_strided_slice [[arg2]]92// ORDER-SAME: offsets = [0, 0]93// ORDER: [[accum1:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]94// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>95 96// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]97// ORDER-SAME: offsets = [0, 0]98// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]99// ORDER-SAME: offsets = [4, 0]100// ORDER: [[c:%.+]] = vector.extract_strided_slice [[arg2]]101// ORDER-SAME: offsets = [0, 4]102// ORDER: [[accum2:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]103// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>104 105// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]106// ORDER-SAME: offsets = [4, 0]107// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]108// ORDER-SAME: offsets = [0, 0]109// ORDER: [[c:%.+]] = vector.extract_strided_slice [[arg2]]110// ORDER-SAME: offsets = [4, 0]111// ORDER: [[accum3:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]112// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>113 114// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]115// ORDER-SAME: offsets = [4, 0]116// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]117// ORDER-SAME: offsets = [4, 0]118// ORDER: [[c:%.+]] = vector.extract_strided_slice [[arg2]]119// ORDER-SAME: offsets = [4, 4]120// ORDER: [[accum4:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[c]]121// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>122 123// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]124// ORDER-SAME: offsets = [0, 2]125// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]126// ORDER-SAME: offsets = [0, 2]127// ORDER: [[accum5:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum1]]128// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>129 130// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]131// ORDER-SAME: offsets = [0, 2]132// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]133// ORDER-SAME: offsets = [4, 2]134// ORDER: [[accum6:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum2]]135// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>136 137// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]138// ORDER-SAME: offsets = [4, 2]139// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]140// ORDER-SAME: offsets = [0, 2]141// ORDER: [[accum7:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum3]]142// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>143 144// ORDER: [[a:%.+]] = vector.extract_strided_slice [[arg0]]145// ORDER-SAME: offsets = [4, 2]146// ORDER: [[b:%.+]] = vector.extract_strided_slice [[arg1]]147// ORDER-SAME: offsets = [4, 2]148// ORDER: [[accum8:%.+]] = vector.contract {{{.*}}} [[a]], [[b]], [[accum4]]149// ORDER-SAME: vector<4x2xf32>, vector<4x2xf32> into vector<4x4xf32>150 151// ORDER: return152 153 154 155func.func @vector_contract_f16(%lhs : vector<8x8xf16>, %rhs : vector<8x8xf16>,156 %init : vector<8x8xf16>) -> vector<8x8xf16> {157 %0 = vector.contract158 {indexing_maps = [affine_map<(i, j, k) -> (i, k)>,159 affine_map<(i, j, k) -> (j, k)>,160 affine_map<(i, j, k) -> (i, j)>],161 iterator_types = ["parallel", "parallel", "reduction"]}162 %lhs, %rhs, %init : vector<8x8xf16>, vector<8x8xf16> into vector<8x8xf16>163 return %0 : vector<8x8xf16>164}165// CHECK-LABEL: func @vector_contract_f16166// CHECK: vector.contract {167// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>168// CHECK: vector.contract {169// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>170// CHECK: vector.contract {171// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>172// CHECK: vector.contract {173// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>174// CHECK: vector.contract {175// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>176// CHECK: vector.contract {177// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>178// CHECK: vector.contract {179// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>180// CHECK: vector.contract {181// CHECK-SAME: vector<4x4xf16>, vector<4x4xf16> into vector<4x4xf16>182// CHECK: return183 184func.func @vector_fma(%a: vector<4x4xf32>, %b: vector<4x4xf32>, %c: vector<4x4xf32>) -> vector<4x4xf32> {185 %0 = vector.fma %a, %b, %c: vector<4x4xf32>186 return %0 : vector<4x4xf32>187}188// CHECK-LABEL: func @vector_fma189// CHECK-COUNT-4: vector.fma %{{.+}}, %{{.+}}, %{{.+}} : vector<2x2xf32>190 191func.func @vector_fma_3d(%a: vector<3x2x2xf32>) -> vector<3x2x2xf32>{192 %0 = vector.fma %a, %a, %a : vector<3x2x2xf32>193 return %0 : vector<3x2x2xf32>194}195// CHECK-LABEL: func @vector_fma_3d196// CHECK-SAME: (%[[SRC:.*]]: vector<3x2x2xf32>) -> vector<3x2x2xf32> {197// CHECK: %[[CST:.*]] = arith.constant dense<0.000000e+00> : vector<3x2x2xf32>198// CHECK: %[[E_LHS_0:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [0, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>199// CHECK: %[[S_LHS_0:.*]] = vector.shape_cast %[[E_LHS_0]] : vector<1x2x2xf32> to vector<2x2xf32>200// CHECK: %[[E_RHS_0:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [0, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>201// CHECK: %[[S_RHS_0:.*]] = vector.shape_cast %[[E_RHS_0]] : vector<1x2x2xf32> to vector<2x2xf32>202// CHECK: %[[E_OUT_0:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [0, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>203// CHECK: %[[S_OUT_0:.*]] = vector.shape_cast %[[E_OUT_0]] : vector<1x2x2xf32> to vector<2x2xf32>204// CHECK: %[[FMA0:.*]] = vector.fma %[[S_LHS_0]], %[[S_RHS_0]], %[[S_OUT_0]] : vector<2x2xf32>205// CHECK: %[[I0:.*]] = vector.insert_strided_slice %[[FMA0]], %[[CST]] {offsets = [0, 0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<3x2x2xf32>206// CHECK: %[[E_LHS_1:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [1, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>207// CHECK: %[[S_LHS_1:.*]] = vector.shape_cast %[[E_LHS_1]] : vector<1x2x2xf32> to vector<2x2xf32>208// CHECK: %[[E_RHS_1:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [1, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>209// CHECK: %[[S_RHS_1:.*]] = vector.shape_cast %[[E_RHS_1]] : vector<1x2x2xf32> to vector<2x2xf32>210// CHECK: %[[E_OUT_1:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [1, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>211// CHECK: %[[S_OUT_1:.*]] = vector.shape_cast %[[E_OUT_1]] : vector<1x2x2xf32> to vector<2x2xf32>212// CHECK: %[[FMA1:.*]] = vector.fma %[[S_LHS_1]], %[[S_RHS_1]], %[[S_OUT_1]] : vector<2x2xf32>213// CHECK: %[[I1:.*]] = vector.insert_strided_slice %[[FMA1]], %[[I0]] {offsets = [1, 0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<3x2x2xf32>214// CHECK: %[[E_LHS_2:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [2, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>215// CHECK: %[[S_LHS_2:.*]] = vector.shape_cast %[[E_LHS_2]] : vector<1x2x2xf32> to vector<2x2xf32>216// CHECK: %[[E_RHS_2:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [2, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>217// CHECK: %[[S_RHS_2:.*]] = vector.shape_cast %[[E_RHS_2]] : vector<1x2x2xf32> to vector<2x2xf32>218// CHECK: %[[E_OUT_2:.*]] = vector.extract_strided_slice %[[SRC]] {offsets = [2, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<3x2x2xf32> to vector<1x2x2xf32>219// CHECK: %[[S_OUT_2:.*]] = vector.shape_cast %[[E_OUT_2]] : vector<1x2x2xf32> to vector<2x2xf32>220// CHECK: %[[FMA2:.*]] = vector.fma %[[S_LHS_2]], %[[S_RHS_2]], %[[S_OUT_2]] : vector<2x2xf32>221// CHECK: %[[I2:.*]] = vector.insert_strided_slice %[[FMA2]], %[[I1]] {offsets = [2, 0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<3x2x2xf32>222// CHECK: return %[[I2]] : vector<3x2x2xf32>223 224func.func @vector_multi_reduction(%v : vector<4x6xf32>, %acc: vector<4xf32>) -> vector<4xf32> {225 %0 = vector.multi_reduction #vector.kind<add>, %v, %acc [1] : vector<4x6xf32> to vector<4xf32>226 return %0 : vector<4xf32>227}228// CHECK-LABEL: func @vector_multi_reduction229// CHECK: %[[V0:.*]] = arith.constant dense<0.000000e+00> : vector<4xf32>230// CHECK: %[[E0:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x6xf32> to vector<2x2xf32>231// CHECK: %[[ACC0:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>232// CHECK: %[[R0:.*]] = vector.multi_reduction <add>, %[[E0]], %[[ACC0]] [1] : vector<2x2xf32> to vector<2xf32>233// CHECK: %[[E1:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x6xf32> to vector<2x2xf32>234// CHECK: %[[R1:.*]] = vector.multi_reduction <add>, %[[E1]], %[[R0]] [1] : vector<2x2xf32> to vector<2xf32>235// CHECK: %[[E2:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0, 4], sizes = [2, 2], strides = [1, 1]} : vector<4x6xf32> to vector<2x2xf32>236// CHECK: %[[R2:.*]] = vector.multi_reduction <add>, %[[E2]], %[[R1]] [1] : vector<2x2xf32> to vector<2xf32>237// CHECK: %[[E3:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [2, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x6xf32> to vector<2x2xf32>238// CHECK: %[[ACC1:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [2], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>239// CHECK: %[[R3:.*]] = vector.multi_reduction <add>, %[[E3]], %[[ACC1]] [1] : vector<2x2xf32> to vector<2xf32>240// CHECK: %[[E4:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x6xf32> to vector<2x2xf32>241// CHECK: %[[R4:.*]] = vector.multi_reduction <add>, %[[E4]], %[[R3]] [1] : vector<2x2xf32> to vector<2xf32>242// CHECK: %[[E5:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [2, 4], sizes = [2, 2], strides = [1, 1]} : vector<4x6xf32> to vector<2x2xf32>243// CHECK: %[[R5:.*]] = vector.multi_reduction <add>, %[[E5]], %[[R4]] [1] : vector<2x2xf32> to vector<2xf32>244// CHECK: %[[V1:.*]] = vector.insert_strided_slice %[[R2]], %[[V0]] {offsets = [0], strides = [1]} : vector<2xf32> into vector<4xf32>245// CHECK: %[[V2:.*]] = vector.insert_strided_slice %[[R5]], %[[V1]] {offsets = [2], strides = [1]} : vector<2xf32> into vector<4xf32>246// CHECK: return %[[V2]] : vector<4xf32>247 248// This is a negative test case to ensure that further unrolling is not performed. Since the vector.multi_reduction249// operation has already been unrolled, attempting additional unrolling should not be allowed.250func.func @negative_vector_multi_reduction(%v: vector<4x2xf32>, %acc: f32) -> f32 {251 %0 = vector.multi_reduction #vector.kind<add>, %v, %acc [0, 1] : vector<4x2xf32> to f32252 return %0 : f32253}254// CHECK-LABEL: func @negative_vector_multi_reduction255// CHECK-NEXT: %[[R0:.*]] = vector.multi_reduction <add>, %{{.*}}, %{{.*}} [0, 1] : vector<4x2xf32> to f32256// CHECK-NEXT: return %[[R0]] : f32257 258func.func @vector_reduction(%v : vector<8xf32>) -> f32 {259 %0 = vector.reduction <add>, %v : vector<8xf32> into f32260 return %0 : f32261}262// CHECK-LABEL: func @vector_reduction(263// CHECK-SAME: %[[v:.*]]: vector<8xf32>264// CHECK: %[[s0:.*]] = vector.extract_strided_slice %[[v]] {offsets = [0], sizes = [2]265// CHECK: %[[r0:.*]] = vector.reduction <add>, %[[s0]]266// CHECK: %[[s1:.*]] = vector.extract_strided_slice %[[v]] {offsets = [2], sizes = [2]267// CHECK: %[[r1:.*]] = vector.reduction <add>, %[[s1]]268// CHECK: %[[add1:.*]] = arith.addf %[[r0]], %[[r1]]269// CHECK: %[[s2:.*]] = vector.extract_strided_slice %[[v]] {offsets = [4], sizes = [2]270// CHECK: %[[r2:.*]] = vector.reduction <add>, %[[s2]]271// CHECK: %[[add2:.*]] = arith.addf %[[add1]], %[[r2]]272// CHECK: %[[s3:.*]] = vector.extract_strided_slice %[[v]] {offsets = [6], sizes = [2]273// CHECK: %[[r3:.*]] = vector.reduction <add>, %[[s3]]274// CHECK: %[[add3:.*]] = arith.addf %[[add2]], %[[r3]]275// CHECK: return %[[add3]]276 277func.func @vector_transpose(%v : vector<2x4x3x8xf32>) -> vector<2x3x8x4xf32> {278 %t = vector.transpose %v, [0, 2, 3, 1] : vector<2x4x3x8xf32> to vector<2x3x8x4xf32>279 return %t : vector<2x3x8x4xf32>280}281// CHECK-LABEL: func @vector_transpose282// CHECK: %[[VI:.*]] = arith.constant dense<0.000000e+00> : vector<2x3x8x4xf32>283// CHECK: %[[E0:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0, 0, 0, 0], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>284// CHECK: %[[T0:.*]] = vector.transpose %[[E0]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>285// CHECK: %[[V0:.*]] = vector.insert_strided_slice %[[T0]], %[[VI]] {offsets = [0, 0, 0, 0], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>286// CHECK: %[[E1:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0, 2, 0, 0], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>287// CHECK: %[[T1:.*]] = vector.transpose %[[E1]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>288// CHECK: %[[V1:.*]] = vector.insert_strided_slice %[[T1]], %[[V0]] {offsets = [0, 0, 0, 2], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>289// CHECK: %[[E2:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0, 0, 0, 4], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>290// CHECK: %[[T2:.*]] = vector.transpose %[[E2]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>291// CHECK: %[[V2:.*]] = vector.insert_strided_slice %[[T2]], %[[V1]] {offsets = [0, 0, 4, 0], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>292// CHECK: %[[E3:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0, 2, 0, 4], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>293// CHECK: %[[T3:.*]] = vector.transpose %[[E3]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>294// CHECK: %[[V3:.*]] = vector.insert_strided_slice %[[T3]], %[[V2]] {offsets = [0, 0, 4, 2], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>295// CHECK: %[[E4:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [1, 0, 0, 0], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>296// CHECK: %[[T4:.*]] = vector.transpose %[[E4]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>297// CHECK: %[[V4:.*]] = vector.insert_strided_slice %[[T4]], %[[V3]] {offsets = [1, 0, 0, 0], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>298// CHECK: %[[E5:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [1, 2, 0, 0], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>299// CHECK: %[[T5:.*]] = vector.transpose %[[E5]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>300// CHECK: %[[V5:.*]] = vector.insert_strided_slice %[[T5]], %[[V4]] {offsets = [1, 0, 0, 2], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>301// CHECK: %[[E6:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [1, 0, 0, 4], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>302// CHECK: %[[T6:.*]] = vector.transpose %[[E6]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>303// CHECK: %[[V6:.*]] = vector.insert_strided_slice %[[T6]], %[[V5]] {offsets = [1, 0, 4, 0], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>304// CHECK: %[[E7:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [1, 2, 0, 4], sizes = [1, 2, 3, 4], strides = [1, 1, 1, 1]} : vector<2x4x3x8xf32> to vector<1x2x3x4xf32>305// CHECK: %[[T7:.*]] = vector.transpose %[[E7]], [0, 2, 3, 1] : vector<1x2x3x4xf32> to vector<1x3x4x2xf32>306// CHECK: %[[V7:.*]] = vector.insert_strided_slice %[[T7]], %[[V6]] {offsets = [1, 0, 4, 2], strides = [1, 1, 1, 1]} : vector<1x3x4x2xf32> into vector<2x3x8x4xf32>307// CHECK: return %[[V7]] : vector<2x3x8x4xf32>308 309// -----310 311func.func @vector_contract_batched(%lhs: vector<8x8x4xf32>, %rhs: vector<8x8x4xf32>, %init: vector<8x8x8xf32>) -> vector<8x8x8xf32> {312 %0 = vector.contract313 {indexing_maps = [affine_map<(d0,d1,d2,c0) -> (d0,d1,c0)>,314 affine_map<(d0,d1,d2,c0) -> (d0,d2,c0)>,315 affine_map<(d0,d1,d2,c0) -> (d0,d1,d2)>],316 iterator_types = ["parallel", "parallel", "parallel", "reduction"]}317 %lhs, %rhs, %init : vector<8x8x4xf32>, vector<8x8x4xf32> into vector<8x8x8xf32>318 return %0 : vector<8x8x8xf32>319}320 321 322// CHECK-LABEL: vector_contract_batched323// CHECK-COUNT-16: vector.contract324// CHECK-NOT: vector.contract325// CHECK: return326 327// UNROLL-LABEL: vector_contract_batched328// UNROLL-COUNT-1: vector.contract329// UNROLL-NOT: vector.contract330// UNROLL: return331 332 333// BATCHED-LABEL: vector_contract_batched334// BATCHED-COUNT-16: vector.contract335// BATCHED-NOT: vector.contract336// BATCHED: return337 338 339func.func @vector_broadcast(%v: vector<4xf32>) -> vector<4x4xf32> {340 %0 = vector.broadcast %v : vector<4xf32> to vector<4x4xf32>341 return %0 : vector<4x4xf32>342}343 344// CHECK-LABEL: func @vector_broadcast345// CHECK-SAME: [[arg0:%.+]]: vector<4xf32>346// CHECK: [[c:%.+]] = arith.constant dense<0.000000e+00> : vector<4x4xf32>347// CHECK: [[s0:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>348// CHECK: [[b0:%.+]] = vector.broadcast [[s0]] : vector<2xf32> to vector<2x2xf32>349// CHECK: [[r0:%.+]] = vector.insert_strided_slice [[b0]], [[c]] {offsets = [0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>350// CHECK: [[s1:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [2], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>351// CHECK: [[b1:%.+]] = vector.broadcast [[s1]] : vector<2xf32> to vector<2x2xf32>352// CHECK: [[r1:%.+]] = vector.insert_strided_slice [[b1]], [[r0]] {offsets = [0, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>353// CHECK: [[s2:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>354// CHECK: [[b2:%.+]] = vector.broadcast [[s2]] : vector<2xf32> to vector<2x2xf32>355// CHECK: [[r2:%.+]] = vector.insert_strided_slice [[b2]], [[r1]] {offsets = [2, 0], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>356// CHECK: [[s3:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [2], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>357// CHECK: [[b3:%.+]] = vector.broadcast [[s3]] : vector<2xf32> to vector<2x2xf32>358// CHECK: [[r3:%.+]] = vector.insert_strided_slice [[b3]], [[r2]] {offsets = [2, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>359// CHECK: return [[r3]] : vector<4x4xf32>360 361func.func @vector_broadcast_with_leading_unit_dim(%v: vector<1x4xf32>) -> vector<4x4xf32> {362 %0 = vector.broadcast %v : vector<1x4xf32> to vector<4x4xf32>363 return %0 : vector<4x4xf32>364}365 366// CHECK-LABEL: func.func @vector_broadcast_with_leading_unit_dim367// CHECK-SAME: ([[arg0:%.+]]: vector<1x4xf32>) -> vector<4x4xf32> {368// CHECK: [[c:%.+]] = arith.constant dense<0.000000e+00> : vector<4x4xf32>369// CHECK: [[s0:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0, 0], sizes = [1, 2], strides = [1, 1]} : vector<1x4xf32> to vector<1x2xf32>370// CHECK: [[b0:%.+]] = vector.broadcast [[s0]] : vector<1x2xf32> to vector<2x2xf32>371// CHECK: [[r0:%.+]] = vector.insert_strided_slice [[b0]], [[c]] {offsets = [0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>372// CHECK: [[s1:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0, 2], sizes = [1, 2], strides = [1, 1]} : vector<1x4xf32> to vector<1x2xf32>373// CHECK: [[b1:%.+]] = vector.broadcast [[s1]] : vector<1x2xf32> to vector<2x2xf32>374// CHECK: [[r1:%.+]] = vector.insert_strided_slice [[b1]], [[r0]] {offsets = [0, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>375// CHECK: [[s2:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0, 0], sizes = [1, 2], strides = [1, 1]} : vector<1x4xf32> to vector<1x2xf32>376// CHECK: [[b2:%.+]] = vector.broadcast [[s2]] : vector<1x2xf32> to vector<2x2xf32>377// CHECK: [[r2:%.+]] = vector.insert_strided_slice [[b2]], [[r1]] {offsets = [2, 0], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>378// CHECK: [[s3:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0, 2], sizes = [1, 2], strides = [1, 1]} : vector<1x4xf32> to vector<1x2xf32>379// CHECK: [[b3:%.+]] = vector.broadcast [[s3]] : vector<1x2xf32> to vector<2x2xf32>380// CHECK: [[r3:%.+]] = vector.insert_strided_slice [[b3]], [[r2]] {offsets = [2, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>381// CHECK: return [[r3]] : vector<4x4xf32>382 383func.func @vector_broadcast_with_tailing_unit_dim(%v: vector<4x1xf32>) -> vector<4x4xf32> {384 %0 = vector.broadcast %v : vector<4x1xf32> to vector<4x4xf32>385 return %0 : vector<4x4xf32>386}387 388// CHECK-LABEL: func.func @vector_broadcast_with_tailing_unit_dim389// CHECK-SAME: ([[arg0:%.+]]: vector<4x1xf32>) -> vector<4x4xf32> {390// CHECK: [[c:%.+]] = arith.constant dense<0.000000e+00> : vector<4x4xf32>391// CHECK: [[s0:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0, 0], sizes = [2, 1], strides = [1, 1]} : vector<4x1xf32> to vector<2x1xf32>392// CHECK: [[b0:%.+]] = vector.broadcast [[s0]] : vector<2x1xf32> to vector<2x2xf32>393// CHECK: [[r0:%.+]] = vector.insert_strided_slice [[b0]], [[c]] {offsets = [0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>394// CHECK: [[s1:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [0, 0], sizes = [2, 1], strides = [1, 1]} : vector<4x1xf32> to vector<2x1xf32>395// CHECK: [[b1:%.+]] = vector.broadcast [[s1]] : vector<2x1xf32> to vector<2x2xf32>396// CHECK: [[r1:%.+]] = vector.insert_strided_slice [[b1]], [[r0]] {offsets = [0, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>397// CHECK: [[s2:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [2, 0], sizes = [2, 1], strides = [1, 1]} : vector<4x1xf32> to vector<2x1xf32>398// CHECK: [[b2:%.+]] = vector.broadcast [[s2]] : vector<2x1xf32> to vector<2x2xf32>399// CHECK: [[r2:%.+]] = vector.insert_strided_slice [[b2]], [[r1]] {offsets = [2, 0], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>400// CHECK: [[s3:%.+]] = vector.extract_strided_slice [[arg0]] {offsets = [2, 0], sizes = [2, 1], strides = [1, 1]} : vector<4x1xf32> to vector<2x1xf32>401// CHECK: [[b3:%.+]] = vector.broadcast [[s3]] : vector<2x1xf32> to vector<2x2xf32>402// CHECK: [[r3:%.+]] = vector.insert_strided_slice [[b3]], [[r2]] {offsets = [2, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>403// CHECK: return [[r3]] : vector<4x4xf32>404 405 406func.func @vector_load_2D(%mem: memref<4x4xf16>) -> vector<4x4xf16> {407 %c0 = arith.constant 0 : index408 %0 = vector.load %mem[%c0, %c0] : memref<4x4xf16>, vector<4x4xf16>409 return %0 : vector<4x4xf16>410}411 412// CHECK-LABEL: func.func @vector_load_2D(413// CHECK-SAME: %[[ARG:.*]]: memref<4x4xf16>) -> vector<4x4xf16> {414 // CHECK: %[[C2:.*]] = arith.constant 2 : index415 // CHECK: %[[C0:.*]] = arith.constant 0 : index416 // CHECK: %[[CST:.*]] = arith.constant dense<0.000000e+00> : vector<4x4xf16>417 // CHECK: %[[V0:.*]] = vector.load %[[ARG]][%[[C0]], %[[C0]]] : memref<4x4xf16>, vector<2x2xf16>418 // CHECK: %[[V1:.*]] = vector.insert_strided_slice %[[V0]], %[[CST]] {offsets = [0, 0], strides = [1, 1]} : vector<2x2xf16> into vector<4x4xf16>419 // CHECK: %[[V2:.*]] = vector.load %[[ARG]][%[[C0]], %[[C2]]] : memref<4x4xf16>, vector<2x2xf16>420 // CHECK: %[[V3:.*]] = vector.insert_strided_slice %[[V2]], %[[V1]] {offsets = [0, 2], strides = [1, 1]} : vector<2x2xf16> into vector<4x4xf16>421 // CHECK: %[[V4:.*]] = vector.load %[[ARG]][%[[C2]], %[[C0]]] : memref<4x4xf16>, vector<2x2xf16>422 // CHECK: %[[V5:.*]] = vector.insert_strided_slice %[[V4]], %[[V3]] {offsets = [2, 0], strides = [1, 1]} : vector<2x2xf16> into vector<4x4xf16>423 // CHECK: %[[V6:.*]] = vector.load %[[ARG]][%[[C2]], %[[C2]]] : memref<4x4xf16>, vector<2x2xf16>424 // CHECK: %[[V7:.*]] = vector.insert_strided_slice %[[V6]], %[[V5]] {offsets = [2, 2], strides = [1, 1]} : vector<2x2xf16> into vector<4x4xf16>425 // CHECK: return %[[V7]] : vector<4x4xf16>426 427 428func.func @vector_store_2D(%mem: memref<4x4xf16>, %v: vector<4x4xf16>) {429 %c0 = arith.constant 0 : index430 vector.store %v, %mem[%c0, %c0] : memref<4x4xf16>, vector<4x4xf16>431 return432}433 434// CHECK-LABEL: func.func @vector_store_2D(435// CHECK-SAME: %[[ARG0:.*]]: memref<4x4xf16>, %[[ARG1:.*]]: vector<4x4xf16>) {436 // CHECK: %[[C2:.*]] = arith.constant 2 : index437 // CHECK: %[[C0:.*]] = arith.constant 0 : index438 // CHECK: %[[V0:.*]] = vector.extract_strided_slice %[[ARG1]] {offsets = [0, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x4xf16> to vector<2x2xf16>439 // CHECK: vector.store %[[V0]], %[[ARG0]][%[[C0]], %[[C0]]] : memref<4x4xf16>, vector<2x2xf16>440 // CHECK: %[[V1:.*]] = vector.extract_strided_slice %[[ARG1]] {offsets = [0, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x4xf16> to vector<2x2xf16>441 // CHECK: vector.store %[[V1]], %[[ARG0]][%[[C0]], %[[C2]]] : memref<4x4xf16>, vector<2x2xf16>442 // CHECK: %[[V2:.*]] = vector.extract_strided_slice %[[ARG1]] {offsets = [2, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x4xf16> to vector<2x2xf16>443 // CHECK: vector.store %[[V2]], %[[ARG0]][%[[C2]], %[[C0]]] : memref<4x4xf16>, vector<2x2xf16>444 // CHECK: %[[V3:.*]] = vector.extract_strided_slice %[[ARG1]] {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x4xf16> to vector<2x2xf16>445 // CHECK: vector.store %[[V3]], %[[ARG0]][%[[C2]], %[[C2]]] : memref<4x4xf16>, vector<2x2xf16>446 447 448func.func @vector_step() -> vector<32xindex> {449 %0 = vector.step : vector<32xindex>450 return %0 : vector<32xindex>451}452// CHECK-LABEL: func @vector_step453// CHECK: %[[CST:.*]] = arith.constant dense<24> : vector<8xindex>454// CHECK: %[[CST0:.*]] = arith.constant dense<16> : vector<8xindex>455// CHECK: %[[CST1:.*]] = arith.constant dense<8> : vector<8xindex>456// CHECK: %[[CST2:.*]] = arith.constant dense<0> : vector<32xindex>457// CHECK: %[[STEP:.*]] = vector.step : vector<8xindex>458// CHECK: %[[INS0:.*]] = vector.insert_strided_slice %[[STEP]], %[[CST2]] {offsets = [0], strides = [1]} : vector<8xindex> into vector<32xindex>459// CHECK: %[[ADD1:.*]] = arith.addi %[[STEP]], %[[CST1]] : vector<8xindex>460// CHECK: %[[INS1:.*]] = vector.insert_strided_slice %[[ADD1]], %[[INS0]] {offsets = [8], strides = [1]} : vector<8xindex> into vector<32xindex>461// CHECK: %[[ADD2:.*]] = arith.addi %[[STEP]], %[[CST0]] : vector<8xindex>462// CHECK: %[[INS2:.*]] = vector.insert_strided_slice %[[ADD2]], %[[INS1]] {offsets = [16], strides = [1]} : vector<8xindex> into vector<32xindex>463// CHECK: %[[ADD3:.*]] = arith.addi %[[STEP]], %[[CST]] : vector<8xindex>464// CHECK: %[[INS3:.*]] = vector.insert_strided_slice %[[ADD3]], %[[INS2]] {offsets = [24], strides = [1]} : vector<8xindex> into vector<32xindex>465// CHECK: return %[[INS3]] : vector<32xindex>466 467 468func.func @elementwise_3D_to_2D(%v1: vector<2x2x2xf32>, %v2: vector<2x2x2xf32>) -> vector<2x2x2xf32> {469 %0 = arith.addf %v1, %v2 : vector<2x2x2xf32>470 return %0 : vector<2x2x2xf32>471}472// CHECK-LABEL: func @elementwise_3D_to_2D473// CHECK-SAME: (%[[ARG0:.*]]: vector<2x2x2xf32>, %[[ARG1:.*]]: vector<2x2x2xf32>) -> vector<2x2x2xf32> {474// CHECK: %[[CST:.*]] = arith.constant dense<0.000000e+00> : vector<2x2x2xf32>475// CHECK: %[[E_LHS_0:.*]] = vector.extract_strided_slice %[[ARG0]] {offsets = [0, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<2x2x2xf32> to vector<1x2x2xf32>476// CHECK: %[[S_LHS_0:.*]] = vector.shape_cast %[[E_LHS_0]] : vector<1x2x2xf32> to vector<2x2xf32>477// CHECK: %[[E_RHS_0:.*]] = vector.extract_strided_slice %[[ARG1]] {offsets = [0, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<2x2x2xf32> to vector<1x2x2xf32>478// CHECK: %[[S_RHS_0:.*]] = vector.shape_cast %[[E_RHS_0]] : vector<1x2x2xf32> to vector<2x2xf32>479// CHECK: %[[ADD0:.*]] = arith.addf %[[S_LHS_0]], %[[S_RHS_0]] : vector<2x2xf32>480// CHECK: %[[I0:.*]] = vector.insert_strided_slice %[[ADD0]], %[[CST]] {offsets = [0, 0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<2x2x2xf32>481// CHECK: %[[E_LHS_1:.*]] = vector.extract_strided_slice %[[ARG0]] {offsets = [1, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<2x2x2xf32> to vector<1x2x2xf32>482// CHECK: %[[S_LHS_1:.*]] = vector.shape_cast %[[E_LHS_1]] : vector<1x2x2xf32> to vector<2x2xf32>483// CHECK: %[[E_RHS_1:.*]] = vector.extract_strided_slice %[[ARG1]] {offsets = [1, 0, 0], sizes = [1, 2, 2], strides = [1, 1, 1]} : vector<2x2x2xf32> to vector<1x2x2xf32>484// CHECK: %[[S_RHS_1:.*]] = vector.shape_cast %[[E_RHS_1]] : vector<1x2x2xf32> to vector<2x2xf32>485// CHECK: %[[ADD1:.*]] = arith.addf %[[S_LHS_1]], %[[S_RHS_1]] : vector<2x2xf32>486// CHECK: %[[I1:.*]] = vector.insert_strided_slice %[[ADD1]], %[[I0]] {offsets = [1, 0, 0], strides = [1, 1]} : vector<2x2xf32> into vector<2x2x2xf32>487// CHECK: return %[[I1]] : vector<2x2x2xf32>488 489 490func.func @elementwise_4D_to_2D(%v1: vector<2x2x2x2xf32>, %v2: vector<2x2x2x2xf32>) -> vector<2x2x2x2xf32> {491 %0 = arith.addf %v1, %v2 : vector<2x2x2x2xf32>492 return %0 : vector<2x2x2x2xf32>493}494 495// CHECK-LABEL: func @elementwise_4D_to_2D496// CHECK-COUNT-4: arith.addf %{{.*}}, %{{.*}} : vector<2x2xf32>497// CHECK-NOT: arith.addf498// CHECK: return499 500 501func.func @shape_cast_1D(%v: vector<16xf32>) -> vector<2x2x4xf32> {502 %0 = vector.shape_cast %v : vector<16xf32> to vector<2x2x4xf32>503 return %0 : vector<2x2x4xf32>504}505 506// CHECK-LABEL: func @shape_cast_1D507// CHECK-SAME: (%[[V:.*]]: vector<16xf32>) -> vector<2x2x4xf32> {508// CHECK: %[[CST:.*]] = arith.constant dense<0.000000e+00> : vector<2x2x4xf32>509// CHECK: %[[S0:.*]] = vector.extract_strided_slice %[[V]] {offsets = [0], sizes = [8], strides = [1]} : vector<16xf32> to vector<8xf32>510// CHECK: %[[SC0:.*]] = vector.shape_cast %[[S0]] : vector<8xf32> to vector<2x4xf32>511// CHECK: %[[I0:.*]] = vector.insert_strided_slice %[[SC0]], %[[CST]] {offsets = [0, 0, 0], strides = [1, 1]} : vector<2x4xf32> into vector<2x2x4xf32>512// CHECK: %[[S1:.*]] = vector.extract_strided_slice %[[V]] {offsets = [8], sizes = [8], strides = [1]} : vector<16xf32> to vector<8xf32>513// CHECK: %[[SC1:.*]] = vector.shape_cast %[[S1]] : vector<8xf32> to vector<2x4xf32>514// CHECK: %[[I1:.*]] = vector.insert_strided_slice %[[SC1]], %[[I0]] {offsets = [1, 0, 0], strides = [1, 1]} : vector<2x4xf32> into vector<2x2x4xf32>515// CHECK: return %[[I1]] : vector<2x2x4xf32>516 517 518func.func @shape_cast_2D(%v: vector<8x2xf32>) -> vector<4x4xf32> {519 %0 = vector.shape_cast %v : vector<8x2xf32> to vector<4x4xf32>520 return %0 : vector<4x4xf32>521}522 523// CHECK-LABEL: func @shape_cast_2D524// CHECK-SAME: (%[[V:.*]]: vector<8x2xf32>) -> vector<4x4xf32> {525// CHECK: %[[CST:.*]] = arith.constant dense<0.000000e+00> : vector<4x4xf32>526// CHECK: %[[S0:.*]] = vector.extract_strided_slice %[[V]] {offsets = [0, 0], sizes = [4, 2], strides = [1, 1]} : vector<8x2xf32> to vector<4x2xf32>527// CHECK: %[[SC0:.*]] = vector.shape_cast %[[S0]] : vector<4x2xf32> to vector<2x4xf32>528// CHECK: %[[I0:.*]] = vector.insert_strided_slice %[[SC0]], %[[CST]] {offsets = [0, 0], strides = [1, 1]} : vector<2x4xf32> into vector<4x4xf32>529// CHECK: %[[S1:.*]] = vector.extract_strided_slice %[[V]] {offsets = [4, 0], sizes = [4, 2], strides = [1, 1]} : vector<8x2xf32> to vector<4x2xf32>530// CHECK: %[[SC1:.*]] = vector.shape_cast %[[S1]] : vector<4x2xf32> to vector<2x4xf32>531// CHECK: %[[I1:.*]] = vector.insert_strided_slice %[[SC1]], %[[I0]] {offsets = [2, 0], strides = [1, 1]} : vector<2x4xf32> into vector<4x4xf32>532// CHECK: return %[[I1]] : vector<4x4xf32>533 534 535// This is a negative test case to ensure that such shape casts are not unrolled536// because the targetShape (2x4) is not contiguous in result vector537func.func @negative_shape_cast_target_shape_not_contiguous(%v: vector<64xf32>) -> vector<8x8xf32> {538 %0 = vector.shape_cast %v : vector<64xf32> to vector<8x8xf32>539 return %0 : vector<8x8xf32>540}541 542// CHECK-LABEL: func @negative_shape_cast_target_shape_not_contiguous543// CHECK-SAME: (%[[V:.*]]: vector<64xf32>) -> vector<8x8xf32> {544// CHECK: %[[SC:.*]] = vector.shape_cast %[[V]] : vector<64xf32> to vector<8x8xf32>545// CHECK: return %[[SC]] : vector<8x8xf32>546 547 548// This is negative test case to ensure that such shape casts are not unrolled549// because it cannot determine the extractShape from source vector (8x3)550// to extract conitguous targetShape (2x4)551func.func @negative_shape_cast_source_shape_not_determinable(%v: vector<8x3xf32>) -> vector<6x4xf32> {552 %0 = vector.shape_cast %v : vector<8x3xf32> to vector<6x4xf32>553 return %0 : vector<6x4xf32>554}555 556// CHECK-LABEL: func @negative_shape_cast_source_shape_not_determinable557// CHECK-SAME: (%[[V:.*]]: vector<8x3xf32>) -> vector<6x4xf32> {558// CHECK: %[[SC:.*]] = vector.shape_cast %[[V]] : vector<8x3xf32> to vector<6x4xf32>559// CHECK: return %[[SC]] : vector<6x4xf32>560 561 562// TargetShape is [1x16]563func.func @shape_cast_leading_unit_dim(%v: vector<32xf32>) -> vector<1x32xf32> {564 %0 = vector.shape_cast %v : vector<32xf32> to vector<1x32xf32>565 return %0 : vector<1x32xf32>566}567 568// CHECK-LABEL: func @shape_cast_leading_unit_dim569// CHECK-SAME: (%[[V:.*]]: vector<32xf32>) -> vector<1x32xf32> {570// CHECK: %[[CST:.*]] = arith.constant dense<0.000000e+00> : vector<1x32xf32>571// CHECK: %[[S0:.*]] = vector.extract_strided_slice %[[V]] {offsets = [0], sizes = [16], strides = [1]} : vector<32xf32> to vector<16xf32>572// CHECK: %[[SC0:.*]] = vector.shape_cast %[[S0]] : vector<16xf32> to vector<1x16xf32>573// CHECK: %[[I0:.*]] = vector.insert_strided_slice %[[SC0]], %[[CST]] {offsets = [0, 0], strides = [1, 1]} : vector<1x16xf32> into vector<1x32xf32>574// CHECK: %[[S1:.*]] = vector.extract_strided_slice %[[V]] {offsets = [16], sizes = [16], strides = [1]} : vector<32xf32> to vector<16xf32>575// CHECK: %[[SC1:.*]] = vector.shape_cast %[[S1]] : vector<16xf32> to vector<1x16xf32>576// CHECK: %[[I1:.*]] = vector.insert_strided_slice %[[SC1]], %[[I0]] {offsets = [0, 16], strides = [1, 1]} : vector<1x16xf32> into vector<1x32xf32>577// CHECK: return %[[I1]] : vector<1x32xf32>578