1831 lines · plain
1// RUN: mlir-opt %s -convert-vector-to-llvm -split-input-file | FileCheck %s2 3//===========================================================================//4// Complex tests for Vector-to-LLVM conversion5//6// These examples, in order to convert to LLVM, require7// * `populateVectorToLLVMConversionPatterns`.8// as well as various other patterns/conversion that are part of9// `ConvertVectorToLLVMPass`.10//11// Please, in the first instance, always try adding tests in12// vector-to-llvm-interface.mlir instead.13//===========================================================================//14 15//===----------------------------------------------------------------------===//16// vector.bitcast17//===----------------------------------------------------------------------===//18 19// CHECK-LABEL: func.func @bitcast_2d(20// CHECK-SAME: %[[ARG_0:.*]]: vector<2x4xi32>) -> vector<2x2xi64> {21// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : vector<2x4xi32> to !llvm.array<2 x vector<4xi32>>22// CHECK: %[[VEC_1:.*]] = llvm.extractvalue %[[T0]][0] : !llvm.array<2 x vector<4xi32>>23// CHECK: %[[BCAST_1:.*]] = llvm.bitcast %[[VEC_1]] : vector<4xi32> to vector<2xi64>24// CHECK: %[[OUT_1:.*]] = llvm.insertvalue %[[BCAST_1]], {{.*}}[0] : !llvm.array<2 x vector<2xi64>>25// CHECK: %[[VEC_2:.*]] = llvm.extractvalue %[[T0]][1] : !llvm.array<2 x vector<4xi32>>26// CHECK: %[[BCAST_2:.*]] = llvm.bitcast %[[VEC_2]] : vector<4xi32> to vector<2xi64>27// CHECK: %[[OUT_2:.*]] = llvm.insertvalue %[[BCAST_2]], %[[OUT_1]][1] : !llvm.array<2 x vector<2xi64>>28func.func @bitcast_2d(%arg0: vector<2x4xi32>) -> vector<2x2xi64> {29 %0 = vector.bitcast %arg0 : vector<2x4xi32> to vector<2x2xi64>30 return %0 : vector<2x2xi64>31}32 33// -----34 35// CHECK-LABEL: func.func @bitcast_2d_scalable(36// CHECK-SAME: %[[ARG_0:.*]]: vector<2x[4]xi32>) -> vector<2x[2]xi64> {37// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : vector<2x[4]xi32> to !llvm.array<2 x vector<[4]xi32>>38// CHECK: %[[VEC_1:.*]] = llvm.extractvalue %[[T0]][0] : !llvm.array<2 x vector<[4]xi32>>39// CHECK: %[[BCAST_1:.*]] = llvm.bitcast %[[VEC_1]] : vector<[4]xi32> to vector<[2]xi64>40// CHECK: %[[OUT_1:.*]] = llvm.insertvalue %[[BCAST_1]], {{.*}}[0] : !llvm.array<2 x vector<[2]xi64>>41// CHECK: %[[VEC_2:.*]] = llvm.extractvalue %[[T0]][1] : !llvm.array<2 x vector<[4]xi32>>42// CHECK: %[[BCAST_2:.*]] = llvm.bitcast %[[VEC_2]] : vector<[4]xi32> to vector<[2]xi64>43// CHECK: %[[OUT_2:.*]] = llvm.insertvalue %[[BCAST_2]], %[[OUT_1]][1] : !llvm.array<2 x vector<[2]xi64>>44func.func @bitcast_2d_scalable(%arg0: vector<2x[4]xi32>) -> vector<2x[2]xi64> {45 %0 = vector.bitcast %arg0 : vector<2x[4]xi32> to vector<2x[2]xi64>46 return %0 : vector<2x[2]xi64>47}48 49// -----50 51//===----------------------------------------------------------------------===//52// vector.broadcast53//===----------------------------------------------------------------------===//54 55func.func @broadcast_vec0d_from_f32(%arg0: f32) -> vector<f32> {56 %0 = vector.broadcast %arg0 : f32 to vector<f32>57 return %0 : vector<f32>58}59// CHECK-LABEL: @broadcast_vec0d_from_f3260// CHECK-SAME: %[[A:.*]]: f32)61// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]62// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<1xf32> to vector<f32>63// CHECK: return %[[T1]] : vector<f32>64 65// -----66 67func.func @broadcast_vec1d_from_f32(%arg0: f32) -> vector<2xf32> {68 %0 = vector.broadcast %arg0 : f32 to vector<2xf32>69 return %0 : vector<2xf32>70}71// CHECK-LABEL: @broadcast_vec1d_from_f3272// CHECK-SAME: %[[A:.*]]: f32)73// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]74// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]75// CHECK: return %[[T1]] : vector<2xf32>76 77// -----78 79func.func @broadcast_single_elem_vec1d_from_f32(%arg0: f32) -> vector<1xf32> {80 %0 = vector.broadcast %arg0 : f32 to vector<1xf32>81 return %0 : vector<1xf32>82}83// CHECK-LABEL: @broadcast_single_elem_vec1d_from_f3284// CHECK-SAME: %[[A:.*]]: f32)85// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]86// CHECK-NOT: llvm.shufflevector87// CHECK: return %[[T0]] : vector<1xf32>88 89// -----90 91func.func @broadcast_vec1d_from_f32_scalable(%arg0: f32) -> vector<[2]xf32> {92 %0 = vector.broadcast %arg0 : f32 to vector<[2]xf32>93 return %0 : vector<[2]xf32>94}95// CHECK-LABEL: @broadcast_vec1d_from_f32_scalable96// CHECK-SAME: %[[A:.*]]: f32)97// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]98// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]99// CHECK: return %[[T1]] : vector<[2]xf32>100 101// -----102 103func.func @broadcast_vec1d_from_index(%arg0: index) -> vector<2xindex> {104 %0 = vector.broadcast %arg0 : index to vector<2xindex>105 return %0 : vector<2xindex>106}107// CHECK-LABEL: @broadcast_vec1d_from_index108// CHECK-SAME: %[[A:.*]]: index)109// CHECK: %[[A1:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64110// CHECK: %[[T0:.*]] = llvm.insertelement %[[A1]]111// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]112// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<2xi64> to vector<2xindex>113// CHECK: return %[[T2]] : vector<2xindex>114 115// -----116 117func.func @broadcast_vec1d_from_index_scalable(%arg0: index) -> vector<[2]xindex> {118 %0 = vector.broadcast %arg0 : index to vector<[2]xindex>119 return %0 : vector<[2]xindex>120}121// CHECK-LABEL: @broadcast_vec1d_from_index_scalable122// CHECK-SAME: %[[A:.*]]: index)123// CHECK: %[[A1:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64124// CHECK: %[[T0:.*]] = llvm.insertelement %[[A1]]125// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]126// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<[2]xi64> to vector<[2]xindex>127// CHECK: return %[[T2]] : vector<[2]xindex>128 129// -----130 131func.func @broadcast_vec2d_from_scalar(%arg0: f32) -> vector<2x3xf32> {132 %0 = vector.broadcast %arg0 : f32 to vector<2x3xf32>133 return %0 : vector<2x3xf32>134}135// CHECK-LABEL: @broadcast_vec2d_from_scalar(136// CHECK-SAME: %[[A:.*]]: f32)137// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]138// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]139// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0] : !llvm.array<2 x vector<3xf32>>140// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1] : !llvm.array<2 x vector<3xf32>>141// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32>142// CHECK: return %[[T4]] : vector<2x3xf32>143 144// -----145 146func.func @broadcast_vec2d_from_scalar_scalable(%arg0: f32) -> vector<2x[3]xf32> {147 %0 = vector.broadcast %arg0 : f32 to vector<2x[3]xf32>148 return %0 : vector<2x[3]xf32>149}150// CHECK-LABEL: @broadcast_vec2d_from_scalar_scalable(151// CHECK-SAME: %[[A:.*]]: f32)152// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]153// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]154// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0] : !llvm.array<2 x vector<[3]xf32>>155// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1] : !llvm.array<2 x vector<[3]xf32>>156// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x vector<[3]xf32>> to vector<2x[3]xf32>157// CHECK: return %[[T4]] : vector<2x[3]xf32>158 159// -----160 161func.func @broadcast_vec3d_from_scalar(%arg0: f32) -> vector<2x3x4xf32> {162 %0 = vector.broadcast %arg0 : f32 to vector<2x3x4xf32>163 return %0 : vector<2x3x4xf32>164}165// CHECK-LABEL: @broadcast_vec3d_from_scalar(166// CHECK-SAME: %[[A:.*]]: f32)167// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]168// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]169// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0, 0] : !llvm.array<2 x array<3 x vector<4xf32>>>170// ...171// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1, 2] : !llvm.array<2 x array<3 x vector<4xf32>>>172// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x array<3 x vector<4xf32>>> to vector<2x3x4xf32>173// CHECK: return %[[T4]] : vector<2x3x4xf32>174 175// -----176 177func.func @broadcast_vec3d_from_scalar_scalable(%arg0: f32) -> vector<2x3x[4]xf32> {178 %0 = vector.broadcast %arg0 : f32 to vector<2x3x[4]xf32>179 return %0 : vector<2x3x[4]xf32>180}181// CHECK-LABEL: @broadcast_vec3d_from_scalar_scalable(182// CHECK-SAME: %[[A:.*]]: f32)183// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]]184// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]]185// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0, 0] : !llvm.array<2 x array<3 x vector<[4]xf32>>>186// ...187// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1, 2] : !llvm.array<2 x array<3 x vector<[4]xf32>>>188// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x array<3 x vector<[4]xf32>>> to vector<2x3x[4]xf32>189// CHECK: return %[[T4]] : vector<2x3x[4]xf32>190 191// -----192 193func.func @broadcast_vec2d_from_vec0d(%arg0: vector<f32>) -> vector<3x2xf32> {194 %0 = vector.broadcast %arg0 : vector<f32> to vector<3x2xf32>195 return %0 : vector<3x2xf32>196}197// CHECK-LABEL: @broadcast_vec2d_from_vec0d(198// CHECK-SAME: %[[A:.*]]: vector<f32>)199// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<f32> to vector<1xf32>200// CHECK: %[[T1:.*]] = ub.poison : vector<3x2xf32>201// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>202// CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64203// CHECK: %[[T5:.*]] = llvm.extractelement %[[T0]][%[[T4]] : i64] : vector<1xf32>204// CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]]205// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]]206// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T6]], %[[T2]][0] : !llvm.array<3 x vector<2xf32>>207// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][1] : !llvm.array<3 x vector<2xf32>>208// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T6]], %[[T8]][2] : !llvm.array<3 x vector<2xf32>>209// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T9]] : !llvm.array<3 x vector<2xf32>> to vector<3x2xf32>210// CHECK: return %[[T10]] : vector<3x2xf32>211 212// -----213 214func.func @broadcast_vec2d_from_vec1d(%arg0: vector<2xf32>) -> vector<3x2xf32> {215 %0 = vector.broadcast %arg0 : vector<2xf32> to vector<3x2xf32>216 return %0 : vector<3x2xf32>217}218// CHECK-LABEL: @broadcast_vec2d_from_vec1d(219// CHECK-SAME: %[[A:.*]]: vector<2xf32>)220// CHECK: %[[T0:.*]] = ub.poison : vector<3x2xf32>221// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>222// CHECK: %[[T2:.*]] = llvm.insertvalue %[[A]], %[[T1]][0] : !llvm.array<3 x vector<2xf32>>223// CHECK: %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][1] : !llvm.array<3 x vector<2xf32>>224// CHECK: %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][2] : !llvm.array<3 x vector<2xf32>>225// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : !llvm.array<3 x vector<2xf32>> to vector<3x2xf32>226// CHECK: return %[[T5]] : vector<3x2xf32>227 228// -----229 230func.func @broadcast_vec2d_from_vec1d_scalable(%arg0: vector<[2]xf32>) -> vector<3x[2]xf32> {231 %0 = vector.broadcast %arg0 : vector<[2]xf32> to vector<3x[2]xf32>232 return %0 : vector<3x[2]xf32>233}234// CHECK-LABEL: @broadcast_vec2d_from_vec1d_scalable(235// CHECK-SAME: %[[A:.*]]: vector<[2]xf32>)236// CHECK: %[[T0:.*]] = ub.poison : vector<3x[2]xf32>237// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x[2]xf32> to !llvm.array<3 x vector<[2]xf32>>238// CHECK: %[[T2:.*]] = llvm.insertvalue %[[A]], %[[T1]][0] : !llvm.array<3 x vector<[2]xf32>>239// CHECK: %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][1] : !llvm.array<3 x vector<[2]xf32>>240// CHECK: %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][2] : !llvm.array<3 x vector<[2]xf32>>241// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : !llvm.array<3 x vector<[2]xf32>> to vector<3x[2]xf32>242// CHECK: return %[[T5]] : vector<3x[2]xf32>243 244// -----245 246func.func @broadcast_vec2d_from_index_vec1d(%arg0: vector<2xindex>) -> vector<3x2xindex> {247 %0 = vector.broadcast %arg0 : vector<2xindex> to vector<3x2xindex>248 return %0 : vector<3x2xindex>249}250// CHECK-LABEL: @broadcast_vec2d_from_index_vec1d(251// CHECK-SAME: %[[A:.*]]: vector<2xindex>)252// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2xindex> to vector<2xi64>253// CHECK: %[[T0:.*]] = ub.poison : vector<3x2xindex>254// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xindex> to !llvm.array<3 x vector<2xi64>>255// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<3 x vector<2xi64>>256 257// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %{{.*}} : !llvm.array<3 x vector<2xi64>> to vector<3x2xindex>258// CHECK: return %[[T4]] : vector<3x2xindex>259 260// -----261 262func.func @broadcast_vec2d_from_index_vec1d_scalable(%arg0: vector<[2]xindex>) -> vector<3x[2]xindex> {263 %0 = vector.broadcast %arg0 : vector<[2]xindex> to vector<3x[2]xindex>264 return %0 : vector<3x[2]xindex>265}266// CHECK-LABEL: @broadcast_vec2d_from_index_vec1d_scalable(267// CHECK-SAME: %[[A:.*]]: vector<[2]xindex>)268// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<[2]xindex> to vector<[2]xi64>269// CHECK: %[[T0:.*]] = ub.poison : vector<3x[2]xindex>270// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x[2]xindex> to !llvm.array<3 x vector<[2]xi64>>271// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<3 x vector<[2]xi64>>272 273// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %{{.*}} : !llvm.array<3 x vector<[2]xi64>> to vector<3x[2]xindex>274// CHECK: return %[[T4]] : vector<3x[2]xindex>275 276// -----277 278func.func @broadcast_vec3d_from_vec1d(%arg0: vector<2xf32>) -> vector<4x3x2xf32> {279 %0 = vector.broadcast %arg0 : vector<2xf32> to vector<4x3x2xf32>280 return %0 : vector<4x3x2xf32>281}282// CHECK-LABEL: @broadcast_vec3d_from_vec1d(283// CHECK-SAME: %[[A:.*]]: vector<2xf32>)284// CHECK-DAG: %[[T0:.*]] = ub.poison : vector<3x2xf32>285// CHECK-DAG: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>286// CHECK-DAG: %[[T1:.*]] = ub.poison : vector<4x3x2xf32>287// CHECK-DAG: %[[T6:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>>288 289// CHECK: %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][0] : !llvm.array<3 x vector<2xf32>>290// CHECK: %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][1] : !llvm.array<3 x vector<2xf32>>291// CHECK: %[[T5:.*]] = llvm.insertvalue %[[A]], %[[T4]][2] : !llvm.array<3 x vector<2xf32>>292 293// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T5]], %[[T6]][0] : !llvm.array<4 x array<3 x vector<2xf32>>>294// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T5]], %[[T7]][1] : !llvm.array<4 x array<3 x vector<2xf32>>>295// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T5]], %[[T8]][2] : !llvm.array<4 x array<3 x vector<2xf32>>>296// CHECK: %[[T10:.*]] = llvm.insertvalue %[[T5]], %[[T9]][3] : !llvm.array<4 x array<3 x vector<2xf32>>>297 298// CHECK: %[[T11:.*]] = builtin.unrealized_conversion_cast %[[T10]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32>299// CHECK: return %[[T11]] : vector<4x3x2xf32>300 301// -----302 303func.func @broadcast_vec3d_from_vec1d_scalable(%arg0: vector<[2]xf32>) -> vector<4x3x[2]xf32> {304 %0 = vector.broadcast %arg0 : vector<[2]xf32> to vector<4x3x[2]xf32>305 return %0 : vector<4x3x[2]xf32>306}307// CHECK-LABEL: @broadcast_vec3d_from_vec1d_scalable(308// CHECK-SAME: %[[A:.*]]: vector<[2]xf32>)309// CHECK-DAG: %[[T0:.*]] = ub.poison : vector<3x[2]xf32>310// CHECK-DAG: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x[2]xf32> to !llvm.array<3 x vector<[2]xf32>>311// CHECK-DAG: %[[T1:.*]] = ub.poison : vector<4x3x[2]xf32>312// CHECK-DAG: %[[T6:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x[2]xf32> to !llvm.array<4 x array<3 x vector<[2]xf32>>>313 314// CHECK: %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][0] : !llvm.array<3 x vector<[2]xf32>>315// CHECK: %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][1] : !llvm.array<3 x vector<[2]xf32>>316// CHECK: %[[T5:.*]] = llvm.insertvalue %[[A]], %[[T4]][2] : !llvm.array<3 x vector<[2]xf32>>317 318// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T5]], %[[T6]][0] : !llvm.array<4 x array<3 x vector<[2]xf32>>>319// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T5]], %[[T7]][1] : !llvm.array<4 x array<3 x vector<[2]xf32>>>320// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T5]], %[[T8]][2] : !llvm.array<4 x array<3 x vector<[2]xf32>>>321// CHECK: %[[T10:.*]] = llvm.insertvalue %[[T5]], %[[T9]][3] : !llvm.array<4 x array<3 x vector<[2]xf32>>>322 323// CHECK: %[[T11:.*]] = builtin.unrealized_conversion_cast %[[T10]] : !llvm.array<4 x array<3 x vector<[2]xf32>>> to vector<4x3x[2]xf32>324// CHECK: return %[[T11]] : vector<4x3x[2]xf32>325 326// -----327 328func.func @broadcast_vec3d_from_vec2d(%arg0: vector<3x2xf32>) -> vector<4x3x2xf32> {329 %0 = vector.broadcast %arg0 : vector<3x2xf32> to vector<4x3x2xf32>330 return %0 : vector<4x3x2xf32>331}332// CHECK-LABEL: @broadcast_vec3d_from_vec2d(333// CHECK-SAME: %[[A:.*]]: vector<3x2xf32>)334// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>335// CHECK: %[[T0:.*]] = ub.poison : vector<4x3x2xf32>336// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>>337// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<4 x array<3 x vector<2xf32>>>338// CHECK: %[[T5:.*]] = llvm.insertvalue %[[T1]], %[[T3]][1] : !llvm.array<4 x array<3 x vector<2xf32>>>339// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T1]], %[[T5]][2] : !llvm.array<4 x array<3 x vector<2xf32>>>340// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T1]], %[[T7]][3] : !llvm.array<4 x array<3 x vector<2xf32>>>341// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T9]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32>342// CHECK: return %[[T10]] : vector<4x3x2xf32>343 344// -----345 346func.func @broadcast_vec3d_from_vec2d_scalable(%arg0: vector<3x[2]xf32>) -> vector<4x3x[2]xf32> {347 %0 = vector.broadcast %arg0 : vector<3x[2]xf32> to vector<4x3x[2]xf32>348 return %0 : vector<4x3x[2]xf32>349}350// CHECK-LABEL: @broadcast_vec3d_from_vec2d_scalable(351// CHECK-SAME: %[[A:.*]]: vector<3x[2]xf32>)352// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<3x[2]xf32> to !llvm.array<3 x vector<[2]xf32>>353// CHECK: %[[T0:.*]] = ub.poison : vector<4x3x[2]xf32>354// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<4x3x[2]xf32> to !llvm.array<4 x array<3 x vector<[2]xf32>>>355// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<4 x array<3 x vector<[2]xf32>>>356// CHECK: %[[T5:.*]] = llvm.insertvalue %[[T1]], %[[T3]][1] : !llvm.array<4 x array<3 x vector<[2]xf32>>>357// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T1]], %[[T5]][2] : !llvm.array<4 x array<3 x vector<[2]xf32>>>358// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T1]], %[[T7]][3] : !llvm.array<4 x array<3 x vector<[2]xf32>>>359// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T9]] : !llvm.array<4 x array<3 x vector<[2]xf32>>> to vector<4x3x[2]xf32>360// CHECK: return %[[T10]] : vector<4x3x[2]xf32>361 362 363// -----364 365func.func @broadcast_stretch(%arg0: vector<1xf32>) -> vector<4xf32> {366 %0 = vector.broadcast %arg0 : vector<1xf32> to vector<4xf32>367 return %0 : vector<4xf32>368}369// CHECK-LABEL: @broadcast_stretch(370// CHECK-SAME: %[[A:.*]]: vector<1xf32>)371// CHECK: %[[T1:.*]] = llvm.mlir.constant(0 : i64) : i64372// CHECK: %[[T2:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T1]] : i64] : vector<1xf32>373// CHECK: %[[T3:.*]] = llvm.insertelement %[[T2]]374// CHECK: %[[T4:.*]] = llvm.shufflevector %[[T3]]375// CHECK: return %[[T4]] : vector<4xf32>376 377// -----378 379func.func @broadcast_stretch_scalable(%arg0: vector<1xf32>) -> vector<[4]xf32> {380 %0 = vector.broadcast %arg0 : vector<1xf32> to vector<[4]xf32>381 return %0 : vector<[4]xf32>382}383// CHECK-LABEL: @broadcast_stretch_scalable(384// CHECK-SAME: %[[A:.*]]: vector<1xf32>)385// CHECK: %[[T1:.*]] = llvm.mlir.constant(0 : i64) : i64386// CHECK: %[[T2:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T1]] : i64] : vector<1xf32>387// CHECK: %[[T3:.*]] = llvm.insertelement %[[T2]]388// CHECK: %[[T4:.*]] = llvm.shufflevector %[[T3]]389// CHECK: return %[[T4]] : vector<[4]xf32>390 391// -----392 393func.func @broadcast_stretch_at_start(%arg0: vector<1x4xf32>) -> vector<3x4xf32> {394 %0 = vector.broadcast %arg0 : vector<1x4xf32> to vector<3x4xf32>395 return %0 : vector<3x4xf32>396}397// CHECK-LABEL: @broadcast_stretch_at_start(398// CHECK-SAME: %[[A:.*]]: vector<1x4xf32>)399// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x4xf32> to !llvm.array<1 x vector<4xf32>>400// CHECK: %[[T1:.*]] = ub.poison : vector<3x4xf32>401// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<3x4xf32> to !llvm.array<3 x vector<4xf32>>402// CHECK: %[[T3:.*]] = llvm.extractvalue %[[T2]][0] : !llvm.array<1 x vector<4xf32>>403// CHECK: %[[T5:.*]] = llvm.insertvalue %[[T3]], %[[T4]][0] : !llvm.array<3 x vector<4xf32>>404// CHECK: %[[T6:.*]] = llvm.insertvalue %[[T3]], %[[T5]][1] : !llvm.array<3 x vector<4xf32>>405// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T3]], %[[T6]][2] : !llvm.array<3 x vector<4xf32>>406// CHECK: %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T7]] : !llvm.array<3 x vector<4xf32>> to vector<3x4xf32>407// CHECK: return %[[T8]] : vector<3x4xf32>408 409// -----410 411func.func @broadcast_stretch_at_start_scalable(%arg0: vector<1x[4]xf32>) -> vector<3x[4]xf32> {412 %0 = vector.broadcast %arg0 : vector<1x[4]xf32> to vector<3x[4]xf32>413 return %0 : vector<3x[4]xf32>414}415// CHECK-LABEL: @broadcast_stretch_at_start_scalable(416// CHECK-SAME: %[[A:.*]]: vector<1x[4]xf32>)417// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x[4]xf32> to !llvm.array<1 x vector<[4]xf32>>418// CHECK: %[[T1:.*]] = ub.poison : vector<3x[4]xf32>419// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<3x[4]xf32> to !llvm.array<3 x vector<[4]xf32>>420// CHECK: %[[T3:.*]] = llvm.extractvalue %[[T2]][0] : !llvm.array<1 x vector<[4]xf32>>421// CHECK: %[[T5:.*]] = llvm.insertvalue %[[T3]], %[[T4]][0] : !llvm.array<3 x vector<[4]xf32>>422// CHECK: %[[T6:.*]] = llvm.insertvalue %[[T3]], %[[T5]][1] : !llvm.array<3 x vector<[4]xf32>>423// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T3]], %[[T6]][2] : !llvm.array<3 x vector<[4]xf32>>424// CHECK: %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T7]] : !llvm.array<3 x vector<[4]xf32>> to vector<3x[4]xf32>425// CHECK: return %[[T8]] : vector<3x[4]xf32>426 427// -----428 429func.func @broadcast_stretch_at_end(%arg0: vector<4x1xf32>) -> vector<4x3xf32> {430 %0 = vector.broadcast %arg0 : vector<4x1xf32> to vector<4x3xf32>431 return %0 : vector<4x3xf32>432}433// CHECK-LABEL: @broadcast_stretch_at_end(434// CHECK-SAME: %[[A:.*]]: vector<4x1xf32>)435// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4x1xf32> to !llvm.array<4 x vector<1xf32>>436// CHECK: %[[T1:.*]] = ub.poison : vector<4x3xf32>437// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3xf32> to !llvm.array<4 x vector<3xf32>>438// CHECK: %[[T3:.*]] = llvm.extractvalue %[[T2]][0] : !llvm.array<4 x vector<1xf32>>439// CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64440// CHECK: %[[T5:.*]] = llvm.extractelement %[[T3]]{{\[}}%[[T4]] : i64] : vector<1xf32>441// CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]]442// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]]443// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][0] : !llvm.array<4 x vector<3xf32>>444// CHECK: %[[T10:.*]] = llvm.extractvalue %[[T2]][1] : !llvm.array<4 x vector<1xf32>>445// CHECK: %[[T11:.*]] = llvm.mlir.constant(0 : i64) : i64446// CHECK: %[[T12:.*]] = llvm.extractelement %[[T10]]{{\[}}%[[T11]] : i64] : vector<1xf32>447// CHECK: %[[T13Insert:.*]] = llvm.insertelement %[[T12]]448// CHECK: %[[T13:.*]] = llvm.shufflevector %[[T13Insert]]449// CHECK: %[[T14:.*]] = llvm.insertvalue %[[T13]], %[[T8]][1] : !llvm.array<4 x vector<3xf32>>450// CHECK: %[[T16:.*]] = llvm.extractvalue %[[T2]][2] : !llvm.array<4 x vector<1xf32>>451// CHECK: %[[T17:.*]] = llvm.mlir.constant(0 : i64) : i64452// CHECK: %[[T18:.*]] = llvm.extractelement %[[T16]]{{\[}}%[[T17]] : i64] : vector<1xf32>453// CHECK: %[[T19Insert:.*]] = llvm.insertelement %[[T18]]454// CHECK: %[[T19:.*]] = llvm.shufflevector %[[T19Insert]]455// CHECK: %[[T20:.*]] = llvm.insertvalue %[[T19]], %[[T14]][2] : !llvm.array<4 x vector<3xf32>>456// CHECK: %[[T22:.*]] = llvm.extractvalue %[[T2]][3] : !llvm.array<4 x vector<1xf32>>457// CHECK: %[[T23:.*]] = llvm.mlir.constant(0 : i64) : i64458// CHECK: %[[T24:.*]] = llvm.extractelement %[[T22]]{{\[}}%[[T23]] : i64] : vector<1xf32>459// CHECK: %[[T25Insert:.*]] = llvm.insertelement %[[T24]]460// CHECK: %[[T25:.*]] = llvm.shufflevector %[[T25Insert]]461// CHECK: %[[T26:.*]] = llvm.insertvalue %[[T25]], %[[T20]][3] : !llvm.array<4 x vector<3xf32>>462// CHECK: %[[T27:.*]] = builtin.unrealized_conversion_cast %[[T26]] : !llvm.array<4 x vector<3xf32>> to vector<4x3xf32>463// CHECK: return %[[T27]] : vector<4x3xf32>464 465// TODO: Add support for scalable vectors466 467func.func @broadcast_stretch_at_end_scalable(%arg0: vector<[4]x1xf32>) -> vector<[4]x3xf32> {468 %0 = vector.broadcast %arg0 : vector<[4]x1xf32> to vector<[4]x3xf32>469 return %0 : vector<[4]x3xf32>470}471// CHECK-LABEL: @broadcast_stretch_at_end_scalable472// CHECK-SAME: %[[A:.*]]: vector<[4]x1xf32>)473// CHECK: vector.broadcast %[[A]] : vector<[4]x1xf32> to vector<[4]x3xf32>474 475// -----476 477func.func @broadcast_stretch_in_middle(%arg0: vector<4x1x2xf32>) -> vector<4x3x2xf32> {478 %0 = vector.broadcast %arg0 : vector<4x1x2xf32> to vector<4x3x2xf32>479 return %0 : vector<4x3x2xf32>480}481// CHECK-LABEL: @broadcast_stretch_in_middle(482// CHECK-SAME: %[[A:.*]]: vector<4x1x2xf32>) -> vector<4x3x2xf32> {483// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4x1x2xf32> to !llvm.array<4 x array<1 x vector<2xf32>>>484// CHECK: %[[T1:.*]] = ub.poison : vector<4x3x2xf32>485// CHECK: %[[T9:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>>486// CHECK: %[[T2:.*]] = ub.poison : vector<3x2xf32>487// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>488// CHECK: %[[T4:.*]] = llvm.extractvalue %[[T3]][0, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>489// CHECK: %[[T6:.*]] = llvm.insertvalue %[[T4]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>490// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T4]], %[[T6]][1] : !llvm.array<3 x vector<2xf32>>491// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T4]], %[[T7]][2] : !llvm.array<3 x vector<2xf32>>492// CHECK: %[[T10:.*]] = llvm.insertvalue %[[T8]], %[[T9]][0] : !llvm.array<4 x array<3 x vector<2xf32>>>493// CHECK: %[[T12:.*]] = llvm.extractvalue %[[T3]][1, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>494// CHECK: %[[T14:.*]] = llvm.insertvalue %[[T12]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>495// CHECK: %[[T15:.*]] = llvm.insertvalue %[[T12]], %[[T14]][1] : !llvm.array<3 x vector<2xf32>>496// CHECK: %[[T16:.*]] = llvm.insertvalue %[[T12]], %[[T15]][2] : !llvm.array<3 x vector<2xf32>>497// CHECK: %[[T17:.*]] = llvm.insertvalue %[[T16]], %[[T10]][1] : !llvm.array<4 x array<3 x vector<2xf32>>>498// CHECK: %[[T19:.*]] = llvm.extractvalue %[[T3]][2, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>499// CHECK: %[[T21:.*]] = llvm.insertvalue %[[T19]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>500// CHECK: %[[T22:.*]] = llvm.insertvalue %[[T19]], %[[T21]][1] : !llvm.array<3 x vector<2xf32>>501// CHECK: %[[T23:.*]] = llvm.insertvalue %[[T19]], %[[T22]][2] : !llvm.array<3 x vector<2xf32>>502// CHECK: %[[T24:.*]] = llvm.insertvalue %[[T23]], %[[T17]][2] : !llvm.array<4 x array<3 x vector<2xf32>>>503// CHECK: %[[T26:.*]] = llvm.extractvalue %[[T3]][3, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>504// CHECK: %[[T28:.*]] = llvm.insertvalue %[[T26]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>505// CHECK: %[[T29:.*]] = llvm.insertvalue %[[T26]], %[[T28]][1] : !llvm.array<3 x vector<2xf32>>506// CHECK: %[[T30:.*]] = llvm.insertvalue %[[T26]], %[[T29]][2] : !llvm.array<3 x vector<2xf32>>507// CHECK: %[[T31:.*]] = llvm.insertvalue %[[T30]], %[[T24]][3] : !llvm.array<4 x array<3 x vector<2xf32>>>508// CHECK: %[[T32:.*]] = builtin.unrealized_conversion_cast %[[T31]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32>509// CHECK: return %[[T32]] : vector<4x3x2xf32>510 511// -----512 513func.func @broadcast_stretch_in_middle_scalable_v1(%arg0: vector<4x1x[2]xf32>) -> vector<4x3x[2]xf32> {514 %0 = vector.broadcast %arg0 : vector<4x1x[2]xf32> to vector<4x3x[2]xf32>515 return %0 : vector<4x3x[2]xf32>516}517// CHECK-LABEL: @broadcast_stretch_in_middle_scalable_v1(518// CHECK-SAME: %[[A:.*]]: vector<4x1x[2]xf32>) -> vector<4x3x[2]xf32> {519// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4x1x[2]xf32> to !llvm.array<4 x array<1 x vector<[2]xf32>>>520// CHECK: %[[T1:.*]] = ub.poison : vector<4x3x[2]xf32>521// CHECK: %[[T9:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x[2]xf32> to !llvm.array<4 x array<3 x vector<[2]xf32>>>522// CHECK: %[[T2:.*]] = ub.poison : vector<3x[2]xf32>523// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<3x[2]xf32> to !llvm.array<3 x vector<[2]xf32>>524// CHECK: %[[T4:.*]] = llvm.extractvalue %[[T3]][0, 0] : !llvm.array<4 x array<1 x vector<[2]xf32>>>525// CHECK: %[[T6:.*]] = llvm.insertvalue %[[T4]], %[[T5]][0] : !llvm.array<3 x vector<[2]xf32>>526// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T4]], %[[T6]][1] : !llvm.array<3 x vector<[2]xf32>>527// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T4]], %[[T7]][2] : !llvm.array<3 x vector<[2]xf32>>528// CHECK: %[[T10:.*]] = llvm.insertvalue %[[T8]], %[[T9]][0] : !llvm.array<4 x array<3 x vector<[2]xf32>>>529// CHECK: %[[T12:.*]] = llvm.extractvalue %[[T3]][1, 0] : !llvm.array<4 x array<1 x vector<[2]xf32>>>530// CHECK: %[[T14:.*]] = llvm.insertvalue %[[T12]], %[[T5]][0] : !llvm.array<3 x vector<[2]xf32>>531// CHECK: %[[T15:.*]] = llvm.insertvalue %[[T12]], %[[T14]][1] : !llvm.array<3 x vector<[2]xf32>>532// CHECK: %[[T16:.*]] = llvm.insertvalue %[[T12]], %[[T15]][2] : !llvm.array<3 x vector<[2]xf32>>533// CHECK: %[[T17:.*]] = llvm.insertvalue %[[T16]], %[[T10]][1] : !llvm.array<4 x array<3 x vector<[2]xf32>>>534// CHECK: %[[T19:.*]] = llvm.extractvalue %[[T3]][2, 0] : !llvm.array<4 x array<1 x vector<[2]xf32>>>535// CHECK: %[[T21:.*]] = llvm.insertvalue %[[T19]], %[[T5]][0] : !llvm.array<3 x vector<[2]xf32>>536// CHECK: %[[T22:.*]] = llvm.insertvalue %[[T19]], %[[T21]][1] : !llvm.array<3 x vector<[2]xf32>>537// CHECK: %[[T23:.*]] = llvm.insertvalue %[[T19]], %[[T22]][2] : !llvm.array<3 x vector<[2]xf32>>538// CHECK: %[[T24:.*]] = llvm.insertvalue %[[T23]], %[[T17]][2] : !llvm.array<4 x array<3 x vector<[2]xf32>>>539// CHECK: %[[T26:.*]] = llvm.extractvalue %[[T3]][3, 0] : !llvm.array<4 x array<1 x vector<[2]xf32>>>540// CHECK: %[[T28:.*]] = llvm.insertvalue %[[T26]], %[[T5]][0] : !llvm.array<3 x vector<[2]xf32>>541// CHECK: %[[T29:.*]] = llvm.insertvalue %[[T26]], %[[T28]][1] : !llvm.array<3 x vector<[2]xf32>>542// CHECK: %[[T30:.*]] = llvm.insertvalue %[[T26]], %[[T29]][2] : !llvm.array<3 x vector<[2]xf32>>543// CHECK: %[[T31:.*]] = llvm.insertvalue %[[T30]], %[[T24]][3] : !llvm.array<4 x array<3 x vector<[2]xf32>>>544// CHECK: %[[T32:.*]] = builtin.unrealized_conversion_cast %[[T31]] : !llvm.array<4 x array<3 x vector<[2]xf32>>> to vector<4x3x[2]xf32>545// CHECK: return %[[T32]] : vector<4x3x[2]xf32>546 547// -----548 549// TODO: Add support for scalable vectors550 551func.func @broadcast_stretch_in_middle_scalable_v2(%arg0: vector<[4]x1x2xf32>) -> vector<[4]x3x2xf32> {552 %0 = vector.broadcast %arg0 : vector<[4]x1x2xf32> to vector<[4]x3x2xf32>553 return %0 : vector<[4]x3x2xf32>554}555// CHECK-LABEL: @broadcast_stretch_in_middle_scalable_v2(556// CHECK-SAME: %[[A:.*]]: vector<[4]x1x2xf32>) -> vector<[4]x3x2xf32> {557// CHECK: vector.broadcast %[[A]] : vector<[4]x1x2xf32> to vector<[4]x3x2xf32>558 559// -----560 561//===----------------------------------------------------------------------===//562// vector.outerproduct563//===----------------------------------------------------------------------===//564 565func.func @outerproduct(%arg0: vector<2xf32>, %arg1: vector<3xf32>) -> vector<2x3xf32> {566 %2 = vector.outerproduct %arg0, %arg1 : vector<2xf32>, vector<3xf32>567 return %2 : vector<2x3xf32>568}569// CHECK-LABEL: @outerproduct(570// CHECK-SAME: %[[A:.*]]: vector<2xf32>,571// CHECK-SAME: %[[B:.*]]: vector<3xf32>)572// CHECK: %[[T2:.*]] = arith.constant dense<0.000000e+00> : vector<2x3xf32>573// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>>574// CHECK: %[[T3:.*]] = llvm.mlir.constant(0 : i64) : i64575// CHECK: %[[T4:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T3]] : i64] : vector<2xf32>576// CHECK: %[[T5Insert:.*]] = llvm.insertelement %[[T4]]577// CHECK: %[[T5:.*]] = llvm.shufflevector %[[T5Insert]]578// CHECK: %[[T6:.*]] = arith.mulf %[[T5]], %[[B]] : vector<3xf32>579// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][0] : !llvm.array<2 x vector<3xf32>>580// CHECK: %[[T9:.*]] = llvm.mlir.constant(1 : i64) : i64581// CHECK: %[[T10:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T9]] : i64] : vector<2xf32>582// CHECK: %[[T11Insert:.*]] = llvm.insertelement %[[T10]]583// CHECK: %[[T11:.*]] = llvm.shufflevector %[[T11Insert]]584// CHECK: %[[T12:.*]] = arith.mulf %[[T11]], %[[B]] : vector<3xf32>585// CHECK: %[[T13:.*]] = llvm.insertvalue %[[T12]], %[[T8]][1] : !llvm.array<2 x vector<3xf32>>586// CHECK: %[[T14:.*]] = builtin.unrealized_conversion_cast %[[T13]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32>587// CHECK: return %[[T14]] : vector<2x3xf32>588 589// -----590 591func.func @outerproduct_scalable(%arg0: vector<2xf32>, %arg1: vector<[3]xf32>) -> vector<2x[3]xf32> {592 %2 = vector.outerproduct %arg0, %arg1 : vector<2xf32>, vector<[3]xf32>593 return %2 : vector<2x[3]xf32>594}595// CHECK-LABEL: @outerproduct_scalable596// CHECK-SAME: %[[A:.*]]: vector<2xf32>,597// CHECK-SAME: %[[B:.*]]: vector<[3]xf32>)598// CHECK: %[[T2:.*]] = arith.constant dense<0.000000e+00> : vector<2x[3]xf32>599// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<2x[3]xf32> to !llvm.array<2 x vector<[3]xf32>>600// CHECK: %[[T3:.*]] = llvm.mlir.constant(0 : i64) : i64601// CHECK: %[[T4:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T3]] : i64] : vector<2xf32>602// CHECK: %[[T5Insert:.*]] = llvm.insertelement %[[T4]]603// CHECK: %[[T5:.*]] = llvm.shufflevector %[[T5Insert]]604// CHECK: %[[T6:.*]] = arith.mulf %[[T5]], %[[B]] : vector<[3]xf32>605// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][0] : !llvm.array<2 x vector<[3]xf32>>606// CHECK: %[[T9:.*]] = llvm.mlir.constant(1 : i64) : i64607// CHECK: %[[T10:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T9]] : i64] : vector<2xf32>608// CHECK: %[[T11Insert:.*]] = llvm.insertelement %[[T10]]609// CHECK: %[[T11:.*]] = llvm.shufflevector %[[T11Insert]]610// CHECK: %[[T12:.*]] = arith.mulf %[[T11]], %[[B]] : vector<[3]xf32>611// CHECK: %[[T13:.*]] = llvm.insertvalue %[[T12]], %[[T8]][1] : !llvm.array<2 x vector<[3]xf32>>612// CHECK: %[[T14:.*]] = builtin.unrealized_conversion_cast %[[T13]] : !llvm.array<2 x vector<[3]xf32>> to vector<2x[3]xf32>613// CHECK: return %[[T14]] : vector<2x[3]xf32>614 615// -----616 617func.func @outerproduct_index(%arg0: vector<2xindex>, %arg1: vector<3xindex>) -> vector<2x3xindex> {618 %2 = vector.outerproduct %arg0, %arg1 : vector<2xindex>, vector<3xindex>619 return %2 : vector<2x3xindex>620}621// CHECK-LABEL: @outerproduct_index(622// CHECK-SAME: %[[A:.*]]: vector<2xindex>,623// CHECK-SAME: %[[B:.*]]: vector<3xindex>)624// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2xindex> to vector<2xi64>625// CHECK: %[[T0:.*]] = arith.constant dense<0> : vector<2x3xindex>626// CHECK: %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<2x3xindex> to !llvm.array<2 x vector<3xi64>>627// CHECK: %[[T2:.*]] = llvm.mlir.constant(0 : i64) : i64628// CHECK: %[[T3:.*]] = llvm.extractelement %[[T1]]{{\[}}%[[T2]] : i64] : vector<2xi64>629// CHECK: %[[T4:.*]] = llvm.insertelement %[[T3]]630// CHECK: %[[T5:.*]] = llvm.shufflevector %[[T4]]631// CHECK: %[[T5Cast:.*]] = builtin.unrealized_conversion_cast %[[T5]] : vector<3xi64> to vector<3xindex>632// CHECK: %[[T6:.*]] = arith.muli %[[T5Cast]], %[[B]] : vector<3xindex>633// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T6]] : vector<3xindex> to vector<3xi64>634// CHECK: %{{.*}} = llvm.insertvalue %[[T7]], %[[T8]][0] : !llvm.array<2 x vector<3xi64>>635 636// -----637 638func.func @outerproduct_index_scalable(%arg0: vector<2xindex>, %arg1: vector<[3]xindex>) -> vector<2x[3]xindex> {639 %2 = vector.outerproduct %arg0, %arg1 : vector<2xindex>, vector<[3]xindex>640 return %2 : vector<2x[3]xindex>641}642// CHECK-LABEL: @outerproduct_index_scalable643// CHECK-SAME: %[[A:.*]]: vector<2xindex>,644// CHECK-SAME: %[[B:.*]]: vector<[3]xindex>)645// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2xindex> to vector<2xi64>646// CHECK: %[[T0:.*]] = arith.constant dense<0> : vector<2x[3]xindex>647// CHECK: %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<2x[3]xindex> to !llvm.array<2 x vector<[3]xi64>>648// CHECK: %[[T2:.*]] = llvm.mlir.constant(0 : i64) : i64649// CHECK: %[[T3:.*]] = llvm.extractelement %[[T1]]{{\[}}%[[T2]] : i64] : vector<2xi64>650// CHECK: %[[T4:.*]] = llvm.insertelement %[[T3]]651// CHECK: %[[T5:.*]] = llvm.shufflevector %[[T4]]652// CHECK: %[[T5Cast:.*]] = builtin.unrealized_conversion_cast %[[T5]] : vector<[3]xi64> to vector<[3]xindex>653// CHECK: %[[T6:.*]] = arith.muli %[[T5Cast]], %[[B]] : vector<[3]xindex>654// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T6]] : vector<[3]xindex> to vector<[3]xi64>655// CHECK: %{{.*}} = llvm.insertvalue %[[T7]], %[[T8]][0] : !llvm.array<2 x vector<[3]xi64>>656 657// -----658 659func.func @outerproduct_add(%arg0: vector<2xf32>, %arg1: vector<3xf32>, %arg2: vector<2x3xf32>) -> vector<2x3xf32> {660 %2 = vector.outerproduct %arg0, %arg1, %arg2 : vector<2xf32>, vector<3xf32>661 return %2 : vector<2x3xf32>662}663// CHECK-LABEL: @outerproduct_add(664// CHECK-SAME: %[[A:.*]]: vector<2xf32>,665// CHECK-SAME: %[[B:.*]]: vector<3xf32>,666// CHECK-SAME: %[[C:.*]]: vector<2x3xf32>) -> vector<2x3xf32>667// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[C]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>>668// CHECK: %[[T3:.*]] = arith.constant dense<0.000000e+00> : vector<2x3xf32>669// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T3]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>>670// CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64671// CHECK: %[[T5:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T4]] : i64] : vector<2xf32>672// CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]]673// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]]674// CHECK: %[[T8:.*]] = llvm.extractvalue %[[T7]][0] : !llvm.array<2 x vector<3xf32>>675// CHECK: %[[T9:.*]] = llvm.intr.fmuladd(%[[T6]], %[[B]], %[[T8]]) : (vector<3xf32>, vector<3xf32>, vector<3xf32>) -> vector<3xf32>676// CHECK: %[[T11:.*]] = llvm.insertvalue %[[T9]], %[[T10]][0] : !llvm.array<2 x vector<3xf32>>677// CHECK: %[[T12:.*]] = llvm.mlir.constant(1 : i64) : i64678// CHECK: %[[T13:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T12]] : i64] : vector<2xf32>679// CHECK: %[[T14Insert:.*]] = llvm.insertelement %[[T13]]680// CHECK: %[[T14:.*]] = llvm.shufflevector %[[T14Insert]]681// CHECK: %[[T16:.*]] = llvm.extractvalue %[[T7]][1] : !llvm.array<2 x vector<3xf32>>682// CHECK: %[[T17:.*]] = llvm.intr.fmuladd(%[[T14]], %[[B]], %[[T16]]) : (vector<3xf32>, vector<3xf32>, vector<3xf32>) -> vector<3xf32>683// CHECK: %[[T18:.*]] = llvm.insertvalue %[[T17]], %[[T11]][1] : !llvm.array<2 x vector<3xf32>>684// CHECK: %[[T19:.*]] = builtin.unrealized_conversion_cast %[[T18]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32>685// CHECK: return %[[T19]] : vector<2x3xf32>686 687// -----688 689func.func @outerproduct_add_scalable(%arg0: vector<2xf32>, %arg1: vector<[3]xf32>, %arg2: vector<2x[3]xf32>) -> vector<2x[3]xf32> {690 %2 = vector.outerproduct %arg0, %arg1, %arg2 : vector<2xf32>, vector<[3]xf32>691 return %2 : vector<2x[3]xf32>692}693// CHECK-LABEL: @outerproduct_add_scalable694// CHECK-SAME: %[[A:.*]]: vector<2xf32>,695// CHECK-SAME: %[[B:.*]]: vector<[3]xf32>,696// CHECK-SAME: %[[C:.*]]: vector<2x[3]xf32>) -> vector<2x[3]xf32>697// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[C]] : vector<2x[3]xf32> to !llvm.array<2 x vector<[3]xf32>>698// CHECK: %[[T3:.*]] = arith.constant dense<0.000000e+00> : vector<2x[3]xf32>699// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T3]] : vector<2x[3]xf32> to !llvm.array<2 x vector<[3]xf32>>700// CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64701// CHECK: %[[T5:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T4]] : i64] : vector<2xf32>702// CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]]703// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]]704// CHECK: %[[T8:.*]] = llvm.extractvalue %[[T7]][0] : !llvm.array<2 x vector<[3]xf32>>705// CHECK: %[[T9:.*]] = llvm.intr.fmuladd(%[[T6]], %[[B]], %[[T8]]) : (vector<[3]xf32>, vector<[3]xf32>, vector<[3]xf32>) -> vector<[3]xf32>706// CHECK: %[[T11:.*]] = llvm.insertvalue %[[T9]], %[[T10]][0] : !llvm.array<2 x vector<[3]xf32>>707// CHECK: %[[T12:.*]] = llvm.mlir.constant(1 : i64) : i64708// CHECK: %[[T13:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T12]] : i64] : vector<2xf32>709// CHECK: %[[T14Insert:.*]] = llvm.insertelement %[[T13]]710// CHECK: %[[T14:.*]] = llvm.shufflevector %[[T14Insert]]711// CHECK: %[[T16:.*]] = llvm.extractvalue %[[T7]][1] : !llvm.array<2 x vector<[3]xf32>>712// CHECK: %[[T17:.*]] = llvm.intr.fmuladd(%[[T14]], %[[B]], %[[T16]]) : (vector<[3]xf32>, vector<[3]xf32>, vector<[3]xf32>) -> vector<[3]xf32>713// CHECK: %[[T18:.*]] = llvm.insertvalue %[[T17]], %[[T11]][1] : !llvm.array<2 x vector<[3]xf32>>714// CHECK: %[[T19:.*]] = builtin.unrealized_conversion_cast %[[T18]] : !llvm.array<2 x vector<[3]xf32>> to vector<2x[3]xf32>715// CHECK: return %[[T19]] : vector<2x[3]xf32>716 717// -----718 719//===----------------------------------------------------------------------===//720// vector.mask { vector.outerproduct }721//===----------------------------------------------------------------------===//722 723func.func @masked_float_add_outerprod(%arg0: vector<2xf32>, %arg1: f32, %arg2: vector<2xf32>, %m: vector<2xi1>) -> vector<2xf32> {724 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<add>} : vector<2xf32>, f32 } : vector<2xi1> -> vector<2xf32>725 return %0 : vector<2xf32>726}727 728// CHECK-LABEL: func.func @masked_float_add_outerprod(729// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<2xf32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xf32> {730// CHECK: %[[VAL_8:.*]] = llvm.intr.fmuladd(%[[VAL_0]], %{{.*}}, %[[VAL_2]]) : (vector<2xf32>, vector<2xf32>, vector<2xf32>) -> vector<2xf32>731// CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_3]], %[[VAL_8]], %[[VAL_2]] : vector<2xi1>, vector<2xf32>732 733// -----734 735func.func @masked_float_add_outerprod_scalable(%arg0: vector<[2]xf32>, %arg1: f32, %arg2: vector<[2]xf32>, %m: vector<[2]xi1>) -> vector<[2]xf32> {736 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<add>} : vector<[2]xf32>, f32 } : vector<[2]xi1> -> vector<[2]xf32>737 return %0 : vector<[2]xf32>738}739 740// CHECK-LABEL: func.func @masked_float_add_outerprod_scalable(741// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<[2]xf32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xf32> {742// CHECK: %[[VAL_8:.*]] = llvm.intr.fmuladd(%[[VAL_0]], %{{.*}}, %[[VAL_2]]) : (vector<[2]xf32>, vector<[2]xf32>, vector<[2]xf32>) -> vector<[2]xf32>743// CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_3]], %[[VAL_8]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xf32>744 745// -----746 747func.func @masked_float_mul_outerprod(%arg0: vector<2xf32>, %arg1: f32, %arg2: vector<2xf32>, %m: vector<2xi1>) -> vector<2xf32> {748 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<mul>} : vector<2xf32>, f32 } : vector<2xi1> -> vector<2xf32>749 return %0 : vector<2xf32>750}751 752// CHECK-LABEL: func.func @masked_float_mul_outerprod(753// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<2xf32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xf32> {754// CHECK: %[[VAL_8:.*]] = arith.mulf %[[VAL_0]], %{{.*}} : vector<2xf32>755// CHECK: %[[VAL_9:.*]] = arith.mulf %[[VAL_8]], %[[VAL_2]] : vector<2xf32>756// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xf32>757 758// -----759 760func.func @masked_float_mul_outerprod_scalable(%arg0: vector<[2]xf32>, %arg1: f32, %arg2: vector<[2]xf32>, %m: vector<[2]xi1>) -> vector<[2]xf32> {761 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<mul>} : vector<[2]xf32>, f32 } : vector<[2]xi1> -> vector<[2]xf32>762 return %0 : vector<[2]xf32>763}764 765// CHECK-LABEL: func.func @masked_float_mul_outerprod_scalable(766// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<[2]xf32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xf32> {767// CHECK: %[[VAL_8:.*]] = arith.mulf %[[VAL_0]], %{{.*}} : vector<[2]xf32>768// CHECK: %[[VAL_9:.*]] = arith.mulf %[[VAL_8]], %[[VAL_2]] : vector<[2]xf32>769// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xf32>770 771// -----772 773func.func @masked_float_max_outerprod(%arg0: vector<2xf32>, %arg1: f32, %arg2: vector<2xf32>, %m: vector<2xi1>) -> vector<2xf32> {774 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<maxnumf>} : vector<2xf32>, f32 } : vector<2xi1> -> vector<2xf32>775 return %0 : vector<2xf32>776}777 778// CHECK-LABEL: func.func @masked_float_max_outerprod(779// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<2xf32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xf32> {780// CHECK: %[[VAL_8:.*]] = arith.mulf %[[VAL_0]], %{{.*}} : vector<2xf32>781// CHECK: %[[VAL_9:.*]] = arith.maxnumf %[[VAL_8]], %[[VAL_2]] : vector<2xf32>782// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xf32>783 784// -----785 786func.func @masked_float_max_outerprod_scalable(%arg0: vector<[2]xf32>, %arg1: f32, %arg2: vector<[2]xf32>, %m: vector<[2]xi1>) -> vector<[2]xf32> {787 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<maxnumf>} : vector<[2]xf32>, f32 } : vector<[2]xi1> -> vector<[2]xf32>788 return %0 : vector<[2]xf32>789}790 791// CHECK-LABEL: func.func @masked_float_max_outerprod_scalable(792// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<[2]xf32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xf32> {793// CHECK: %[[VAL_8:.*]] = arith.mulf %[[VAL_0]], %{{.*}} : vector<[2]xf32>794// CHECK: %[[VAL_9:.*]] = arith.maxnumf %[[VAL_8]], %[[VAL_2]] : vector<[2]xf32>795// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xf32>796 797// -----798 799func.func @masked_float_min_outerprod(%arg0: vector<2xf32>, %arg1: f32, %arg2: vector<2xf32>, %m: vector<2xi1>) -> vector<2xf32> {800 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<minnumf>} : vector<2xf32>, f32 } : vector<2xi1> -> vector<2xf32>801 return %0 : vector<2xf32>802}803 804// CHECK-LABEL: func.func @masked_float_min_outerprod(805// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<2xf32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xf32> {806// CHECK: %[[VAL_8:.*]] = arith.mulf %[[VAL_0]], %{{.*}} : vector<2xf32>807// CHECK: %[[VAL_9:.*]] = arith.minnumf %[[VAL_8]], %[[VAL_2]] : vector<2xf32>808// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xf32>809 810// -----811 812func.func @masked_float_min_outerprod_scalable(%arg0: vector<[2]xf32>, %arg1: f32, %arg2: vector<[2]xf32>, %m: vector<[2]xi1>) -> vector<[2]xf32> {813 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<minnumf>} : vector<[2]xf32>, f32 } : vector<[2]xi1> -> vector<[2]xf32>814 return %0 : vector<[2]xf32>815}816 817// CHECK-LABEL: func.func @masked_float_min_outerprod_scalable(818// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xf32>, %[[VAL_1:.*]]: f32, %[[VAL_2:.*]]: vector<[2]xf32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xf32> {819// CHECK: %[[VAL_8:.*]] = arith.mulf %[[VAL_0]], %{{.*}} : vector<[2]xf32>820// CHECK: %[[VAL_9:.*]] = arith.minnumf %[[VAL_8]], %[[VAL_2]] : vector<[2]xf32>821// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xf32>822 823// -----824 825func.func @masked_int_add_outerprod(%arg0: vector<2xi32>, %arg1: i32, %arg2: vector<2xi32>, %m: vector<2xi1>) -> vector<2xi32> {826 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<add>} : vector<2xi32>, i32 } : vector<2xi1> -> vector<2xi32>827 return %0 : vector<2xi32>828}829 830// CHECK-LABEL: func.func @masked_int_add_outerprod(831// CHECK-SAME: %[[VAL_0:.*]]: vector<2xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<2xi32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xi32> {832// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<2xi32>833// CHECK: %[[VAL_9:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] : vector<2xi32>834// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xi32>835 836// -----837 838func.func @masked_int_add_outerprod_scalable(%arg0: vector<[2]xi32>, %arg1: i32, %arg2: vector<[2]xi32>, %m: vector<[2]xi1>) -> vector<[2]xi32> {839 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<add>} : vector<[2]xi32>, i32 } : vector<[2]xi1> -> vector<[2]xi32>840 return %0 : vector<[2]xi32>841}842 843// CHECK-LABEL: func.func @masked_int_add_outerprod_scalable(844// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<[2]xi32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xi32> {845// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<[2]xi32>846// CHECK: %[[VAL_9:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] : vector<[2]xi32>847// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xi32>848 849// -----850 851func.func @masked_int_mul_outerprod(%arg0: vector<2xi32>, %arg1: i32, %arg2: vector<2xi32>, %m: vector<2xi1>) -> vector<2xi32> {852 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<mul>} : vector<2xi32>, i32 } : vector<2xi1> -> vector<2xi32>853 return %0 : vector<2xi32>854}855 856// CHECK-LABEL: func.func @masked_int_mul_outerprod(857// CHECK-SAME: %[[VAL_0:.*]]: vector<2xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<2xi32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xi32> {858// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<2xi32>859// CHECK: %[[VAL_9:.*]] = arith.muli %[[VAL_8]], %[[VAL_2]] : vector<2xi32>860// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xi32>861 862// -----863 864func.func @masked_int_mul_outerprod_scalable(%arg0: vector<[2]xi32>, %arg1: i32, %arg2: vector<[2]xi32>, %m: vector<[2]xi1>) -> vector<[2]xi32> {865 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<mul>} : vector<[2]xi32>, i32 } : vector<[2]xi1> -> vector<[2]xi32>866 return %0 : vector<[2]xi32>867}868 869// CHECK-LABEL: func.func @masked_int_mul_outerprod_scalable(870// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<[2]xi32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xi32> {871// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<[2]xi32>872// CHECK: %[[VAL_9:.*]] = arith.muli %[[VAL_8]], %[[VAL_2]] : vector<[2]xi32>873// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xi32>874 875// -----876 877func.func @masked_int_max_outerprod(%arg0: vector<2xi32>, %arg1: i32, %arg2: vector<2xi32>, %m: vector<2xi1>) -> vector<2xi32> {878 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<maxsi>} : vector<2xi32>, i32 } : vector<2xi1> -> vector<2xi32>879 return %0 : vector<2xi32>880}881 882// CHECK-LABEL: func.func @masked_int_max_outerprod(883// CHECK-SAME: %[[VAL_0:.*]]: vector<2xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<2xi32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xi32> {884// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<2xi32>885// CHECK: %[[VAL_9:.*]] = arith.maxsi %[[VAL_8]], %[[VAL_2]] : vector<2xi32>886// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xi32>887 888// -----889 890func.func @masked_int_max_outerprod_scalable(%arg0: vector<[2]xi32>, %arg1: i32, %arg2: vector<[2]xi32>, %m: vector<[2]xi1>) -> vector<[2]xi32> {891 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<maxsi>} : vector<[2]xi32>, i32 } : vector<[2]xi1> -> vector<[2]xi32>892 return %0 : vector<[2]xi32>893}894 895// CHECK-LABEL: func.func @masked_int_max_outerprod_scalable(896// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<[2]xi32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xi32> {897// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<[2]xi32>898// CHECK: %[[VAL_9:.*]] = arith.maxsi %[[VAL_8]], %[[VAL_2]] : vector<[2]xi32>899// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xi32>900 901// -----902 903func.func @masked_int_min_outerprod(%arg0: vector<2xi32>, %arg1: i32, %arg2: vector<2xi32>, %m: vector<2xi1>) -> vector<2xi32> {904 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<minui>} : vector<2xi32>, i32 } : vector<2xi1> -> vector<2xi32>905 return %0 : vector<2xi32>906}907 908// CHECK-LABEL: func.func @masked_int_min_outerprod(909// CHECK-SAME: %[[VAL_0:.*]]: vector<2xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<2xi32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xi32> {910// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<2xi32>911// CHECK: %[[VAL_9:.*]] = arith.minui %[[VAL_8]], %[[VAL_2]] : vector<2xi32>912// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xi32>913 914// -----915 916func.func @masked_int_min_outerprod_scalable(%arg0: vector<[2]xi32>, %arg1: i32, %arg2: vector<[2]xi32>, %m: vector<[2]xi1>) -> vector<[2]xi32> {917 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<minui>} : vector<[2]xi32>, i32 } : vector<[2]xi1> -> vector<[2]xi32>918 return %0 : vector<[2]xi32>919}920 921// CHECK-LABEL: func.func @masked_int_min_outerprod_scalable(922// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<[2]xi32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xi32> {923// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<[2]xi32>924// CHECK: %[[VAL_9:.*]] = arith.minui %[[VAL_8]], %[[VAL_2]] : vector<[2]xi32>925// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xi32>926 927// -----928 929func.func @masked_int_and_outerprod(%arg0: vector<2xi32>, %arg1: i32, %arg2: vector<2xi32>, %m: vector<2xi1>) -> vector<2xi32> {930 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<and>} : vector<2xi32>, i32 } : vector<2xi1> -> vector<2xi32>931 return %0 : vector<2xi32>932}933 934// CHECK-LABEL: func.func @masked_int_and_outerprod(935// CHECK-SAME: %[[VAL_0:.*]]: vector<2xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<2xi32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xi32> {936// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<2xi32>937// CHECK: %[[VAL_9:.*]] = arith.andi %[[VAL_8]], %[[VAL_2]] : vector<2xi32>938// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xi32>939 940// -----941 942func.func @masked_int_and_outerprod_scalable(%arg0: vector<[2]xi32>, %arg1: i32, %arg2: vector<[2]xi32>, %m: vector<[2]xi1>) -> vector<[2]xi32> {943 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<and>} : vector<[2]xi32>, i32 } : vector<[2]xi1> -> vector<[2]xi32>944 return %0 : vector<[2]xi32>945}946 947// CHECK-LABEL: func.func @masked_int_and_outerprod_scalable(948// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<[2]xi32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xi32> {949// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<[2]xi32>950// CHECK: %[[VAL_9:.*]] = arith.andi %[[VAL_8]], %[[VAL_2]] : vector<[2]xi32>951// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xi32>952 953// -----954 955func.func @masked_int_or_outerprod(%arg0: vector<2xi32>, %arg1: i32, %arg2: vector<2xi32>, %m: vector<2xi1>) -> vector<2xi32> {956 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<or>} : vector<2xi32>, i32 } : vector<2xi1> -> vector<2xi32>957 return %0 : vector<2xi32>958}959 960// CHECK-LABEL: func.func @masked_int_or_outerprod(961// CHECK-SAME: %[[VAL_0:.*]]: vector<2xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<2xi32>, %[[VAL_3:.*]]: vector<2xi1>) -> vector<2xi32> {962// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<2xi32>963// CHECK: %[[VAL_9:.*]] = arith.ori %[[VAL_8]], %[[VAL_2]] : vector<2xi32>964// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<2xi1>, vector<2xi32>965 966// -----967 968func.func @masked_int_or_outerprod_scalable(%arg0: vector<[2]xi32>, %arg1: i32, %arg2: vector<[2]xi32>, %m: vector<[2]xi1>) -> vector<[2]xi32> {969 %0 = vector.mask %m { vector.outerproduct %arg0, %arg1, %arg2 {kind = #vector.kind<or>} : vector<[2]xi32>, i32 } : vector<[2]xi1> -> vector<[2]xi32>970 return %0 : vector<[2]xi32>971}972 973// CHECK-LABEL: func.func @masked_int_or_outerprod_scalable974// CHECK-SAME: %[[VAL_0:.*]]: vector<[2]xi32>, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: vector<[2]xi32>, %[[VAL_3:.*]]: vector<[2]xi1>) -> vector<[2]xi32> {975// CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_0]], %{{.*}} : vector<[2]xi32>976// CHECK: %[[VAL_9:.*]] = arith.ori %[[VAL_8]], %[[VAL_2]] : vector<[2]xi32>977// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_3]], %[[VAL_9]], %[[VAL_2]] : vector<[2]xi1>, vector<[2]xi32>978 979// -----980 981//===----------------------------------------------------------------------===//982// vector.extract983//===----------------------------------------------------------------------===//984 985// FIXME: Segfaults for --convert-to-llvm="filter-dialects=vector"986func.func @extract_scalar_from_vec_1d_f32_poison_idx(%arg0: vector<16xf32>) -> f32 {987 %0 = vector.extract %arg0[-1]: f32 from vector<16xf32>988 return %0 : f32989}990// CHECK-LABEL: @extract_scalar_from_vec_1d_f32_poison_idx991// CHECK: %[[UB:.*]] = ub.poison : f32992// CHECK: return %[[UB]] : f32993 994// -----995 996// FIXME: Segfaults for --convert-to-llvm="filter-dialects=vector"997func.func @extract_vec_2d_from_vec_3d_f32_poison_idx(%arg0: vector<4x3x16xf32>) -> vector<3x16xf32> {998 %0 = vector.extract %arg0[-1]: vector<3x16xf32> from vector<4x3x16xf32>999 return %0 : vector<3x16xf32>1000}1001// CHECK-LABEL: @extract_vec_2d_from_vec_3d_f32_poison_idx1002// CHECK: %[[UB:.*]] = ub.poison : vector<3x16xf32>1003// CHECK: return %[[UB]] : vector<3x16xf32>1004 1005// -----1006 1007//===----------------------------------------------------------------------===//1008// vector.print1009//===----------------------------------------------------------------------===//1010 1011func.func @print_scalar_i1(%arg0: i1) {1012 vector.print %arg0 : i11013 return1014}1015//1016// Type "boolean" always uses zero extension.1017//1018// CHECK-LABEL: @print_scalar_i1(1019// CHECK-SAME: %[[A:.*]]: i1)1020// CHECK: %[[S:.*]] = arith.extui %[[A]] : i1 to i641021// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()1022// CHECK: llvm.call @printNewline() : () -> ()1023 1024// -----1025 1026func.func @print_scalar_i4(%arg0: i4) {1027 vector.print %arg0 : i41028 return1029}1030// CHECK-LABEL: @print_scalar_i4(1031// CHECK-SAME: %[[A:.*]]: i4)1032// CHECK: %[[S:.*]] = arith.extsi %[[A]] : i4 to i641033// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()1034// CHECK: llvm.call @printNewline() : () -> ()1035 1036// -----1037 1038func.func @print_scalar_si4(%arg0: si4) {1039 vector.print %arg0 : si41040 return1041}1042// CHECK-LABEL: @print_scalar_si4(1043// CHECK-SAME: %[[A:.*]]: si4)1044// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : si4 to i41045// CHECK: %[[S:.*]] = arith.extsi %[[C]] : i4 to i641046// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()1047// CHECK: llvm.call @printNewline() : () -> ()1048 1049// -----1050 1051func.func @print_scalar_ui4(%arg0: ui4) {1052 vector.print %arg0 : ui41053 return1054}1055// CHECK-LABEL: @print_scalar_ui4(1056// CHECK-SAME: %[[A:.*]]: ui4)1057// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui4 to i41058// CHECK: %[[S:.*]] = arith.extui %[[C]] : i4 to i641059// CHECK: llvm.call @printU64(%[[S]]) : (i64) -> ()1060// CHECK: llvm.call @printNewline() : () -> ()1061 1062// -----1063 1064func.func @print_scalar_i32(%arg0: i32) {1065 vector.print %arg0 : i321066 return1067}1068// CHECK-LABEL: @print_scalar_i32(1069// CHECK-SAME: %[[A:.*]]: i32)1070// CHECK: %[[S:.*]] = arith.extsi %[[A]] : i32 to i641071// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()1072// CHECK: llvm.call @printNewline() : () -> ()1073 1074// -----1075 1076func.func @print_scalar_ui32(%arg0: ui32) {1077 vector.print %arg0 : ui321078 return1079}1080// CHECK-LABEL: @print_scalar_ui32(1081// CHECK-SAME: %[[A:.*]]: ui32)1082// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui32 to i321083// CHECK: %[[S:.*]] = arith.extui %[[C]] : i32 to i641084// CHECK: llvm.call @printU64(%[[S]]) : (i64) -> ()1085 1086// -----1087 1088func.func @print_scalar_i40(%arg0: i40) {1089 vector.print %arg0 : i401090 return1091}1092// CHECK-LABEL: @print_scalar_i40(1093// CHECK-SAME: %[[A:.*]]: i40)1094// CHECK: %[[S:.*]] = arith.extsi %[[A]] : i40 to i641095// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()1096// CHECK: llvm.call @printNewline() : () -> ()1097 1098// -----1099 1100func.func @print_scalar_si40(%arg0: si40) {1101 vector.print %arg0 : si401102 return1103}1104// CHECK-LABEL: @print_scalar_si40(1105// CHECK-SAME: %[[A:.*]]: si40)1106// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : si40 to i401107// CHECK: %[[S:.*]] = arith.extsi %[[C]] : i40 to i641108// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()1109// CHECK: llvm.call @printNewline() : () -> ()1110 1111// -----1112 1113func.func @print_scalar_ui40(%arg0: ui40) {1114 vector.print %arg0 : ui401115 return1116}1117// CHECK-LABEL: @print_scalar_ui40(1118// CHECK-SAME: %[[A:.*]]: ui40)1119// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui40 to i401120// CHECK: %[[S:.*]] = arith.extui %[[C]] : i40 to i641121// CHECK: llvm.call @printU64(%[[S]]) : (i64) -> ()1122// CHECK: llvm.call @printNewline() : () -> ()1123 1124// -----1125 1126//===----------------------------------------------------------------------===//1127// vector.extract_strided_slice1128//===----------------------------------------------------------------------===//1129 1130func.func @extract_strided_slice_f32_1d_from_1d(%arg0: vector<4xf32>) -> vector<2xf32> {1131 %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>1132 return %0 : vector<2xf32>1133}1134// CHECK-LABEL: @extract_strided_slice_f32_1d_from_1d1135// CHECK-SAME: %[[A:.*]]: vector<4xf32>)1136// CHECK: %[[T0:.*]] = llvm.shufflevector %[[A]], %[[A]] [2, 3] : vector<4xf32>1137// CHECK: return %[[T0]] : vector<2xf32>1138 1139// NOTE: For scalable vectors we could only extract vector<[4]xf32> from vector<[4]xf32>, but that would be a NOP.1140 1141// -----1142 1143func.func @extract_strided_slice_index_1d_from_1d(%arg0: vector<4xindex>) -> vector<2xindex> {1144 %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4xindex> to vector<2xindex>1145 return %0 : vector<2xindex>1146}1147// CHECK-LABEL: @extract_strided_slice_index_1d_from_1d1148// CHECK-SAME: %[[A:.*]]: vector<4xindex>)1149// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4xindex> to vector<4xi64>1150// CHECK: %[[T2:.*]] = llvm.shufflevector %[[T0]], %[[T0]] [2, 3] : vector<4xi64>1151// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<2xi64> to vector<2xindex>1152// CHECK: return %[[T3]] : vector<2xindex>1153 1154// NOTE: For scalable vectors we could only extract vector<[4]xindex> from vector<[4]xindex>, but that would be a NOP.1155 1156// -----1157 1158func.func @extract_strided_slice_f32_1d_from_2d(%arg0: vector<4x8xf32>) -> vector<2x8xf32> {1159 %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4x8xf32> to vector<2x8xf32>1160 return %0 : vector<2x8xf32>1161}1162// CHECK-LABEL: @extract_strided_slice_f32_1d_from_2d(1163// CHECK-SAME: %[[ARG:.*]]: vector<4x8xf32>)1164// CHECK: %[[A:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x8xf32> to !llvm.array<4 x vector<8xf32>>1165// CHECK: %[[T0:.*]] = llvm.mlir.poison : !llvm.array<2 x vector<8xf32>>1166// CHECK: %[[T1:.*]] = llvm.extractvalue %[[A]][2] : !llvm.array<4 x vector<8xf32>>1167// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %[[T0]][0] : !llvm.array<2 x vector<8xf32>>1168// CHECK: %[[T3:.*]] = llvm.extractvalue %[[A]][3] : !llvm.array<4 x vector<8xf32>>1169// CHECK: %[[T4:.*]] = llvm.insertvalue %[[T3]], %[[T2]][1] : !llvm.array<2 x vector<8xf32>>1170// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : !llvm.array<2 x vector<8xf32>> to vector<2x8xf32>1171// CHECK: return %[[T5]]1172 1173// -----1174 1175func.func @extract_strided_slice_f32_1d_from_2d_scalable(%arg0: vector<4x[8]xf32>) -> vector<2x[8]xf32> {1176 %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4x[8]xf32> to vector<2x[8]xf32>1177 return %0 : vector<2x[8]xf32>1178}1179// CHECK-LABEL: func.func @extract_strided_slice_f32_1d_from_2d_scalable(1180// CHECK-SAME: %[[ARG:.*]]: vector<4x[8]xf32>)1181// CHECK: %[[A:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x[8]xf32> to !llvm.array<4 x vector<[8]xf32>>1182// CHECK: %[[CST:.*]] = arith.constant dense<0.000000e+00> : vector<2x[8]xf32>1183// CHECK: %[[DST:.*]] = builtin.unrealized_conversion_cast %[[CST]] : vector<2x[8]xf32> to !llvm.array<2 x vector<[8]xf32>>1184// CHECK: %[[E0:.*]] = llvm.extractvalue %[[A]][2] : !llvm.array<4 x vector<[8]xf32>>1185// CHECK: %[[E1:.*]] = llvm.extractvalue %[[A]][3] : !llvm.array<4 x vector<[8]xf32>>1186// CHECK: %[[I0:.*]] = llvm.insertvalue %[[E0]], %[[DST]][0] : !llvm.array<2 x vector<[8]xf32>>1187// CHECK: %[[I1:.*]] = llvm.insertvalue %[[E1]], %[[I0]][1] : !llvm.array<2 x vector<[8]xf32>>1188// CHECK: %[[RES:.*]] = builtin.unrealized_conversion_cast %[[I1]] : !llvm.array<2 x vector<[8]xf32>> to vector<2x[8]xf32>1189// CHECK: return %[[RES]]1190 1191// -----1192 1193func.func @extract_strided_slice_f32_2d_from_2d(%arg0: vector<4x8xf32>) -> vector<2x2xf32> {1194 %0 = vector.extract_strided_slice %arg0 {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x8xf32> to vector<2x2xf32>1195 return %0 : vector<2x2xf32>1196}1197// CHECK-LABEL: @extract_strided_slice_f32_2d_from_2d(1198// CHECK-SAME: %[[ARG:.*]]: vector<4x8xf32>)1199// CHECK: %[[A:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x8xf32> to !llvm.array<4 x vector<8xf32>>1200// CHECK: %[[VAL_2:.*]] = arith.constant dense<0.000000e+00> : vector<2x2xf32>1201// CHECK: %[[VAL_6:.*]] = builtin.unrealized_conversion_cast %[[VAL_2]] : vector<2x2xf32> to !llvm.array<2 x vector<2xf32>>1202// CHECK: %[[T2:.*]] = llvm.extractvalue %[[A]][2] : !llvm.array<4 x vector<8xf32>>1203// CHECK: %[[T3:.*]] = llvm.shufflevector %[[T2]], %[[T2]] [2, 3] : vector<8xf32>1204// CHECK: %[[T4:.*]] = llvm.insertvalue %[[T3]], %[[VAL_6]][0] : !llvm.array<2 x vector<2xf32>>1205// CHECK: %[[T5:.*]] = llvm.extractvalue %[[A]][3] : !llvm.array<4 x vector<8xf32>>1206// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T5]], %[[T5]] [2, 3] : vector<8xf32>1207// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T6]], %[[T4]][1] : !llvm.array<2 x vector<2xf32>>1208// CHECK: %[[VAL_12:.*]] = builtin.unrealized_conversion_cast %[[T7]] : !llvm.array<2 x vector<2xf32>> to vector<2x2xf32>1209// CHECK: return %[[VAL_12]] : vector<2x2xf32>1210 1211// -----1212 1213// NOTE: For scalable vectors, we can only extract "full" scalable dimensions1214// (e.g. [8] from [8], but not [4] from [8]).1215 1216func.func @extract_strided_slice_f32_2d_from_2d_scalable(%arg0: vector<4x[8]xf32>) -> vector<2x[8]xf32> {1217 %0 = vector.extract_strided_slice %arg0 {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x[8]xf32> to vector<2x[8]xf32>1218 return %0 : vector<2x[8]xf32>1219}1220// CHECK-LABEL: @extract_strided_slice_f32_2d_from_2d_scalable(1221// CHECK-SAME: %[[ARG:.*]]: vector<4x[8]xf32>)1222// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x[8]xf32> to !llvm.array<4 x vector<[8]xf32>>1223// CHECK: %[[T3:.*]] = arith.constant dense<0.000000e+00> : vector<2x[8]xf32>1224// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : vector<2x[8]xf32> to !llvm.array<2 x vector<[8]xf32>>1225// CHECK: %[[T5:.*]] = llvm.extractvalue %[[T1]][2] : !llvm.array<4 x vector<[8]xf32>>1226// CHECK: %[[T6:.*]] = llvm.insertvalue %[[T5]], %[[T4]][0] : !llvm.array<2 x vector<[8]xf32>>1227// CHECK: %[[T7:.*]] = llvm.extractvalue %[[T1]][3] : !llvm.array<4 x vector<[8]xf32>>1228// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T7]], %[[T6]][1] : !llvm.array<2 x vector<[8]xf32>>1229// CHECK: %[[T9:.*]] = builtin.unrealized_conversion_cast %[[T8]] : !llvm.array<2 x vector<[8]xf32>> to vector<2x[8]xf32>1230// CHECK: return %[[T9]] : vector<2x[8]xf32>1231 1232// -----1233 1234//===----------------------------------------------------------------------===//1235// vector.insert_strided_slice1236//===----------------------------------------------------------------------===//1237 1238func.func @insert_strided_slice_f32_2d_into_3d(%b: vector<4x4xf32>, %c: vector<4x4x4xf32>) -> vector<4x4x4xf32> {1239 %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x4xf32> into vector<4x4x4xf32>1240 return %0 : vector<4x4x4xf32>1241}1242// CHECK-LABEL: @insert_strided_slice_f32_2d_into_3d1243// CHECK: llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xf32>>>1244 1245// -----1246 1247func.func @insert_strided_slice_f32_2d_into_3d_scalable(%b: vector<4x[4]xf32>, %c: vector<4x4x[4]xf32>) -> vector<4x4x[4]xf32> {1248 %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x[4]xf32> into vector<4x4x[4]xf32>1249 return %0 : vector<4x4x[4]xf32>1250}1251// CHECK-LABEL: @insert_strided_slice_f32_2d_into_3d_scalable1252// CHECK: llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<[4]xf32>>>1253 1254// -----1255 1256func.func @insert_strided_index_slice_index_2d_into_3d(%b: vector<4x4xindex>, %c: vector<4x4x4xindex>) -> vector<4x4x4xindex> {1257 %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x4xindex> into vector<4x4x4xindex>1258 return %0 : vector<4x4x4xindex>1259}1260// CHECK-LABEL: @insert_strided_index_slice_index_2d_into_3d1261// CHECK: llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xi64>>>1262 1263// -----1264 1265func.func @insert_strided_index_slice_index_2d_into_3d_scalable(%b: vector<4x[4]xindex>, %c: vector<4x4x[4]xindex>) -> vector<4x4x[4]xindex> {1266 %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x[4]xindex> into vector<4x4x[4]xindex>1267 return %0 : vector<4x4x[4]xindex>1268}1269// CHECK-LABEL: @insert_strided_index_slice_index_2d_into_3d_scalable1270// CHECK: llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<[4]xi64>>>1271 1272// -----1273 1274func.func @insert_strided_slice_f32_2d_into_2d(%a: vector<2x2xf32>, %b: vector<4x4xf32>) -> vector<4x4xf32> {1275 %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>1276 return %0 : vector<4x4xf32>1277}1278 1279// CHECK-LABEL: @insert_strided_slice_f32_2d_into_2d1280//1281// Subvector vector<2xf32> @0 into vector<4xf32> @21282// CHECK: %[[V2_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<2xf32>>1283// CHECK: %[[V4_0:.*]] = llvm.extractvalue {{.*}}[2] : !llvm.array<4 x vector<4xf32>>1284// Element @0 -> element @21285// CHECK: %[[R4_0:.*]] = llvm.shufflevector %[[V2_0]], %[[V2_0]] [0, 1, 0, 0] : vector<2xf32>1286// CHECK: %[[R4_1:.*]] = llvm.shufflevector %[[R4_0]], %[[V4_0]] [4, 5, 0, 1] : vector<4xf32>1287// CHECK: llvm.insertvalue %[[R4_1]], {{.*}}[2] : !llvm.array<4 x vector<4xf32>>1288//1289// Subvector vector<2xf32> @1 into vector<4xf32> @31290// CHECK: %[[V2_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<2xf32>>1291// CHECK: %[[V4_3:.*]] = llvm.extractvalue {{.*}}[3] : !llvm.array<4 x vector<4xf32>>1292// Element @0 -> element @21293// CHECK: %[[R4_2:.*]] = llvm.shufflevector %[[V2_1]], %[[V2_1]] [0, 1, 0, 0] : vector<2xf32>1294// CHECK: %[[R4_3:.*]] = llvm.shufflevector %[[R4_2]], %[[V4_3]] [4, 5, 0, 1] : vector<4xf32>1295// CHECK: llvm.insertvalue %[[R4_3]], {{.*}}[3] : !llvm.array<4 x vector<4xf32>>1296 1297// -----1298 1299// NOTE: For scalable dimensions, the corresponding "base" size must match1300// (i.e. we can only insert "full" scalable dimensions, e.g. [2] into [2], but1301// not [2] from [4]).1302 1303func.func @insert_strided_slice_f32_2d_into_2d_scalable(%a: vector<2x[2]xf32>, %b: vector<4x[2]xf32>) -> vector<4x[2]xf32> {1304 %0 = vector.insert_strided_slice %a, %b {offsets = [2, 0], strides = [1, 1]} : vector<2x[2]xf32> into vector<4x[2]xf32>1305 return %0 : vector<4x[2]xf32>1306}1307 1308// CHECK-LABEL: func.func @insert_strided_slice_f32_2d_into_2d_scalable1309// Subvector vector<[2]xf32> @0 into vector<[4]xf32> @21310// CHECK: %[[A_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<[2]xf32>>1311// Element @0 -> element @21312// CHECK: %[[B_UPDATED:.*]] = llvm.insertvalue %[[A_0]], {{.*}}[2] : !llvm.array<4 x vector<[2]xf32>>1313// Subvector vector<[2]xf32> @1 into vector<[4]xf32> @31314// CHECK: %[[A_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<[2]xf32>>1315// Element @0 -> element @21316// CHECK: llvm.insertvalue %[[A_1]], %[[B_UPDATED]][3] : !llvm.array<4 x vector<[2]xf32>>1317 1318// -----1319 1320func.func @insert_strided_slice_f32_2d_into_3d(%arg0: vector<2x4xf32>, %arg1: vector<16x4x8xf32>) -> vector<16x4x8xf32> {1321 %0 = vector.insert_strided_slice %arg0, %arg1 {offsets = [0, 0, 2], strides = [1, 1]}:1322 vector<2x4xf32> into vector<16x4x8xf32>1323 return %0 : vector<16x4x8xf32>1324}1325// CHECK-LABEL: func @insert_strided_slice_f32_2d_into_3d1326// CHECK: %[[V4_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<4xf32>>1327// CHECK: %[[V4_0_0:.*]] = llvm.extractvalue {{.*}}[0, 0] : !llvm.array<16 x array<4 x vector<8xf32>>>1328// CHECK: %[[R8_0:.*]] = llvm.shufflevector %[[V4_0]], %[[V4_0]] [0, 1, 2, 3, 0, 0, 0, 0] : vector<4xf32>1329// CHECK: %[[R8_1:.*]] = llvm.shufflevector %[[R8_0:.*]], %[[V4_0_0]] [8, 9, 0, 1, 2, 3, 14, 15] : vector<8xf32>1330// CHECK: llvm.insertvalue %[[R8_1]], {{.*}}[0] : !llvm.array<4 x vector<8xf32>>1331 1332// CHECK: %[[V4_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<4xf32>>1333// CHECK: %[[V4_0_1:.*]] = llvm.extractvalue {{.*}}[0, 1] : !llvm.array<16 x array<4 x vector<8xf32>>>1334// CHECK: %[[R8_2:.*]] = llvm.shufflevector %[[V4_1]], %[[V4_1]] [0, 1, 2, 3, 0, 0, 0, 0] : vector<4xf32>1335// CHECK: %[[R8_3:.*]] = llvm.shufflevector %[[R8_2]], %[[V4_0_1]] [8, 9, 0, 1, 2, 3, 14, 15] : vector<8xf32>1336// CHECK: llvm.insertvalue %[[R8_3]], {{.*}}[1] : !llvm.array<4 x vector<8xf32>>1337 1338// -----1339 1340// NOTE: For scalable dimensions, the corresponding "base" size must match1341// (i.e. we can only insert "full" scalable dimensions, e.g. [4] into [4], but1342// not [4] from [8]).1343 1344func.func @insert_strided_slice_f32_2d_into_3d_scalable(%arg0: vector<2x[4]xf32>, %arg1: vector<16x4x[4]xf32>) -> vector<16x4x[4]xf32> {1345 %0 = vector.insert_strided_slice %arg0, %arg1 {offsets = [3, 2, 0], strides = [1, 1]}:1346 vector<2x[4]xf32> into vector<16x4x[4]xf32>1347 return %0 : vector<16x4x[4]xf32>1348}1349 1350// CHECK-LABEL: func.func @insert_strided_slice_f32_2d_into_3d_scalable(1351 1352// Subvector vector<4x[4]xf32> from vector<16x4x[4]xf32> @31353// CHECK: %[[ARG_1_0:.*]] = llvm.extractvalue {{.*}}[3] : !llvm.array<16 x array<4 x vector<[4]xf32>>>1354 1355// Subvector vector<[4]xf32> @0 into vector<4x[4]xf32> @21356// CHECK: %[[ARG_0_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<[4]xf32>>1357// CHECK: %[[B_UPDATED_0:.*]] = llvm.insertvalue %[[ARG_0_0]], %[[ARG_1_0]][2] : !llvm.array<4 x vector<[4]xf32>>1358 1359// Subvector vector<[4]xf32> @1 into vector<4x[4]xf32> @31360// CHECK: %[[ARG_0_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<[4]xf32>>1361// CHECK: %[[B_UPDATED_1:.*]] = llvm.insertvalue %[[ARG_0_1]], %[[B_UPDATED_0]][3] : !llvm.array<4 x vector<[4]xf32>>1362 1363// Subvector vector<4x[4]xf32> into vector<16x4x[4]xf32> @31364// CHECK: llvm.insertvalue %[[B_UPDATED_1]], {{.*}}[3] : !llvm.array<16 x array<4 x vector<[4]xf32>>>1365 1366// -----1367 1368//===----------------------------------------------------------------------===//1369// vector.fma1370//===----------------------------------------------------------------------===//1371 1372func.func @fma(%vec_1d: vector<8xf32>, %vec_2d: vector<2x4xf32>, %vec_3d: vector<1x1x1xf32>, %vec_0d: vector<f32>) -> (vector<8xf32>, vector<2x4xf32>, vector<1x1x1xf32>, vector<f32>) {1373 // CHECK-LABEL: @fma1374 // CHECK-SAME: %[[VEC_1D:.*]]: vector<8xf32>1375 // CHECK-SAME: %[[VEC_2D:.*]]: vector<2x4xf32>1376 // CHECK-SAME: %[[VEC_3D:.*]]: vector<1x1x1xf32>1377 // CHECK: %[[VEC_2D_CAST:.*]] = builtin.unrealized_conversion_cast %[[VEC_2D]] : vector<2x4xf32> to !llvm.array<2 x vector<4xf32>>1378 // CHECK: llvm.intr.fmuladd1379 // CHECK-SAME: (vector<8xf32>, vector<8xf32>, vector<8xf32>) -> vector<8xf32>1380 %0 = vector.fma %vec_1d, %vec_1d, %vec_1d : vector<8xf32>1381 1382 // CHECK: %[[VEC_2D_00:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][0] : !llvm.array<2 x vector<4xf32>>1383 // CHECK: %[[VEC_2D_01:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][0] : !llvm.array<2 x vector<4xf32>>1384 // CHECK: %[[VEC_2D_02:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][0] : !llvm.array<2 x vector<4xf32>>1385 // CHECK: %[[VEC_2D_ADD_1:.*]] = llvm.intr.fmuladd(%[[VEC_2D_00]], %[[VEC_2D_01]], %[[VEC_2D_02]]) :1386 // CHECK-SAME: (vector<4xf32>, vector<4xf32>, vector<4xf32>) -> vector<4xf32>1387 // CHECK: llvm.insertvalue %[[VEC_2D_ADD_1]], {{.*}}[0] : !llvm.array<2 x vector<4xf32>>1388 // CHECK: %[[VEC_2D_10:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][1] : !llvm.array<2 x vector<4xf32>>1389 // CHECK: %[[VEC_2D_11:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][1] : !llvm.array<2 x vector<4xf32>>1390 // CHECK: %[[VEC_2D_12:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][1] : !llvm.array<2 x vector<4xf32>>1391 // CHECK: %[[VEC_2D_ADD_2:.*]] = llvm.intr.fmuladd(%[[VEC_2D_10]], %[[VEC_2D_11]], %[[VEC_2D_12]]) :1392 // CHECK-SAME: (vector<4xf32>, vector<4xf32>, vector<4xf32>) -> vector<4xf32>1393 // CHECK: llvm.insertvalue %[[VEC_2D_ADD_2]], {{.*}}[1] : !llvm.array<2 x vector<4xf32>>1394 %1 = vector.fma %vec_2d, %vec_2d, %vec_2d : vector<2x4xf32>1395 1396 // CHECK: %[[C0:.*]] = llvm.intr.fmuladd1397 // CHECK-SAME: (vector<1xf32>, vector<1xf32>, vector<1xf32>) -> vector<1xf32>1398 %2 = vector.fma %vec_3d, %vec_3d, %vec_3d : vector<1x1x1xf32>1399 1400 // CHECK: %[[D0:.*]] = llvm.intr.fmuladd1401 // CHECK-SAME: (vector<1xf32>, vector<1xf32>, vector<1xf32>) -> vector<1xf32>1402 %3 = vector.fma %vec_0d, %vec_0d, %vec_0d : vector<f32>1403 1404 return %0, %1, %2, %3: vector<8xf32>, vector<2x4xf32>, vector<1x1x1xf32>, vector<f32>1405}1406 1407// -----1408 1409func.func @fma_scalable(%vec_1d: vector<[8]xf32>, %vec_2d: vector<2x[4]xf32>, %vec_3d: vector<1x1x[1]xf32>, %vec_0d: vector<f32>) -> (vector<[8]xf32>, vector<2x[4]xf32>, vector<1x1x[1]xf32>) {1410 // CHECK-LABEL: @fma_scalable1411 // CHECK-SAME: %[[VEC_1D:.*]]: vector<[8]xf32>1412 // CHECK-SAME: %[[VEC_2D:.*]]: vector<2x[4]xf32>1413 // CHECK-SAME: %[[VEC_3D:.*]]: vector<1x1x[1]xf32>1414 // CHECK: %[[VEC_2D_CAST:.*]] = builtin.unrealized_conversion_cast %[[VEC_2D]] : vector<2x[4]xf32> to !llvm.array<2 x vector<[4]xf32>>1415 // CHECK: llvm.intr.fmuladd1416 // CHECK-SAME: (vector<[8]xf32>, vector<[8]xf32>, vector<[8]xf32>) -> vector<[8]xf32>1417 %0 = vector.fma %vec_1d, %vec_1d, %vec_1d : vector<[8]xf32>1418 1419 // CHECK: %[[VEC_2D_00:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][0] : !llvm.array<2 x vector<[4]xf32>>1420 // CHECK: %[[VEC_2D_01:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][0] : !llvm.array<2 x vector<[4]xf32>>1421 // CHECK: %[[VEC_2D_02:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][0] : !llvm.array<2 x vector<[4]xf32>>1422 // CHECK: %[[VEC_2D_ADD_1:.*]] = llvm.intr.fmuladd(%[[VEC_2D_00]], %[[VEC_2D_01]], %[[VEC_2D_02]]) :1423 // CHECK-SAME: (vector<[4]xf32>, vector<[4]xf32>, vector<[4]xf32>) -> vector<[4]xf32>1424 // CHECK: llvm.insertvalue %[[VEC_2D_ADD_1]], {{.*}}[0] : !llvm.array<2 x vector<[4]xf32>>1425 // CHECK: %[[VEC_2D_10:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][1] : !llvm.array<2 x vector<[4]xf32>>1426 // CHECK: %[[VEC_2D_11:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][1] : !llvm.array<2 x vector<[4]xf32>>1427 // CHECK: %[[VEC_2D_12:.*]] = llvm.extractvalue %[[VEC_2D_CAST]][1] : !llvm.array<2 x vector<[4]xf32>>1428 // CHECK: %[[VEC_2D_ADD_2:.*]] = llvm.intr.fmuladd(%[[VEC_2D_10]], %[[VEC_2D_11]], %[[VEC_2D_12]]) :1429 // CHECK-SAME: (vector<[4]xf32>, vector<[4]xf32>, vector<[4]xf32>) -> vector<[4]xf32>1430 // CHECK: llvm.insertvalue %[[VEC_2D_ADD_2]], {{.*}}[1] : !llvm.array<2 x vector<[4]xf32>>1431 %1 = vector.fma %vec_2d, %vec_2d, %vec_2d : vector<2x[4]xf32>1432 1433 // CHECK: %[[C0:.*]] = llvm.intr.fmuladd1434 // CHECK-SAME: (vector<[1]xf32>, vector<[1]xf32>, vector<[1]xf32>) -> vector<[1]xf32>1435 %2 = vector.fma %vec_3d, %vec_3d, %vec_3d : vector<1x1x[1]xf32>1436 1437 return %0, %1, %2: vector<[8]xf32>, vector<2x[4]xf32>, vector<1x1x[1]xf32>1438}1439 1440// -----1441 1442//===----------------------------------------------------------------------===//1443// vector.constant_mask1444//===----------------------------------------------------------------------===//1445 1446func.func @constant_mask_0d_f() -> vector<i1> {1447 %0 = vector.constant_mask [0] : vector<i1>1448 return %0 : vector<i1>1449}1450// CHECK-LABEL: func @constant_mask_0d_f1451// CHECK: %[[VAL_0:.*]] = arith.constant dense<false> : vector<i1>1452// CHECK: return %[[VAL_0]] : vector<i1>1453 1454// -----1455 1456func.func @constant_mask_0d_t() -> vector<i1> {1457 %0 = vector.constant_mask [1] : vector<i1>1458 return %0 : vector<i1>1459}1460// CHECK-LABEL: func @constant_mask_0d_t1461// CHECK: %[[VAL_0:.*]] = arith.constant dense<true> : vector<i1>1462// CHECK: return %[[VAL_0]] : vector<i1>1463 1464// -----1465 1466func.func @constant_mask_1d() -> vector<8xi1> {1467 %0 = vector.constant_mask [4] : vector<8xi1>1468 return %0 : vector<8xi1>1469}1470// CHECK-LABEL: func @constant_mask_1d1471// CHECK: %[[VAL_0:.*]] = arith.constant dense<[true, true, true, true, false, false, false, false]> : vector<8xi1>1472// CHECK: return %[[VAL_0]] : vector<8xi1>1473 1474// -----1475 1476func.func @constant_mask_1d_scalable_all_false() -> vector<[8]xi1> {1477 %0 = vector.constant_mask [0] : vector<[8]xi1>1478 return %0 : vector<[8]xi1>1479}1480// CHECK-LABEL: func @constant_mask_1d_scalable_all_false1481// CHECK: %[[VAL_0:.*]] = arith.constant dense<false> : vector<[8]xi1>1482// CHECK: return %[[VAL_0]] : vector<[8]xi1>1483 1484// -----1485 1486func.func @constant_mask_1d_scalable_all_true() -> vector<[8]xi1> {1487 %0 = vector.constant_mask [8] : vector<[8]xi1>1488 return %0 : vector<[8]xi1>1489}1490// CHECK-LABEL: func @constant_mask_1d_scalable_all_true1491// CHECK: %[[VAL_0:.*]] = arith.constant dense<true> : vector<[8]xi1>1492// CHECK: return %[[VAL_0]] : vector<[8]xi1>1493 1494// -----1495 1496func.func @constant_mask_2d() -> vector<4x4xi1> {1497 %v = vector.constant_mask [2, 2] : vector<4x4xi1>1498 return %v: vector<4x4xi1>1499}1500 1501// CHECK-LABEL: func @constant_mask_2d1502// CHECK: %[[VAL_0:.*]] = arith.constant 1503// CHECK-SAME{LITERAL}: dense<[[true, true, false, false], [true, true, false, false], [false, false, false, false], [false, false, false, false]]> : vector<4x4xi1>1504// CHECK: return %[[VAL_0]] : vector<4x4xi1>1505 1506// -----1507 1508func.func @constant_mask_2d_trailing_scalable() -> vector<4x[4]xi1> {1509 %0 = vector.constant_mask [2, 4] : vector<4x[4]xi1>1510 return %0 : vector<4x[4]xi1>1511}1512// CHECK-LABEL: func.func @constant_mask_2d_trailing_scalable1513// CHECK: %[[VAL_0:.*]] = arith.constant dense<true> : vector<[4]xi1>1514// CHECK: %[[VAL_1:.*]] = arith.constant dense<false> : vector<4x[4]xi1>1515// CHECK: %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[VAL_1]] : vector<4x[4]xi1> to !llvm.array<4 x vector<[4]xi1>>1516// CHECK: %[[VAL_3:.*]] = llvm.insertvalue %[[VAL_0]], %[[VAL_2]][0] : !llvm.array<4 x vector<[4]xi1>>1517// CHECK: %[[VAL_4:.*]] = llvm.insertvalue %[[VAL_0]], %[[VAL_3]][1] : !llvm.array<4 x vector<[4]xi1>>1518// CHECK: %[[VAL_5:.*]] = builtin.unrealized_conversion_cast %[[VAL_4]] : !llvm.array<4 x vector<[4]xi1>> to vector<4x[4]xi1>1519// CHECK: return %[[VAL_5]] : vector<4x[4]xi1>1520 1521// -----1522 1523/// Currently, this is not supported as generating the mask would require1524/// unrolling the leading scalable dimension at compile time.1525func.func @negative_constant_mask_2d_leading_scalable() -> vector<[4]x4xi1> {1526 %0 = vector.constant_mask [4, 2] : vector<[4]x4xi1>1527 return %0 : vector<[4]x4xi1>1528}1529// CHECK-LABEL: func.func @negative_constant_mask_2d_leading_scalable1530// CHECK: %[[VAL_0:.*]] = vector.constant_mask [4, 2] : vector<[4]x4xi1>1531// CHECK: return %[[VAL_0]] : vector<[4]x4xi1>1532 1533// -----1534 1535//===----------------------------------------------------------------------===//1536// vector.create_mask1537//===----------------------------------------------------------------------===//1538 1539func.func @create_mask_0d(%num_elems : index) -> vector<i1> {1540 %v = vector.create_mask %num_elems : vector<i1>1541 return %v: vector<i1>1542}1543 1544// CHECK-LABEL: func @create_mask_0d1545// CHECK-SAME: %[[NUM_ELEMS:.*]]: index1546// CHECK: %[[INDICES:.*]] = arith.constant dense<0> : vector<i32>1547// CHECK: %[[NUM_ELEMS_i32:.*]] = arith.index_cast %[[NUM_ELEMS]] : index to i321548// CHECK: %[[BOUNDS:.*]] = llvm.insertelement %[[NUM_ELEMS_i32]]1549// CHECK: %[[BOUNDS_CAST:.*]] = builtin.unrealized_conversion_cast %[[BOUNDS]] : vector<1xi32> to vector<i32>1550// CHECK: %[[RESULT:.*]] = arith.cmpi sgt, %[[BOUNDS_CAST]], %[[INDICES]] : vector<i32>1551// CHECK: return %[[RESULT]] : vector<i1>1552 1553// -----1554 1555func.func @create_mask_1d(%num_elems : index) -> vector<4xi1> {1556 %v = vector.create_mask %num_elems : vector<4xi1>1557 return %v: vector<4xi1>1558}1559 1560// CHECK-LABEL: func @create_mask_1d1561// CHECK-SAME: %[[NUM_ELEMS:.*]]: index1562// CHECK: %[[INDICES:.*]] = arith.constant dense<[0, 1, 2, 3]> : vector<4xi32>1563// CHECK: %[[NUM_ELEMS_i32:.*]] = arith.index_cast %[[NUM_ELEMS]] : index to i321564// CHECK: %[[BOUNDS_INSERT:.*]] = llvm.insertelement %[[NUM_ELEMS_i32]]1565// CHECK: %[[BOUNDS:.*]] = llvm.shufflevector %[[BOUNDS_INSERT]]1566// CHECK: %[[RESULT:.*]] = arith.cmpi sgt, %[[BOUNDS]], %[[INDICES]] : vector<4xi32>1567// CHECK: return %[[RESULT]] : vector<4xi1>1568 1569// -----1570 1571func.func @create_mask_1d_scalable(%num_elems : index) -> vector<[4]xi1> {1572 %v = vector.create_mask %num_elems : vector<[4]xi1>1573 return %v: vector<[4]xi1>1574}1575 1576// CHECK-LABEL: func @create_mask_1d_scalable1577// CHECK-SAME: %[[NUM_ELEMS:.*]]: index1578// CHECK: %[[INDICES:.*]] = llvm.intr.stepvector : vector<[4]xi32>1579// CHECK: %[[NUM_ELEMS_i32:.*]] = arith.index_cast %[[NUM_ELEMS]] : index to i321580// CHECK: %[[BOUNDS_INSERT:.*]] = llvm.insertelement %[[NUM_ELEMS_i32]], {{.*}} : vector<[4]xi32>1581// CHECK: %[[BOUNDS:.*]] = llvm.shufflevector %[[BOUNDS_INSERT]], {{.*}} : vector<[4]xi32>1582// CHECK: %[[RESULT:.*]] = arith.cmpi slt, %[[INDICES]], %[[BOUNDS]] : vector<[4]xi32>1583// CHECK: return %[[RESULT]] : vector<[4]xi1>1584 1585// -----1586 1587//===----------------------------------------------------------------------===//1588// vector.gather1589//1590// NOTE: vector.constant_mask won't lower with1591// * --convert-to-llvm="filter-dialects=vector",1592// hence testing here.1593//===----------------------------------------------------------------------===//1594 1595 1596func.func @gather_with_mask(%arg0: memref<?xf32>, %arg1: vector<2x3xi32>, %arg2: vector<2x3xf32>) -> vector<2x3xf32> {1597 %0 = arith.constant 0: index1598 %1 = vector.constant_mask [2, 2] : vector<2x3xi1>1599 %2 = vector.gather %arg0[%0][%arg1], %1, %arg2 : memref<?xf32>, vector<2x3xi32>, vector<2x3xi1>, vector<2x3xf32> into vector<2x3xf32>1600 return %2 : vector<2x3xf32>1601}1602 1603// CHECK-LABEL: func @gather_with_mask1604// CHECK: %[[G0:.*]] = llvm.intr.masked.gather %{{.*}}, %{{.*}}, %{{.*}} {alignment = 4 : i32} : (vector<3x!llvm.ptr>, vector<3xi1>, vector<3xf32>) -> vector<3xf32>1605// CHECK: %[[G1:.*]] = llvm.intr.masked.gather %{{.*}}, %{{.*}}, %{{.*}} {alignment = 4 : i32} : (vector<3x!llvm.ptr>, vector<3xi1>, vector<3xf32>) -> vector<3xf32>1606 1607// -----1608 1609func.func @gather_with_mask_scalable(%arg0: memref<?xf32>, %arg1: vector<2x[3]xi32>, %arg2: vector<2x[3]xf32>) -> vector<2x[3]xf32> {1610 %0 = arith.constant 0: index1611 // vector.constant_mask only supports 'none set' or 'all set' scalable1612 // dimensions, hence [2, 3] rather than [2, 2] as in the example for fixed1613 // width vectors above.1614 %1 = vector.constant_mask [2, 3] : vector<2x[3]xi1>1615 %2 = vector.gather %arg0[%0][%arg1], %1, %arg2 : memref<?xf32>, vector<2x[3]xi32>, vector<2x[3]xi1>, vector<2x[3]xf32> into vector<2x[3]xf32>1616 return %2 : vector<2x[3]xf32>1617}1618 1619// CHECK-LABEL: func @gather_with_mask_scalable1620// CHECK: %[[G0:.*]] = llvm.intr.masked.gather %{{.*}}, %{{.*}}, %{{.*}} {alignment = 4 : i32} : (vector<[3]x!llvm.ptr>, vector<[3]xi1>, vector<[3]xf32>) -> vector<[3]xf32>1621// CHECK: %[[G1:.*]] = llvm.intr.masked.gather %{{.*}}, %{{.*}}, %{{.*}} {alignment = 4 : i32} : (vector<[3]x!llvm.ptr>, vector<[3]xi1>, vector<[3]xf32>) -> vector<[3]xf32>1622 1623 1624// -----1625 1626func.func @gather_with_zero_mask(%arg0: memref<?xf32>, %arg1: vector<2x3xi32>, %arg2: vector<2x3xf32>) -> vector<2x3xf32> {1627 %0 = arith.constant 0: index1628 %1 = vector.constant_mask [0, 0] : vector<2x3xi1>1629 %2 = vector.gather %arg0[%0][%arg1], %1, %arg2 : memref<?xf32>, vector<2x3xi32>, vector<2x3xi1>, vector<2x3xf32> into vector<2x3xf32>1630 return %2 : vector<2x3xf32>1631}1632 1633// CHECK-LABEL: func @gather_with_zero_mask1634// CHECK-SAME: (%{{.*}}: memref<?xf32>, %{{.*}}: vector<2x3xi32>, %[[S:.*]]: vector<2x3xf32>)1635// CHECK-NOT: %{{.*}} = llvm.intr.masked.gather1636// CHECK: return %[[S]] : vector<2x3xf32>1637 1638// -----1639 1640func.func @gather_with_zero_mask_scalable(%arg0: memref<?xf32>, %arg1: vector<2x[3]xi32>, %arg2: vector<2x[3]xf32>) -> vector<2x[3]xf32> {1641 %0 = arith.constant 0: index1642 %1 = vector.constant_mask [0, 0] : vector<2x[3]xi1>1643 %2 = vector.gather %arg0[%0][%arg1], %1, %arg2 : memref<?xf32>, vector<2x[3]xi32>, vector<2x[3]xi1>, vector<2x[3]xf32> into vector<2x[3]xf32>1644 return %2 : vector<2x[3]xf32>1645}1646 1647// CHECK-LABEL: func @gather_with_zero_mask_scalable1648// CHECK-SAME: (%{{.*}}: memref<?xf32>, %{{.*}}: vector<2x[3]xi32>, %[[S:.*]]: vector<2x[3]xf32>)1649// CHECK-NOT: %{{.*}} = llvm.intr.masked.gather1650// CHECK: return %[[S]] : vector<2x[3]xf32>1651 1652// -----1653 1654//===----------------------------------------------------------------------===//1655// vector.scatter1656//===----------------------------------------------------------------------===//1657 1658// Multi-Dimensional scatters are not supported yet. Check that we do not lower1659// them.1660 1661func.func @scatter_with_mask(%arg0: memref<?xf32>, %arg1: vector<2x3xi32>, %arg2: vector<2x3xf32>) {1662 %0 = arith.constant 0: index1663 %1 = vector.constant_mask [2, 2] : vector<2x3xi1>1664 vector.scatter %arg0[%0][%arg1], %1, %arg2 : memref<?xf32>, vector<2x3xi32>, vector<2x3xi1>, vector<2x3xf32>1665 return1666}1667 1668// CHECK-LABEL: func @scatter_with_mask1669// CHECK: vector.scatter1670 1671// -----1672 1673func.func @scatter_with_mask_scalable(%arg0: memref<?xf32>, %arg1: vector<2x[3]xi32>, %arg2: vector<2x[3]xf32>) {1674 %0 = arith.constant 0: index1675 // vector.constant_mask only supports 'none set' or 'all set' scalable1676 // dimensions, hence [2, 3] rather than [2, 2] as in the example for fixed1677 // width vectors above.1678 %1 = vector.constant_mask [2, 3] : vector<2x[3]xi1>1679 vector.scatter %arg0[%0][%arg1], %1, %arg2 : memref<?xf32>, vector<2x[3]xi32>, vector<2x[3]xi1>, vector<2x[3]xf32>1680 return1681}1682 1683// CHECK-LABEL: func @scatter_with_mask_scalable1684// CHECK: vector.scatter1685 1686// -----1687 1688//===----------------------------------------------------------------------===//1689// vector.interleave1690//===----------------------------------------------------------------------===//1691 1692// CHECK-LABEL: @interleave_2d1693// CHECK-SAME: %[[LHS:.*]]: vector<2x3xi8>, %[[RHS:.*]]: vector<2x3xi8>)1694func.func @interleave_2d(%a: vector<2x3xi8>, %b: vector<2x3xi8>) -> vector<2x6xi8> {1695 // CHECK: llvm.shufflevector1696 // CHECK-NOT: vector.interleave {{.*}} : vector<2x3xi8>1697 %0 = vector.interleave %a, %b : vector<2x3xi8> -> vector<2x6xi8>1698 return %0 : vector<2x6xi8>1699}1700 1701// -----1702 1703// CHECK-LABEL: @interleave_2d_scalable1704// CHECK-SAME: %[[LHS:.*]]: vector<2x[8]xi16>, %[[RHS:.*]]: vector<2x[8]xi16>)1705func.func @interleave_2d_scalable(%a: vector<2x[8]xi16>, %b: vector<2x[8]xi16>) -> vector<2x[16]xi16> {1706 // CHECK: llvm.intr.vector.interleave21707 // CHECK-NOT: vector.interleave {{.*}} : vector<2x[8]xi16>1708 %0 = vector.interleave %a, %b : vector<2x[8]xi16> -> vector<2x[16]xi16>1709 return %0 : vector<2x[16]xi16>1710}1711 1712// -----1713 1714//===----------------------------------------------------------------------===//1715// vector.deinterleave1716//===----------------------------------------------------------------------===//1717 1718// CHECK-LABEL: @deinterleave_2d1719// CHECK-SAME: %[[ARG:.*]]: vector<2x8xf32>) -> (vector<2x4xf32>, vector<2x4xf32>)1720func.func @deinterleave_2d(%arg: vector<2x8xf32>) -> (vector<2x4xf32>, vector<2x4xf32>) {1721 // CHECK: llvm.shufflevector1722 // CHECK-NOT: vector.deinterleave %{{.*}} : vector<2x8xf32>1723 %0, %1 = vector.deinterleave %arg : vector<2x8xf32> -> vector<2x4xf32>1724 return %0, %1 : vector<2x4xf32>, vector<2x4xf32>1725}1726 1727// -----1728 1729func.func @deinterleave_2d_scalable(%arg: vector<2x[8]xf32>) -> (vector<2x[4]xf32>, vector<2x[4]xf32>) {1730 // CHECK: llvm.intr.vector.deinterleave21731 // CHECK-NOT: vector.deinterleave %{{.*}} : vector<2x[8]xf32>1732 %0, %1 = vector.deinterleave %arg : vector<2x[8]xf32> -> vector<2x[4]xf32>1733 return %0, %1 : vector<2x[4]xf32>, vector<2x[4]xf32>1734}1735 1736 1737// -----1738 1739//===----------------------------------------------------------------------===//1740// vector.step1741//===----------------------------------------------------------------------===//1742 1743// TODO: Investigate why this wouldn't lower with --convert-to-llvm="filter-dialects=vector"1744 1745// CHECK-LABEL: @step1746// CHECK: %[[CST:.+]] = arith.constant dense<[0, 1, 2, 3]> : vector<4xindex>1747// CHECK: return %[[CST]] : vector<4xindex>1748func.func @step() -> vector<4xindex> {1749 %0 = vector.step : vector<4xindex>1750 return %0 : vector<4xindex>1751}1752 1753 1754// -----1755 1756//===----------------------------------------------------------------------===//1757// vector.from_elements1758//===----------------------------------------------------------------------===//1759 1760// NOTE: We unroll multi-dimensional from_elements ops with pattern `UnrollFromElements`1761// and then convert the 1-D from_elements ops to llvm.1762 1763// CHECK-LABEL: func @from_elements_3d1764// CHECK-SAME: %[[ARG_0:.*]]: f32, %[[ARG_1:.*]]: f32, %[[ARG_2:.*]]: f32, %[[ARG_3:.*]]: f32)1765// CHECK: %[[UNDEF_RES:.*]] = ub.poison : vector<2x1x2xf32>1766// CHECK: %[[UNDEF_RES_LLVM:.*]] = builtin.unrealized_conversion_cast %[[UNDEF_RES]] : vector<2x1x2xf32> to !llvm.array<2 x array<1 x vector<2xf32>>>1767// CHECK: %[[UNDEF_VEC_RANK_2:.*]] = ub.poison : vector<1x2xf32>1768// CHECK: %[[UNDEF_VEC_RANK_2_LLVM:.*]] = builtin.unrealized_conversion_cast %[[UNDEF_VEC_RANK_2]] : vector<1x2xf32> to !llvm.array<1 x vector<2xf32>>1769// CHECK: %[[UNDEF_VEC0:.*]] = llvm.mlir.poison : vector<2xf32>1770// CHECK: %[[C0_0:.*]] = llvm.mlir.constant(0 : i64) : i641771// CHECK: %[[VEC0_0:.*]] = llvm.insertelement %[[ARG_0]], %[[UNDEF_VEC0]][%[[C0_0]] : i64] : vector<2xf32>1772// CHECK: %[[C1_0:.*]] = llvm.mlir.constant(1 : i64) : i641773// CHECK: %[[VEC0_1:.*]] = llvm.insertelement %[[ARG_1]], %[[VEC0_0]][%[[C1_0]] : i64] : vector<2xf32>1774// CHECK: %[[RES_RANK_2_0:.*]] = llvm.insertvalue %[[VEC0_1]], %[[UNDEF_VEC_RANK_2_LLVM]][0] : !llvm.array<1 x vector<2xf32>>1775// CHECK: %[[RES_0:.*]] = llvm.insertvalue %[[RES_RANK_2_0]], %[[UNDEF_RES_LLVM]][0] : !llvm.array<2 x array<1 x vector<2xf32>>>1776// CHECK: %[[UNDEF_VEC1:.*]] = llvm.mlir.poison : vector<2xf32>1777// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i641778// CHECK: %[[VEC1_0:.*]] = llvm.insertelement %[[ARG_2]], %[[UNDEF_VEC1]][%[[C0_1]] : i64] : vector<2xf32>1779// CHECK: %[[C1_1:.*]] = llvm.mlir.constant(1 : i64) : i641780// CHECK: %[[VEC1_1:.*]] = llvm.insertelement %[[ARG_3]], %[[VEC1_0]][%[[C1_1]] : i64] : vector<2xf32>1781// CHECK: %[[RES_RANK_2_1:.*]] = llvm.insertvalue %[[VEC1_1]], %[[UNDEF_VEC_RANK_2_LLVM]][0] : !llvm.array<1 x vector<2xf32>>1782// CHECK: %[[RES_1:.*]] = llvm.insertvalue %[[RES_RANK_2_1]], %[[RES_0]][1] : !llvm.array<2 x array<1 x vector<2xf32>>>1783// CHECK: %[[CAST:.*]] = builtin.unrealized_conversion_cast %[[RES_1]] : !llvm.array<2 x array<1 x vector<2xf32>>> to vector<2x1x2xf32>1784// CHECK: return %[[CAST]]1785func.func @from_elements_3d(%arg0: f32, %arg1: f32, %arg2: f32, %arg3: f32) -> vector<2x1x2xf32> {1786 %0 = vector.from_elements %arg0, %arg1, %arg2, %arg3 : vector<2x1x2xf32>1787 return %0 : vector<2x1x2xf32>1788}1789 1790// -----1791 1792//===----------------------------------------------------------------------===//1793// vector.to_elements1794//===----------------------------------------------------------------------===//1795 1796// CHECK-LABEL: func @to_elements_1d(1797// CHECK-SAME: %[[ARG0:.+]]: vector<2xf32>1798// CHECK: %[[C0:.+]] = llvm.mlir.constant(0 : i64) : i641799// CHECK: %[[V0:.+]] = llvm.extractelement %[[ARG0]][%[[C0]] : i64] : vector<2xf32>1800// CHECK: %[[C1:.+]] = llvm.mlir.constant(1 : i64) : i641801// CHECK: %[[V1:.+]] = llvm.extractelement %[[ARG0]][%[[C1]] : i64] : vector<2xf32>1802// CHECK: return %[[V0]], %[[V1]]1803func.func @to_elements_1d(%arg0: vector<2xf32>) -> (f32, f32) {1804 %0:2 = vector.to_elements %arg0 : vector<2xf32>1805 return %0#0, %0#1 : f32, f321806}1807 1808// -----1809 1810// NOTE: We unroll multi-dimensional to_elements ops with pattern1811// `UnrollToElements` and then convert the 1-D to_elements ops to llvm.1812 1813// CHECK-LABEL: func @to_elements_2d(1814// CHECK-SAME: %[[ARG0:.+]]: vector<2x2xf32>1815// CHECK: %[[CAST:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : vector<2x2xf32> to !llvm.array<2 x vector<2xf32>>1816// CHECK: %[[V0:.+]] = llvm.extractvalue %[[CAST]][0] : !llvm.array<2 x vector<2xf32>>1817// CHECK: %[[V1:.+]] = llvm.extractvalue %[[CAST]][1] : !llvm.array<2 x vector<2xf32>>1818// CHECK: %[[C0:.+]] = llvm.mlir.constant(0 : i64) : i641819// CHECK: %[[R0:.+]] = llvm.extractelement %[[V0]][%[[C0]] : i64] : vector<2xf32>1820// CHECK: %[[C1:.+]] = llvm.mlir.constant(1 : i64) : i641821// CHECK: %[[R1:.+]] = llvm.extractelement %[[V0]][%[[C1]] : i64] : vector<2xf32>1822// CHECK: %[[C0:.+]] = llvm.mlir.constant(0 : i64) : i641823// CHECK: %[[R2:.+]] = llvm.extractelement %[[V1]][%[[C0]] : i64] : vector<2xf32>1824// CHECK: %[[C1:.+]] = llvm.mlir.constant(1 : i64) : i641825// CHECK: %[[R3:.+]] = llvm.extractelement %[[V1]][%[[C1]] : i64] : vector<2xf32>1826// CHECK: return %[[R0]], %[[R1]], %[[R2]], %[[R3]]1827func.func @to_elements_2d(%arg0: vector<2x2xf32>) -> (f32, f32, f32, f32) {1828 %0:4 = vector.to_elements %arg0 : vector<2x2xf32>1829 return %0#0, %0#1, %0#2, %0#3 : f32, f32, f32, f321830}1831