1084 lines · plain
1// RUN: mlir-opt -split-input-file -convert-vector-to-spirv -verify-diagnostics %s -o - | FileCheck %s2 3module attributes { spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Float16], []>, #spirv.resource_limits<>> } {4 5// CHECK-LABEL: @bitcast6// CHECK-SAME: %[[ARG0:.+]]: vector<2xf32>, %[[ARG1:.+]]: vector<2xf16>7// CHECK: spirv.Bitcast %[[ARG0]] : vector<2xf32> to vector<4xf16>8// CHECK: spirv.Bitcast %[[ARG1]] : vector<2xf16> to f329func.func @bitcast(%arg0 : vector<2xf32>, %arg1: vector<2xf16>) -> (vector<4xf16>, vector<1xf32>) {10 %0 = vector.bitcast %arg0 : vector<2xf32> to vector<4xf16>11 %1 = vector.bitcast %arg1 : vector<2xf16> to vector<1xf32>12 return %0, %1: vector<4xf16>, vector<1xf32>13}14 15} // end module16 17// -----18 19// Check that without the proper capability we fail the pattern application20// to avoid generating invalid ops.21 22module attributes { spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>> } {23 24// CHECK-LABEL: @bitcast25func.func @bitcast(%arg0 : vector<2xf32>, %arg1: vector<2xf16>) -> (vector<4xf16>, vector<1xf32>) {26 // CHECK-COUNT-2: vector.bitcast27 %0 = vector.bitcast %arg0 : vector<2xf32> to vector<4xf16>28 %1 = vector.bitcast %arg1 : vector<2xf16> to vector<1xf32>29 return %0, %1: vector<4xf16>, vector<1xf32>30}31 32} // end module33 34// -----35 36module attributes { spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Kernel], []>, #spirv.resource_limits<>> } {37 38// CHECK-LABEL: @cl_fma39// CHECK-SAME: %[[A:.*]]: vector<4xf32>, %[[B:.*]]: vector<4xf32>, %[[C:.*]]: vector<4xf32>40// CHECK: spirv.CL.fma %[[A]], %[[B]], %[[C]] : vector<4xf32>41func.func @cl_fma(%a: vector<4xf32>, %b: vector<4xf32>, %c: vector<4xf32>) -> vector<4xf32> {42 %0 = vector.fma %a, %b, %c: vector<4xf32>43 return %0 : vector<4xf32>44}45 46// CHECK-LABEL: @cl_fma_size1_vector47// CHECK: spirv.CL.fma %{{.+}} : f3248func.func @cl_fma_size1_vector(%a: vector<1xf32>, %b: vector<1xf32>, %c: vector<1xf32>) -> vector<1xf32> {49 %0 = vector.fma %a, %b, %c: vector<1xf32>50 return %0 : vector<1xf32>51}52 53// CHECK-LABEL: func @cl_reduction_maximumf54// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)55// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>56// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>57// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>58// CHECK: %[[MAX0:.+]] = spirv.CL.fmax %[[S0]], %[[S1]]59// CHECK: %[[MAX1:.+]] = spirv.CL.fmax %[[MAX0]], %[[S2]]60// CHECK: %[[MAX2:.+]] = spirv.CL.fmax %[[MAX1]], %[[S]]61// CHECK: return %[[MAX2]]62func.func @cl_reduction_maximumf(%v : vector<3xf32>, %s: f32) -> f32 {63 %reduce = vector.reduction <maximumf>, %v, %s : vector<3xf32> into f3264 return %reduce : f3265}66 67// CHECK-LABEL: func @cl_reduction_minimumf68// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)69// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>70// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>71// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>72// CHECK: %[[MIN0:.+]] = spirv.CL.fmin %[[S0]], %[[S1]]73// CHECK: %[[MIN1:.+]] = spirv.CL.fmin %[[MIN0]], %[[S2]]74// CHECK: %[[MIN2:.+]] = spirv.CL.fmin %[[MIN1]], %[[S]]75// CHECK: return %[[MIN2]]76func.func @cl_reduction_minimumf(%v : vector<3xf32>, %s: f32) -> f32 {77 %reduce = vector.reduction <minimumf>, %v, %s : vector<3xf32> into f3278 return %reduce : f3279}80 81// CHECK-LABEL: func @cl_reduction_maxsi82// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)83// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>84// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>85// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>86// CHECK: %[[MAX0:.+]] = spirv.CL.s_max %[[S0]], %[[S1]]87// CHECK: %[[MAX1:.+]] = spirv.CL.s_max %[[MAX0]], %[[S2]]88// CHECK: %[[MAX2:.+]] = spirv.CL.s_max %[[MAX1]], %[[S]]89// CHECK: return %[[MAX2]]90func.func @cl_reduction_maxsi(%v : vector<3xi32>, %s: i32) -> i32 {91 %reduce = vector.reduction <maxsi>, %v, %s : vector<3xi32> into i3292 return %reduce : i3293}94 95// CHECK-LABEL: func @cl_reduction_minsi96// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)97// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>98// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>99// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>100// CHECK: %[[MIN0:.+]] = spirv.CL.s_min %[[S0]], %[[S1]]101// CHECK: %[[MIN1:.+]] = spirv.CL.s_min %[[MIN0]], %[[S2]]102// CHECK: %[[MIN2:.+]] = spirv.CL.s_min %[[MIN1]], %[[S]]103// CHECK: return %[[MIN2]]104func.func @cl_reduction_minsi(%v : vector<3xi32>, %s: i32) -> i32 {105 %reduce = vector.reduction <minsi>, %v, %s : vector<3xi32> into i32106 return %reduce : i32107}108 109// CHECK-LABEL: func @cl_reduction_maxui110// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)111// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>112// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>113// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>114// CHECK: %[[MAX0:.+]] = spirv.CL.u_max %[[S0]], %[[S1]]115// CHECK: %[[MAX1:.+]] = spirv.CL.u_max %[[MAX0]], %[[S2]]116// CHECK: %[[MAX2:.+]] = spirv.CL.u_max %[[MAX1]], %[[S]]117// CHECK: return %[[MAX2]]118func.func @cl_reduction_maxui(%v : vector<3xi32>, %s: i32) -> i32 {119 %reduce = vector.reduction <maxui>, %v, %s : vector<3xi32> into i32120 return %reduce : i32121}122 123// CHECK-LABEL: func @cl_reduction_minui124// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)125// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>126// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>127// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>128// CHECK: %[[MIN0:.+]] = spirv.CL.u_min %[[S0]], %[[S1]]129// CHECK: %[[MIN1:.+]] = spirv.CL.u_min %[[MIN0]], %[[S2]]130// CHECK: %[[MIN2:.+]] = spirv.CL.u_min %[[MIN1]], %[[S]]131// CHECK: return %[[MIN2]]132func.func @cl_reduction_minui(%v : vector<3xi32>, %s: i32) -> i32 {133 %reduce = vector.reduction <minui>, %v, %s : vector<3xi32> into i32134 return %reduce : i32135}136 137} // end module138 139// -----140 141// CHECK-LABEL: @broadcast142// CHECK-SAME: %[[A:.*]]: f32143// CHECK: spirv.CompositeConstruct %[[A]], %[[A]], %[[A]], %[[A]]144// CHECK: spirv.CompositeConstruct %[[A]], %[[A]]145func.func @broadcast(%arg0 : f32) -> (vector<4xf32>, vector<2xf32>) {146 %0 = vector.broadcast %arg0 : f32 to vector<4xf32>147 %1 = vector.broadcast %arg0 : f32 to vector<2xf32>148 return %0, %1: vector<4xf32>, vector<2xf32>149}150 151// -----152 153// CHECK-LABEL: @broadcast_index154// CHECK-SAME: %[[ARG0:.*]]: index155// CHECK: %[[CAST0:.*]] = builtin.unrealized_conversion_cast %[[ARG0]] : index to i32156// CHECK: %[[CONSTRUCT:.*]] = spirv.CompositeConstruct %[[CAST0]], %[[CAST0]], %[[CAST0]], %[[CAST0]] : (i32, i32, i32, i32) -> vector<4xi32>157// CHECK: %[[CAST1:.*]] = builtin.unrealized_conversion_cast %[[CONSTRUCT]] : vector<4xi32> to vector<4xindex>158// CHECK: return %[[CAST1]] : vector<4xindex>159func.func @broadcast_index(%a: index) -> vector<4xindex> {160 %0 = vector.broadcast %a : index to vector<4xindex>161 return %0 : vector<4xindex>162}163 164// -----165 166// CHECK-LABEL: @extract167// CHECK-SAME: %[[ARG:.+]]: vector<2xf32>168// CHECK: spirv.CompositeExtract %[[ARG]][0 : i32] : vector<2xf32>169// CHECK: spirv.CompositeExtract %[[ARG]][1 : i32] : vector<2xf32>170func.func @extract(%arg0 : vector<2xf32>) -> (vector<1xf32>, f32) {171 %0 = "vector.extract"(%arg0) <{static_position = array<i64: 0>}> : (vector<2xf32>) -> vector<1xf32>172 %1 = "vector.extract"(%arg0) <{static_position = array<i64: 1>}> : (vector<2xf32>) -> f32173 return %0, %1: vector<1xf32>, f32174}175 176// -----177 178// CHECK-LABEL: @extract_poison_idx179// CHECK: %[[R:.+]] = spirv.Undef : f32180// CHECK: return %[[R]]181func.func @extract_poison_idx(%arg0 : vector<4xf32>) -> f32 {182 %0 = vector.extract %arg0[-1] : f32 from vector<4xf32>183 return %0: f32184}185 186// -----187 188// CHECK-LABEL: @extract_size1_vector189// CHECK-SAME: %[[ARG0:.+]]: vector<1xf32>190// CHECK: %[[R:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]191// CHECK: return %[[R]]192func.func @extract_size1_vector(%arg0 : vector<1xf32>) -> f32 {193 %0 = vector.extract %arg0[0] : f32 from vector<1xf32>194 return %0: f32195}196 197// -----198 199// CHECK-LABEL: @extract_size1_vector_dynamic200// CHECK-SAME: %[[ARG0:.+]]: vector<1xf32>201// CHECK: %[[R:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]202// CHECK: return %[[R]]203func.func @extract_size1_vector_dynamic(%arg0 : vector<1xf32>, %id : index) -> f32 {204 %0 = vector.extract %arg0[%id] : f32 from vector<1xf32>205 return %0: f32206}207 208// -----209 210// CHECK-LABEL: @extract_dynamic211// CHECK-SAME: %[[V:.*]]: vector<4xf32>, %[[ARG1:.*]]: index212// CHECK: %[[ID:.+]] = builtin.unrealized_conversion_cast %[[ARG1]] : index to i32213// CHECK: %[[MASK:.+]] = spirv.Constant 3 :214// CHECK: %[[MASKED:.+]] = spirv.BitwiseAnd %[[ID]], %[[MASK]] :215// CHECK: spirv.VectorExtractDynamic %[[V]][%[[MASKED]]] : vector<4xf32>, i32216func.func @extract_dynamic(%arg0 : vector<4xf32>, %id : index) -> f32 {217 %0 = vector.extract %arg0[%id] : f32 from vector<4xf32>218 return %0: f32219}220 221// -----222 223// CHECK-LABEL: @extract_dynamic_non_pow2224// CHECK-SAME: %[[V:.*]]: vector<3xf32>, %[[ARG1:.*]]: index225// CHECK: %[[ID:.+]] = builtin.unrealized_conversion_cast %[[ARG1]] : index to i32226// CHECK: %[[POISON:.+]] = spirv.Constant -1 :227// CHECK: %[[CMP:.+]] = spirv.IEqual %[[ID]], %[[POISON]]228// CHECK: %[[ZERO:.+]] = spirv.Constant 0 :229// CHECK: %[[SELECT:.+]] = spirv.Select %[[CMP]], %[[ZERO]], %[[ID]] :230// CHECK: spirv.VectorExtractDynamic %[[V]][%[[SELECT]]] : vector<3xf32>, i32231func.func @extract_dynamic_non_pow2(%arg0 : vector<3xf32>, %id : index) -> f32 {232 %0 = vector.extract %arg0[%id] : f32 from vector<3xf32>233 return %0: f32234}235 236// -----237 238// CHECK-LABEL: @extract_dynamic_cst239// CHECK-SAME: %[[V:.*]]: vector<4xf32>240// CHECK: spirv.CompositeExtract %[[V]][1 : i32] : vector<4xf32>241func.func @extract_dynamic_cst(%arg0 : vector<4xf32>) -> f32 {242 %idx = arith.constant 1 : index243 %0 = vector.extract %arg0[%idx] : f32 from vector<4xf32>244 return %0: f32245}246 247// -----248 249// CHECK-LABEL: func.func @to_elements_one_element 250// CHECK-SAME: %[[A:.*]]: vector<1xf32>)251// CHECK: %[[ELEM0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1xf32> to f32252// CHECK: return %[[ELEM0]] : f32253func.func @to_elements_one_element(%a: vector<1xf32>) -> (f32) {254 %0:1 = vector.to_elements %a : vector<1xf32>255 return %0#0 : f32256}257 258// CHECK-LABEL: func.func @to_elements_no_dead_elements259// CHECK-SAME: %[[A:.*]]: vector<4xf32>)260// CHECK: %[[ELEM0:.*]] = spirv.CompositeExtract %[[A]][0 : i32] : vector<4xf32>261// CHECK: %[[ELEM1:.*]] = spirv.CompositeExtract %[[A]][1 : i32] : vector<4xf32>262// CHECK: %[[ELEM2:.*]] = spirv.CompositeExtract %[[A]][2 : i32] : vector<4xf32>263// CHECK: %[[ELEM3:.*]] = spirv.CompositeExtract %[[A]][3 : i32] : vector<4xf32>264// CHECK: return %[[ELEM0]], %[[ELEM1]], %[[ELEM2]], %[[ELEM3]] : f32, f32, f32, f32265func.func @to_elements_no_dead_elements(%a: vector<4xf32>) -> (f32, f32, f32, f32) {266 %0:4 = vector.to_elements %a : vector<4xf32>267 return %0#0, %0#1, %0#2, %0#3 : f32, f32, f32, f32268}269 270// CHECK-LABEL: func.func @to_elements_dead_elements271// CHECK-SAME: %[[A:.*]]: vector<4xf32>)272// CHECK-NOT: spirv.CompositeExtract %[[A]][0 : i32]273// CHECK: %[[ELEM1:.*]] = spirv.CompositeExtract %[[A]][1 : i32] : vector<4xf32>274// CHECK-NOT: spirv.CompositeExtract %[[A]][2 : i32]275// CHECK: %[[ELEM3:.*]] = spirv.CompositeExtract %[[A]][3 : i32] : vector<4xf32>276// CHECK: return %[[ELEM1]], %[[ELEM3]] : f32, f32277func.func @to_elements_dead_elements(%a: vector<4xf32>) -> (f32, f32) {278 %0:4 = vector.to_elements %a : vector<4xf32>279 return %0#1, %0#3 : f32, f32280}281 282// -----283 284// CHECK-LABEL: @from_elements_0d_f32285// CHECK-SAME: %[[ARG0:.+]]: f32286// CHECK: %[[RETVAL:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]287// CHECK: return %[[RETVAL]]288func.func @from_elements_0d_f32(%arg0 : f32) -> vector<f32> {289 %0 = vector.from_elements %arg0 : vector<f32>290 return %0: vector<f32>291}292 293// CHECK-LABEL: @from_elements_1xf32294// CHECK-SAME: %[[ARG0:.+]]: f32295// CHECK: %[[RETVAL:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]296// CHECK: return %[[RETVAL]]297func.func @from_elements_1xf32(%arg0 : f32) -> vector<1xf32> {298 %0 = vector.from_elements %arg0 : vector<1xf32>299 return %0: vector<1xf32>300}301 302// CHECK-LABEL: @from_elements_3xf32303// CHECK-SAME: %[[ARG0:.+]]: f32, %[[ARG1:.+]]: f32, %[[ARG2:.+]]: f32304// CHECK: %[[RETVAL:.+]] = spirv.CompositeConstruct %[[ARG0]], %[[ARG1]], %[[ARG2]] : (f32, f32, f32) -> vector<3xf32>305// CHECK: return %[[RETVAL]]306func.func @from_elements_3xf32(%arg0 : f32, %arg1 : f32, %arg2 : f32) -> vector<3xf32> {307 %0 = vector.from_elements %arg0, %arg1, %arg2 : vector<3xf32>308 return %0: vector<3xf32>309}310 311func.func @from_elements_3xi8(%arg0 : i8, %arg1 : i8, %arg2 : i8) -> vector<3xi8> {312 %0 = vector.from_elements %arg0, %arg1, %arg2 : vector<3xi8>313 return %0: vector<3xi8>314}315// CHECK-LABEL: @from_elements_3xi8316// CHECK-SAME: %[[ARG0:.+]]: i8, %[[ARG1:.+]]: i8, %[[ARG2:.+]]: i8317// CHECK-DAG: %[[CAST0:.*]] = builtin.unrealized_conversion_cast %[[ARG0]] : i8 to i32318// CHECK-DAG: %[[CAST1:.*]] = builtin.unrealized_conversion_cast %[[ARG1]] : i8 to i32319// CHECK-DAG: %[[CAST2:.*]] = builtin.unrealized_conversion_cast %[[ARG2]] : i8 to i32320// CHECK: %[[VAL:.+]] = spirv.CompositeConstruct %[[CAST0]], %[[CAST1]], %[[CAST2]] : (i32, i32, i32) -> vector<3xi32>321// CHECK: %[[RETVAL:.*]] = builtin.unrealized_conversion_cast %[[VAL]] : vector<3xi32> to vector<3xi8>322// CHECK: return %[[RETVAL]]323 324// -----325 326// CHECK-LABEL: @insert327// CHECK-SAME: %[[V:.*]]: vector<4xf32>, %[[S:.*]]: f32328// CHECK: spirv.CompositeInsert %[[S]], %[[V]][2 : i32] : f32 into vector<4xf32>329func.func @insert(%arg0 : vector<4xf32>, %arg1: f32) -> vector<4xf32> {330 %1 = vector.insert %arg1, %arg0[2] : f32 into vector<4xf32>331 return %1: vector<4xf32>332}333 334// -----335 336// CHECK-LABEL: @insert_poison_idx337// CHECK: %[[R:.+]] = spirv.Undef : vector<4xf32>338// CHECK: return %[[R]]339func.func @insert_poison_idx(%arg0 : vector<4xf32>, %arg1: f32) -> vector<4xf32> {340 %1 = vector.insert %arg1, %arg0[-1] : f32 into vector<4xf32>341 return %1: vector<4xf32>342}343 344// -----345 346// CHECK-LABEL: @insert_index_vector347// CHECK: spirv.CompositeInsert %{{.+}}, %{{.+}}[2 : i32] : i32 into vector<4xi32>348func.func @insert_index_vector(%arg0 : vector<4xindex>, %arg1: index) -> vector<4xindex> {349 %1 = vector.insert %arg1, %arg0[2] : index into vector<4xindex>350 return %1: vector<4xindex>351}352 353// -----354 355// CHECK-LABEL: @insert_size1_vector356// CHECK-SAME: %[[V:.*]]: vector<1xf32>, %[[S:.*]]: f32357// CHECK: %[[R:.+]] = builtin.unrealized_conversion_cast %[[S]]358// CHECK: return %[[R]]359func.func @insert_size1_vector(%arg0 : vector<1xf32>, %arg1: f32) -> vector<1xf32> {360 %1 = vector.insert %arg1, %arg0[0] : f32 into vector<1xf32>361 return %1 : vector<1xf32>362}363 364// -----365 366// CHECK-LABEL: @insert_size1_vector_dynamic367// CHECK-SAME: %[[V:.*]]: vector<1xf32>, %[[S:.*]]: f32368// CHECK: %[[R:.+]] = builtin.unrealized_conversion_cast %[[S]]369// CHECK: return %[[R]]370func.func @insert_size1_vector_dynamic(%arg0 : vector<1xf32>, %arg1: f32, %id : index) -> vector<1xf32> {371 %1 = vector.insert %arg1, %arg0[%id] : f32 into vector<1xf32>372 return %1 : vector<1xf32>373}374 375// -----376 377// CHECK-LABEL: @insert_dynamic378// CHECK-SAME: %[[VAL:.*]]: f32, %[[V:.*]]: vector<4xf32>, %[[ARG2:.*]]: index379// CHECK: %[[ID:.+]] = builtin.unrealized_conversion_cast %[[ARG2]] : index to i32380// CHECK: %[[MASK:.+]] = spirv.Constant 3 :381// CHECK: %[[MASKED:.+]] = spirv.BitwiseAnd %[[ID]], %[[MASK]] :382// CHECK: spirv.VectorInsertDynamic %[[VAL]], %[[V]][%[[MASKED]]] : vector<4xf32>, i32383func.func @insert_dynamic(%val: f32, %arg0 : vector<4xf32>, %id : index) -> vector<4xf32> {384 %0 = vector.insert %val, %arg0[%id] : f32 into vector<4xf32>385 return %0: vector<4xf32>386}387 388// -----389 390// CHECK-LABEL: @insert_dynamic_non_pow2391// CHECK-SAME: %[[VAL:.*]]: f32, %[[V:.*]]: vector<3xf32>, %[[ARG2:.*]]: index392// CHECK: %[[ID:.+]] = builtin.unrealized_conversion_cast %[[ARG2]] : index to i32393// CHECK: %[[POISON:.+]] = spirv.Constant -1 :394// CHECK: %[[CMP:.+]] = spirv.IEqual %[[ID]], %[[POISON]]395// CHECK: %[[ZERO:.+]] = spirv.Constant 0 :396// CHECK: %[[SELECT:.+]] = spirv.Select %[[CMP]], %[[ZERO]], %[[ID]] :397// CHECK: spirv.VectorInsertDynamic %[[VAL]], %[[V]][%[[SELECT]]] : vector<3xf32>, i32398func.func @insert_dynamic_non_pow2(%val: f32, %arg0 : vector<3xf32>, %id : index) -> vector<3xf32> {399 %0 = vector.insert %val, %arg0[%id] : f32 into vector<3xf32>400 return %0: vector<3xf32>401}402 403// -----404 405// CHECK-LABEL: @insert_dynamic_cst406// CHECK-SAME: %[[VAL:.*]]: f32, %[[V:.*]]: vector<4xf32>407// CHECK: spirv.CompositeInsert %[[VAL]], %[[V]][2 : i32] : f32 into vector<4xf32>408func.func @insert_dynamic_cst(%val: f32, %arg0 : vector<4xf32>) -> vector<4xf32> {409 %idx = arith.constant 2 : index410 %0 = vector.insert %val, %arg0[%idx] : f32 into vector<4xf32>411 return %0: vector<4xf32>412}413 414// -----415 416// CHECK-LABEL: @extract_strided_slice417// CHECK-SAME: %[[ARG:.+]]: vector<4xf32>418// CHECK: spirv.VectorShuffle [1 : i32, 2 : i32] %[[ARG]], %[[ARG]] : vector<4xf32>, vector<4xf32> -> vector<2xf32>419// CHECK: spirv.CompositeExtract %[[ARG]][1 : i32] : vector<4xf32>420func.func @extract_strided_slice(%arg0: vector<4xf32>) -> (vector<2xf32>, vector<1xf32>) {421 %0 = vector.extract_strided_slice %arg0 {offsets = [1], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>422 %1 = vector.extract_strided_slice %arg0 {offsets = [1], sizes = [1], strides = [1]} : vector<4xf32> to vector<1xf32>423 return %0, %1 : vector<2xf32>, vector<1xf32>424}425 426// -----427 428// CHECK-LABEL: @insert_strided_slice429// CHECK-SAME: %[[PART:.+]]: vector<2xf32>, %[[ALL:.+]]: vector<4xf32>430// CHECK: spirv.VectorShuffle [0 : i32, 4 : i32, 5 : i32, 3 : i32] %[[ALL]], %[[PART]] : vector<4xf32>, vector<2xf32> -> vector<4xf32>431func.func @insert_strided_slice(%arg0: vector<2xf32>, %arg1: vector<4xf32>) -> vector<4xf32> {432 %0 = vector.insert_strided_slice %arg0, %arg1 {offsets = [1], strides = [1]} : vector<2xf32> into vector<4xf32>433 return %0 : vector<4xf32>434}435 436// -----437 438// CHECK-LABEL: @insert_size1_vector439// CHECK-SAME: %[[SUB:.*]]: vector<1xf32>, %[[FULL:.*]]: vector<3xf32>440// CHECK: %[[S:.+]] = builtin.unrealized_conversion_cast %[[SUB]]441// CHECK: spirv.CompositeInsert %[[S]], %[[FULL]][2 : i32] : f32 into vector<3xf32>442func.func @insert_size1_vector(%arg0 : vector<1xf32>, %arg1: vector<3xf32>) -> vector<3xf32> {443 %1 = vector.insert_strided_slice %arg0, %arg1 {offsets = [2], strides = [1]} : vector<1xf32> into vector<3xf32>444 return %1 : vector<3xf32>445}446 447// -----448 449// CHECK-LABEL: @fma450// CHECK-SAME: %[[A:.*]]: vector<4xf32>, %[[B:.*]]: vector<4xf32>, %[[C:.*]]: vector<4xf32>451// CHECK: spirv.GL.Fma %[[A]], %[[B]], %[[C]] : vector<4xf32>452func.func @fma(%a: vector<4xf32>, %b: vector<4xf32>, %c: vector<4xf32>) -> vector<4xf32> {453 %0 = vector.fma %a, %b, %c: vector<4xf32>454 return %0 : vector<4xf32>455}456 457// -----458 459// CHECK-LABEL: @fma_size1_vector460// CHECK: spirv.GL.Fma %{{.+}} : f32461func.func @fma_size1_vector(%a: vector<1xf32>, %b: vector<1xf32>, %c: vector<1xf32>) -> vector<1xf32> {462 %0 = vector.fma %a, %b, %c: vector<1xf32>463 return %0 : vector<1xf32>464}465 466// -----467 468// CHECK-LABEL: func @splat469// CHECK-SAME: (%[[A:.+]]: f32)470// CHECK: %[[VAL:.+]] = spirv.CompositeConstruct %[[A]], %[[A]], %[[A]], %[[A]]471// CHECK: return %[[VAL]]472func.func @splat(%f : f32) -> vector<4xf32> {473 %splat = vector.broadcast %f : f32 to vector<4xf32>474 return %splat : vector<4xf32>475}476 477// -----478 479// CHECK-LABEL: func @splat_size1_vector480// CHECK-SAME: (%[[A:.+]]: f32)481// CHECK: %[[VAL:.+]] = builtin.unrealized_conversion_cast %[[A]]482// CHECK: return %[[VAL]]483func.func @splat_size1_vector(%f : f32) -> vector<1xf32> {484 %splat = vector.broadcast %f : f32 to vector<1xf32>485 return %splat : vector<1xf32>486}487 488// -----489 490// CHECK-LABEL: func @shuffle491// CHECK-SAME: %[[ARG0:.+]]: vector<1xf32>, %[[ARG1:.+]]: vector<1xf32>492// CHECK-DAG: %[[V0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]493// CHECK-DAG: %[[V1:.+]] = builtin.unrealized_conversion_cast %[[ARG1]]494// CHECK: spirv.CompositeConstruct %[[V0]], %[[V1]], %[[V1]], %[[V0]] : (f32, f32, f32, f32) -> vector<4xf32>495func.func @shuffle(%v0 : vector<1xf32>, %v1: vector<1xf32>) -> vector<4xf32> {496 %shuffle = vector.shuffle %v0, %v1 [0, 1, 1, 0] : vector<1xf32>, vector<1xf32>497 return %shuffle : vector<4xf32>498}499 500// -----501 502// CHECK-LABEL: func @shuffle_index_vector503// CHECK-SAME: %[[ARG0:.+]]: vector<1xindex>, %[[ARG1:.+]]: vector<1xindex>504// CHECK-DAG: %[[V0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]505// CHECK-DAG: %[[V1:.+]] = builtin.unrealized_conversion_cast %[[ARG1]]506// CHECK: spirv.CompositeConstruct %[[V0]], %[[V1]], %[[V1]], %[[V0]] : (i32, i32, i32, i32) -> vector<4xi32>507func.func @shuffle_index_vector(%v0 : vector<1xindex>, %v1: vector<1xindex>) -> vector<4xindex> {508 %shuffle = vector.shuffle %v0, %v1 [0, 1, 1, 0] : vector<1xindex>, vector<1xindex>509 return %shuffle : vector<4xindex>510}511 512// -----513 514// CHECK-LABEL: func @shuffle515// CHECK-SAME: %[[V0:.+]]: vector<3xf32>, %[[V1:.+]]: vector<3xf32>516// CHECK: spirv.VectorShuffle [3 : i32, 2 : i32, 5 : i32, 1 : i32] %[[V0]], %[[V1]] : vector<3xf32>, vector<3xf32> -> vector<4xf32>517func.func @shuffle(%v0 : vector<3xf32>, %v1: vector<3xf32>) -> vector<4xf32> {518 %shuffle = vector.shuffle %v0, %v1 [3, 2, 5, 1] : vector<3xf32>, vector<3xf32>519 return %shuffle : vector<4xf32>520}521 522// -----523 524// CHECK-LABEL: func @shuffle525func.func @shuffle(%v0 : vector<2x16xf32>, %v1: vector<1x16xf32>) -> vector<3x16xf32> {526 // CHECK: vector.shuffle527 %shuffle = vector.shuffle %v0, %v1 [0, 1, 2] : vector<2x16xf32>, vector<1x16xf32>528 return %shuffle : vector<3x16xf32>529}530 531// -----532 533// CHECK-LABEL: func @shuffle534// CHECK-SAME: %[[ARG0:.+]]: vector<1xi32>, %[[ARG1:.+]]: vector<3xi32>535// CHECK: %[[V0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : vector<1xi32> to i32536// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[ARG1]][1 : i32] : vector<3xi32>537// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[ARG1]][2 : i32] : vector<3xi32>538// CHECK: %[[RES:.+]] = spirv.CompositeConstruct %[[V0]], %[[S1]], %[[S2]] : (i32, i32, i32) -> vector<3xi32>539// CHECK: return %[[RES]]540func.func @shuffle(%v0 : vector<1xi32>, %v1: vector<3xi32>) -> vector<3xi32> {541 %shuffle = vector.shuffle %v0, %v1 [0, 2, 3] : vector<1xi32>, vector<3xi32>542 return %shuffle : vector<3xi32>543}544 545// -----546 547// CHECK-LABEL: func @shuffle548// CHECK-SAME: %[[ARG0:.+]]: vector<3xi32>, %[[ARG1:.+]]: vector<1xi32>549// CHECK: %[[V1:.+]] = builtin.unrealized_conversion_cast %[[ARG1]] : vector<1xi32> to i32550// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[ARG0]][0 : i32] : vector<3xi32>551// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[ARG0]][2 : i32] : vector<3xi32>552// CHECK: %[[RES:.+]] = spirv.CompositeConstruct %[[S0]], %[[S1]], %[[V1]] : (i32, i32, i32) -> vector<3xi32>553// CHECK: return %[[RES]]554func.func @shuffle(%v0 : vector<3xi32>, %v1: vector<1xi32>) -> vector<3xi32> {555 %shuffle = vector.shuffle %v0, %v1 [0, 2, 3] : vector<3xi32>, vector<1xi32>556 return %shuffle : vector<3xi32>557}558 559// -----560 561// CHECK-LABEL: func @shuffle562// CHECK-SAME: %[[ARG0:.+]]: vector<1xi32>, %[[ARG1:.+]]: vector<1xi32>563// CHECK-DAG: %[[V0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : vector<1xi32> to i32564// CHECK-DAG: %[[V1:.+]] = builtin.unrealized_conversion_cast %[[ARG1]] : vector<1xi32> to i32565// CHECK: %[[RES:.+]] = spirv.CompositeConstruct %[[V0]], %[[V1]] : (i32, i32) -> vector<2xi32>566// CHECK: return %[[RES]]567func.func @shuffle(%v0 : vector<1xi32>, %v1: vector<1xi32>) -> vector<2xi32> {568 %shuffle = vector.shuffle %v0, %v1 [0, 1] : vector<1xi32>, vector<1xi32>569 return %shuffle : vector<2xi32>570}571 572// -----573 574// CHECK-LABEL: func @shuffle575// CHECK-SAME: %[[ARG0:.+]]: vector<4xi32>, %[[ARG1:.+]]: vector<4xi32>576// CHECK: %[[EXTR:.+]] = spirv.CompositeExtract %[[ARG0]][0 : i32] : vector<4xi32>577// CHECK: %[[RES:.+]] = builtin.unrealized_conversion_cast %[[EXTR]] : i32 to vector<1xi32>578// CHECK: return %[[RES]] : vector<1xi32>579func.func @shuffle(%v0 : vector<4xi32>, %v1: vector<4xi32>) -> vector<1xi32> {580 %shuffle = vector.shuffle %v0, %v1 [0] : vector<4xi32>, vector<4xi32>581 return %shuffle : vector<1xi32>582}583 584// -----585 586// CHECK-LABEL: func @shuffle587// CHECK-SAME: %[[ARG0:.+]]: vector<4xi32>, %[[ARG1:.+]]: vector<4xi32>588// CHECK: %[[EXTR:.+]] = spirv.CompositeExtract %[[ARG1]][1 : i32] : vector<4xi32>589// CHECK: %[[RES:.+]] = builtin.unrealized_conversion_cast %[[EXTR]] : i32 to vector<1xi32>590// CHECK: return %[[RES]] : vector<1xi32>591func.func @shuffle(%v0 : vector<4xi32>, %v1: vector<4xi32>) -> vector<1xi32> {592 %shuffle = vector.shuffle %v0, %v1 [5] : vector<4xi32>, vector<4xi32>593 return %shuffle : vector<1xi32>594}595 596// -----597 598// CHECK-LABEL: func @shuffle599// CHECK-SAME: %[[ARG0:.+]]: vector<4xi32>, %[[ARG1:.+]]: vector<4xi32>600// CHECK: %[[SHUFFLE:.*]] = spirv.VectorShuffle [1 : i32, -1 : i32, 5 : i32, -1 : i32] %[[ARG0]], %[[ARG1]] : vector<4xi32>, vector<4xi32> -> vector<4xi32>601// CHECK: return %[[SHUFFLE]] : vector<4xi32>602func.func @shuffle(%v0 : vector<4xi32>, %v1: vector<4xi32>) -> vector<4xi32> {603 %shuffle = vector.shuffle %v0, %v1 [1, -1, 5, -1] : vector<4xi32>, vector<4xi32>604 return %shuffle : vector<4xi32>605}606 607// -----608 609// CHECK-LABEL: func @interleave610// CHECK-SAME: (%[[ARG0:.+]]: vector<2xf32>, %[[ARG1:.+]]: vector<2xf32>)611// CHECK: %[[SHUFFLE:.*]] = spirv.VectorShuffle [0 : i32, 2 : i32, 1 : i32, 3 : i32] %[[ARG0]], %[[ARG1]] : vector<2xf32>, vector<2xf32> -> vector<4xf32>612// CHECK: return %[[SHUFFLE]]613func.func @interleave(%a: vector<2xf32>, %b: vector<2xf32>) -> vector<4xf32> {614 %0 = vector.interleave %a, %b : vector<2xf32> -> vector<4xf32>615 return %0 : vector<4xf32>616}617 618// -----619 620// CHECK-LABEL: func @interleave_size1621// CHECK-SAME: (%[[ARG0:.+]]: vector<1xf32>, %[[ARG1:.+]]: vector<1xf32>)622// CHECK-DAG: %[[V0:.*]] = builtin.unrealized_conversion_cast %[[ARG0]] : vector<1xf32> to f32623// CHECK-DAG: %[[V1:.*]] = builtin.unrealized_conversion_cast %[[ARG1]] : vector<1xf32> to f32624// CHECK: %[[RES:.*]] = spirv.CompositeConstruct %[[V0]], %[[V1]] : (f32, f32) -> vector<2xf32>625// CHECK: return %[[RES]]626func.func @interleave_size1(%a: vector<1xf32>, %b: vector<1xf32>) -> vector<2xf32> {627 %0 = vector.interleave %a, %b : vector<1xf32> -> vector<2xf32>628 return %0 : vector<2xf32>629}630 631// -----632 633// CHECK-LABEL: func @deinterleave634// CHECK-SAME: (%[[ARG0:.+]]: vector<4xf32>)635// CHECK: %[[SHUFFLE0:.*]] = spirv.VectorShuffle [0 : i32, 2 : i32] %[[ARG0]], %[[ARG0]] : vector<4xf32>, vector<4xf32> -> vector<2xf32>636// CHECK: %[[SHUFFLE1:.*]] = spirv.VectorShuffle [1 : i32, 3 : i32] %[[ARG0]], %[[ARG0]] : vector<4xf32>, vector<4xf32> -> vector<2xf32>637// CHECK: return %[[SHUFFLE0]], %[[SHUFFLE1]]638func.func @deinterleave(%a: vector<4xf32>) -> (vector<2xf32>, vector<2xf32>) {639 %0, %1 = vector.deinterleave %a : vector<4xf32> -> vector<2xf32>640 return %0, %1 : vector<2xf32>, vector<2xf32>641}642 643// -----644 645// CHECK-LABEL: func @deinterleave_scalar646// CHECK-SAME: (%[[ARG0:.+]]: vector<2xf32>)647// CHECK-DAG: %[[EXTRACT0:.*]] = spirv.CompositeExtract %[[ARG0]][0 : i32] : vector<2xf32>648// CHECK-DAG: %[[EXTRACT1:.*]] = spirv.CompositeExtract %[[ARG0]][1 : i32] : vector<2xf32>649// CHECK-DAG: %[[CAST0:.*]] = builtin.unrealized_conversion_cast %[[EXTRACT0]] : f32 to vector<1xf32>650// CHECK-DAG: %[[CAST1:.*]] = builtin.unrealized_conversion_cast %[[EXTRACT1]] : f32 to vector<1xf32>651// CHECK: return %[[CAST0]], %[[CAST1]]652func.func @deinterleave_scalar(%a: vector<2xf32>) -> (vector<1xf32>, vector<1xf32>) {653 %0, %1 = vector.deinterleave %a: vector<2xf32> -> vector<1xf32>654 return %0, %1 : vector<1xf32>, vector<1xf32>655}656 657// -----658 659// CHECK-LABEL: func @reduction_add660// CHECK-SAME: (%[[V:.+]]: vector<4xi32>)661// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<4xi32>662// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<4xi32>663// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<4xi32>664// CHECK: %[[S3:.+]] = spirv.CompositeExtract %[[V]][3 : i32] : vector<4xi32>665// CHECK: %[[ADD0:.+]] = spirv.IAdd %[[S0]], %[[S1]]666// CHECK: %[[ADD1:.+]] = spirv.IAdd %[[ADD0]], %[[S2]]667// CHECK: %[[ADD2:.+]] = spirv.IAdd %[[ADD1]], %[[S3]]668// CHECK: return %[[ADD2]]669func.func @reduction_add(%v : vector<4xi32>) -> i32 {670 %reduce = vector.reduction <add>, %v : vector<4xi32> into i32671 return %reduce : i32672}673 674// -----675 676// CHECK-LABEL: func @reduction_addf_mulf677// CHECK-SAME: (%[[ARG0:.+]]: vector<4xf32>, %[[ARG1:.+]]: vector<4xf32>)678// CHECK: %[[DOT:.+]] = spirv.Dot %[[ARG0]], %[[ARG1]] : vector<4xf32> -> f32679// CHECK: return %[[DOT]] : f32680func.func @reduction_addf_mulf(%arg0: vector<4xf32>, %arg1: vector<4xf32>) -> f32 {681 %mul = arith.mulf %arg0, %arg1 : vector<4xf32>682 %red = vector.reduction <add>, %mul : vector<4xf32> into f32683 return %red : f32684}685 686// -----687 688// CHECK-LABEL: func @reduction_addf_acc_mulf689// CHECK-SAME: (%[[ARG0:.+]]: vector<4xf32>, %[[ARG1:.+]]: vector<4xf32>, %[[ACC:.+]]: f32)690// CHECK: %[[DOT:.+]] = spirv.Dot %[[ARG0]], %[[ARG1]] : vector<4xf32> -> f32691// CHECK: %[[RES:.+]] = spirv.FAdd %[[ACC]], %[[DOT]] : f32692// CHECK: return %[[RES]] : f32693func.func @reduction_addf_acc_mulf(%arg0: vector<4xf32>, %arg1: vector<4xf32>, %acc: f32) -> f32 {694 %mul = arith.mulf %arg0, %arg1 : vector<4xf32>695 %red = vector.reduction <add>, %mul, %acc : vector<4xf32> into f32696 return %red : f32697}698 699// -----700 701// CHECK-LABEL: func @reduction_addf702// CHECK-SAME: (%[[ARG0:.+]]: vector<4xf32>)703// CHECK: %[[ONE:.+]] = spirv.Constant dense<1.0{{.+}}> : vector<4xf32>704// CHECK: %[[DOT:.+]] = spirv.Dot %[[ARG0]], %[[ONE]] : vector<4xf32> -> f32705// CHECK: return %[[DOT]] : f32706func.func @reduction_addf_mulf(%arg0: vector<4xf32>) -> f32 {707 %red = vector.reduction <add>, %arg0 : vector<4xf32> into f32708 return %red : f32709}710 711// -----712 713// CHECK-LABEL: func @reduction_addf_acc714// CHECK-SAME: (%[[ARG0:.+]]: vector<4xf32>, %[[ACC:.+]]: f32)715// CHECK: %[[ONE:.+]] = spirv.Constant dense<1.0{{.*}}> : vector<4xf32>716// CHECK: %[[DOT:.+]] = spirv.Dot %[[ARG0]], %[[ONE]] : vector<4xf32> -> f32717// CHECK: %[[RES:.+]] = spirv.FAdd %[[ACC]], %[[DOT]] : f32718// CHECK: return %[[RES]] : f32719func.func @reduction_addf_acc(%arg0: vector<4xf32>, %acc: f32) -> f32 {720 %red = vector.reduction <add>, %arg0, %acc : vector<4xf32> into f32721 return %red : f32722}723 724// -----725 726// CHECK-LABEL: func @reduction_addf_one_elem727// CHECK-SAME: (%[[ARG0:.+]]: vector<1xf32>)728// CHECK: %[[RES:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : vector<1xf32> to f32729// CHECK: return %[[RES]] : f32730func.func @reduction_addf_one_elem(%arg0: vector<1xf32>) -> f32 {731 %red = vector.reduction <add>, %arg0 : vector<1xf32> into f32732 return %red : f32733}734 735// -----736 737// CHECK-LABEL: func @reduction_addf_one_elem_acc738// CHECK-SAME: (%[[ARG0:.+]]: vector<1xf32>, %[[ACC:.+]]: f32)739// CHECK: %[[RHS:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : vector<1xf32> to f32740// CHECK: %[[RES:.+]] = spirv.FAdd %[[ACC]], %[[RHS]] : f32741// CHECK: return %[[RES]] : f32742func.func @reduction_addf_one_elem_acc(%arg0: vector<1xf32>, %acc: f32) -> f32 {743 %red = vector.reduction <add>, %arg0, %acc : vector<1xf32> into f32744 return %red : f32745}746 747// -----748 749// CHECK-LABEL: func @reduction_mul750// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)751// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>752// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>753// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>754// CHECK: %[[MUL0:.+]] = spirv.FMul %[[S0]], %[[S1]]755// CHECK: %[[MUL1:.+]] = spirv.FMul %[[MUL0]], %[[S2]]756// CHECK: %[[MUL2:.+]] = spirv.FMul %[[MUL1]], %[[S]]757// CHECK: return %[[MUL2]]758func.func @reduction_mul(%v : vector<3xf32>, %s: f32) -> f32 {759 %reduce = vector.reduction <mul>, %v, %s : vector<3xf32> into f32760 return %reduce : f32761}762 763// -----764 765// CHECK-LABEL: func @reduction_maximumf766// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)767// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>768// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>769// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>770// CHECK: %[[MAX0:.+]] = spirv.GL.FMax %[[S0]], %[[S1]]771// CHECK: %[[MAX1:.+]] = spirv.GL.FMax %[[MAX0]], %[[S2]]772// CHECK: %[[MAX2:.+]] = spirv.GL.FMax %[[MAX1]], %[[S]]773// CHECK: return %[[MAX2]]774func.func @reduction_maximumf(%v : vector<3xf32>, %s: f32) -> f32 {775 %reduce = vector.reduction <maximumf>, %v, %s : vector<3xf32> into f32776 return %reduce : f32777}778 779// -----780 781// CHECK-LABEL: func @reduction_minimumf782// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)783// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>784// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>785// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>786// CHECK: %[[MIN0:.+]] = spirv.GL.FMin %[[S0]], %[[S1]]787// CHECK: %[[MIN1:.+]] = spirv.GL.FMin %[[MIN0]], %[[S2]]788// CHECK: %[[MIN2:.+]] = spirv.GL.FMin %[[MIN1]], %[[S]]789// CHECK: return %[[MIN2]]790func.func @reduction_minimumf(%v : vector<3xf32>, %s: f32) -> f32 {791 %reduce = vector.reduction <minimumf>, %v, %s : vector<3xf32> into f32792 return %reduce : f32793}794 795// -----796 797// CHECK-LABEL: func @reduction_maxsi798// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)799// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>800// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>801// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>802// CHECK: %[[MAX0:.+]] = spirv.GL.SMax %[[S0]], %[[S1]]803// CHECK: %[[MAX1:.+]] = spirv.GL.SMax %[[MAX0]], %[[S2]]804// CHECK: %[[MAX2:.+]] = spirv.GL.SMax %[[MAX1]], %[[S]]805// CHECK: return %[[MAX2]]806func.func @reduction_maxsi(%v : vector<3xi32>, %s: i32) -> i32 {807 %reduce = vector.reduction <maxsi>, %v, %s : vector<3xi32> into i32808 return %reduce : i32809}810 811// -----812 813// CHECK-LABEL: func @reduction_minsi814// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)815// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>816// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>817// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>818// CHECK: %[[MIN0:.+]] = spirv.GL.SMin %[[S0]], %[[S1]]819// CHECK: %[[MIN1:.+]] = spirv.GL.SMin %[[MIN0]], %[[S2]]820// CHECK: %[[MIN2:.+]] = spirv.GL.SMin %[[MIN1]], %[[S]]821// CHECK: return %[[MIN2]]822func.func @reduction_minsi(%v : vector<3xi32>, %s: i32) -> i32 {823 %reduce = vector.reduction <minsi>, %v, %s : vector<3xi32> into i32824 return %reduce : i32825}826 827// -----828 829// CHECK-LABEL: func @reduction_maxui830// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)831// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>832// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>833// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>834// CHECK: %[[MAX0:.+]] = spirv.GL.UMax %[[S0]], %[[S1]]835// CHECK: %[[MAX1:.+]] = spirv.GL.UMax %[[MAX0]], %[[S2]]836// CHECK: %[[MAX2:.+]] = spirv.GL.UMax %[[MAX1]], %[[S]]837// CHECK: return %[[MAX2]]838func.func @reduction_maxui(%v : vector<3xi32>, %s: i32) -> i32 {839 %reduce = vector.reduction <maxui>, %v, %s : vector<3xi32> into i32840 return %reduce : i32841}842 843// -----844 845// CHECK-LABEL: func @reduction_minui846// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)847// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>848// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>849// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>850// CHECK: %[[MIN0:.+]] = spirv.GL.UMin %[[S0]], %[[S1]]851// CHECK: %[[MIN1:.+]] = spirv.GL.UMin %[[MIN0]], %[[S2]]852// CHECK: %[[MIN2:.+]] = spirv.GL.UMin %[[MIN1]], %[[S]]853// CHECK: return %[[MIN2]]854func.func @reduction_minui(%v : vector<3xi32>, %s: i32) -> i32 {855 %reduce = vector.reduction <minui>, %v, %s : vector<3xi32> into i32856 return %reduce : i32857}858 859// -----860 861module attributes { spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [BFloat16DotProductKHR], [SPV_KHR_bfloat16]>, #spirv.resource_limits<>> } {862 863// CHECK-LABEL: func @reduction_bf16_addf_mulf864// CHECK-SAME: (%[[ARG0:.+]]: vector<4xbf16>, %[[ARG1:.+]]: vector<4xbf16>)865// CHECK: %[[DOT:.+]] = spirv.Dot %[[ARG0]], %[[ARG1]] : vector<4xbf16> -> bf16866// CHECK: return %[[DOT]] : bf16867func.func @reduction_bf16_addf_mulf(%arg0: vector<4xbf16>, %arg1: vector<4xbf16>) -> bf16 {868 %mul = arith.mulf %arg0, %arg1 : vector<4xbf16>869 %red = vector.reduction <add>, %mul : vector<4xbf16> into bf16870 return %red : bf16871}872 873} // end module874 875// -----876 877// CHECK-LABEL: @shape_cast_same_type878// CHECK-SAME: (%[[ARG0:.*]]: vector<2xf32>)879// CHECK: return %[[ARG0]]880func.func @shape_cast_same_type(%arg0 : vector<2xf32>) -> vector<2xf32> {881 %1 = vector.shape_cast %arg0 : vector<2xf32> to vector<2xf32>882 return %arg0 : vector<2xf32>883}884 885// -----886 887// CHECK-LABEL: @shape_cast_size1_vector888// CHECK-SAME: (%[[ARG0:.*]]: vector<f32>)889// CHECK: %[[R0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : vector<f32> to f32890// CHECK: %[[R1:.+]] = builtin.unrealized_conversion_cast %[[R0]] : f32 to vector<1xf32>891// CHECK: return %[[R1]]892func.func @shape_cast_size1_vector(%arg0 : vector<f32>) -> vector<1xf32> {893 %1 = vector.shape_cast %arg0 : vector<f32> to vector<1xf32>894 return %1 : vector<1xf32>895}896 897// -----898 899// CHECK-LABEL: @step()900// CHECK: %[[CST0:.*]] = spirv.Constant 0 : i32901// CHECK: %[[CST1:.*]] = spirv.Constant 1 : i32902// CHECK: %[[CST2:.*]] = spirv.Constant 2 : i32903// CHECK: %[[CST3:.*]] = spirv.Constant 3 : i32904// CHECK: %[[CONSTRUCT:.*]] = spirv.CompositeConstruct %[[CST0]], %[[CST1]], %[[CST2]], %[[CST3]] : (i32, i32, i32, i32) -> vector<4xi32>905// CHECK: %[[CAST:.*]] = builtin.unrealized_conversion_cast %[[CONSTRUCT]] : vector<4xi32> to vector<4xindex>906// CHECK: return %[[CAST]] : vector<4xindex>907func.func @step() -> vector<4xindex> {908 %0 = vector.step : vector<4xindex>909 return %0 : vector<4xindex>910}911 912// -----913 914// CHECK-LABEL: @step_size1()915// CHECK: %[[CST0:.*]] = spirv.Constant 0 : i32916// CHECK: %[[CAST:.*]] = builtin.unrealized_conversion_cast %[[CST0]] : i32 to vector<1xindex>917// CHECK: return %[[CAST]] : vector<1xindex>918func.func @step_size1() -> vector<1xindex> {919 %0 = vector.step : vector<1xindex>920 return %0 : vector<1xindex>921}922 923// -----924 925module attributes {926 spirv.target_env = #spirv.target_env<927 #spirv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, #spirv.resource_limits<>>928 } {929 930// CHECK-LABEL: @vector_load931// CHECK-SAME: (%[[ARG0:.*]]: memref<4xf32, #spirv.storage_class<StorageBuffer>>)932// CHECK: %[[S0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : memref<4xf32, #spirv.storage_class<StorageBuffer>> to !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>933// CHECK: %[[C0:.+]] = arith.constant 0 : index934// CHECK: %[[S1:.+]] = builtin.unrealized_conversion_cast %[[C0]] : index to i32935// CHECK: %[[CST1:.+]] = spirv.Constant 0 : i32936// CHECK: %[[CST2:.+]] = spirv.Constant 0 : i32937// CHECK: %[[CST3:.+]] = spirv.Constant 1 : i32938// CHECK: %[[S4:.+]] = spirv.AccessChain %[[S0]][%[[CST1]], %[[S1]]] : !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>, i32, i32939// CHECK: %[[S5:.+]] = spirv.Bitcast %[[S4]] : !spirv.ptr<f32, StorageBuffer> to !spirv.ptr<vector<4xf32>, StorageBuffer>940// CHECK: %[[R0:.+]] = spirv.Load "StorageBuffer" %[[S5]] : vector<4xf32>941// CHECK: return %[[R0]] : vector<4xf32>942func.func @vector_load(%arg0 : memref<4xf32, #spirv.storage_class<StorageBuffer>>) -> vector<4xf32> {943 %idx = arith.constant 0 : index944 %cst_0 = arith.constant 0.000000e+00 : f32945 %0 = vector.load %arg0[%idx] : memref<4xf32, #spirv.storage_class<StorageBuffer>>, vector<4xf32>946 return %0: vector<4xf32>947}948 949 950// CHECK-LABEL: @vector_load_single_elem951// CHECK-SAME: (%[[ARG0:.*]]: memref<4xf32, #spirv.storage_class<StorageBuffer>>)952// CHECK: %[[S0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : memref<4xf32, #spirv.storage_class<StorageBuffer>> to !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>953// CHECK: %[[C0:.+]] = arith.constant 0 : index954// CHECK: %[[S1:.+]] = builtin.unrealized_conversion_cast %[[C0]] : index to i32955// CHECK: %[[CST1:.+]] = spirv.Constant 0 : i32956// CHECK: %[[CST2:.+]] = spirv.Constant 0 : i32957// CHECK: %[[CST3:.+]] = spirv.Constant 1 : i32958// CHECK: %[[S4:.+]] = spirv.AccessChain %[[S0]][%[[CST1]], %[[S1]]] : !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>, i32, i32959// CHECK: %[[S5:.+]] = spirv.Load "StorageBuffer" %[[S4]] : f32960// CHECK: %[[R0:.+]] = builtin.unrealized_conversion_cast %[[S5]] : f32 to vector<1xf32>961// CHECK: return %[[R0]] : vector<1xf32>962func.func @vector_load_single_elem(%arg0 : memref<4xf32, #spirv.storage_class<StorageBuffer>>) -> vector<1xf32> {963 %idx = arith.constant 0 : index964 %cst_0 = arith.constant 0.000000e+00 : f32965 %0 = vector.load %arg0[%idx] : memref<4xf32, #spirv.storage_class<StorageBuffer>>, vector<1xf32>966 return %0: vector<1xf32>967}968 969// CHECK-LABEL: @vector_load_aligned970func.func @vector_load_aligned(%arg0 : memref<4xf32, #spirv.storage_class<StorageBuffer>>) -> vector<4xf32> {971 %idx = arith.constant 0 : index972 // CHECK: spirv.Load973 // CHECK-SAME: ["Aligned", 8]974 %0 = vector.load %arg0[%idx] { alignment = 8 } : memref<4xf32, #spirv.storage_class<StorageBuffer>>, vector<4xf32>975 return %0: vector<4xf32>976}977 978// CHECK-LABEL: @vector_load_2d979// CHECK-SAME: (%[[ARG0:.*]]: memref<4x4xf32, #spirv.storage_class<StorageBuffer>>) -> vector<4xf32> {980// CHECK: %[[S0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : memref<4x4xf32, #spirv.storage_class<StorageBuffer>> to !spirv.ptr<!spirv.struct<(!spirv.array<16 x f32, stride=4> [0])>, StorageBuffer>981// CHECK: %[[C0:.+]] = arith.constant 0 : index982// CHECK: %[[S1:.+]] = builtin.unrealized_conversion_cast %[[C0]] : index to i32983// CHECK: %[[C1:.+]] = arith.constant 1 : index984// CHECK: %[[S2:.+]] = builtin.unrealized_conversion_cast %[[C1]] : index to i32985// CHECK: %[[CST0_1:.+]] = spirv.Constant 0 : i32986// CHECK: %[[CST0_2:.+]] = spirv.Constant 0 : i32987// CHECK: %[[CST4:.+]] = spirv.Constant 4 : i32988// CHECK: %[[S3:.+]] = spirv.IMul %[[S1]], %[[CST4]] : i32989// CHECK: %[[CST1:.+]] = spirv.Constant 1 : i32990// CHECK: %[[S6:.+]] = spirv.IAdd %[[S2]], %[[S3]] : i32991// CHECK: %[[S7:.+]] = spirv.AccessChain %[[S0]][%[[CST0_1]], %[[S6]]] : !spirv.ptr<!spirv.struct<(!spirv.array<16 x f32, stride=4> [0])>, StorageBuffer>, i32, i32992// CHECK: %[[S8:.+]] = spirv.Bitcast %[[S7]] : !spirv.ptr<f32, StorageBuffer> to !spirv.ptr<vector<4xf32>, StorageBuffer>993// CHECK: %[[R0:.+]] = spirv.Load "StorageBuffer" %[[S8]] : vector<4xf32>994// CHECK: return %[[R0]] : vector<4xf32>995func.func @vector_load_2d(%arg0 : memref<4x4xf32, #spirv.storage_class<StorageBuffer>>) -> vector<4xf32> {996 %idx_0 = arith.constant 0 : index997 %idx_1 = arith.constant 1 : index998 %0 = vector.load %arg0[%idx_0, %idx_1] : memref<4x4xf32, #spirv.storage_class<StorageBuffer>>, vector<4xf32>999 return %0: vector<4xf32>1000}1001 1002// CHECK-LABEL: @vector_store1003// CHECK-SAME: (%[[ARG0:.*]]: memref<4xf32, #spirv.storage_class<StorageBuffer>>1004// CHECK-SAME: %[[ARG1:.*]]: vector<4xf32>1005// CHECK: %[[S0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : memref<4xf32, #spirv.storage_class<StorageBuffer>> to !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>1006// CHECK: %[[C0:.+]] = arith.constant 0 : index1007// CHECK: %[[S1:.+]] = builtin.unrealized_conversion_cast %[[C0]] : index to i321008// CHECK: %[[CST1:.+]] = spirv.Constant 0 : i321009// CHECK: %[[CST2:.+]] = spirv.Constant 0 : i321010// CHECK: %[[CST3:.+]] = spirv.Constant 1 : i321011// CHECK: %[[S4:.+]] = spirv.AccessChain %[[S0]][%[[CST1]], %[[S1]]] : !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>, i32, i321012// CHECK: %[[S5:.+]] = spirv.Bitcast %[[S4]] : !spirv.ptr<f32, StorageBuffer> to !spirv.ptr<vector<4xf32>, StorageBuffer>1013// CHECK: spirv.Store "StorageBuffer" %[[S5]], %[[ARG1]] : vector<4xf32>1014func.func @vector_store(%arg0 : memref<4xf32, #spirv.storage_class<StorageBuffer>>, %arg1 : vector<4xf32>) {1015 %idx = arith.constant 0 : index1016 vector.store %arg1, %arg0[%idx] : memref<4xf32, #spirv.storage_class<StorageBuffer>>, vector<4xf32>1017 return1018}1019 1020// CHECK-LABEL: @vector_store_aligned1021func.func @vector_store_aligned(%arg0 : memref<4xf32, #spirv.storage_class<StorageBuffer>>, %arg1 : vector<4xf32>) {1022 %idx = arith.constant 0 : index1023 // CHECK: spirv.Store1024 // CHECK-SAME: ["Aligned", 8]1025 vector.store %arg1, %arg0[%idx] { alignment = 8 } : memref<4xf32, #spirv.storage_class<StorageBuffer>>, vector<4xf32>1026 return1027}1028 1029// CHECK-LABEL: @vector_store_single_elem1030// CHECK-SAME: (%[[ARG0:.*]]: memref<4xf32, #spirv.storage_class<StorageBuffer>>1031// CHECK-SAME: %[[ARG1:.*]]: vector<1xf32>1032// CHECK: %[[S0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : memref<4xf32, #spirv.storage_class<StorageBuffer>> to !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>1033// CHECK: %[[S1:.+]] = builtin.unrealized_conversion_cast %[[ARG1]] : vector<1xf32> to f321034// CHECK: %[[C0:.+]] = arith.constant 0 : index1035// CHECK: %[[S2:.+]] = builtin.unrealized_conversion_cast %[[C0]] : index to i321036// CHECK: %[[CST1:.+]] = spirv.Constant 0 : i321037// CHECK: %[[CST2:.+]] = spirv.Constant 0 : i321038// CHECK: %[[CST3:.+]] = spirv.Constant 1 : i321039// CHECK: %[[S4:.+]] = spirv.AccessChain %[[S0]][%[[CST1]], %[[S2]]] : !spirv.ptr<!spirv.struct<(!spirv.array<4 x f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer>1040// CHECK: spirv.Store "StorageBuffer" %[[S4]], %[[S1]] : f321041func.func @vector_store_single_elem(%arg0 : memref<4xf32, #spirv.storage_class<StorageBuffer>>, %arg1 : vector<1xf32>) {1042 %idx = arith.constant 0 : index1043 vector.store %arg1, %arg0[%idx] : memref<4xf32, #spirv.storage_class<StorageBuffer>>, vector<1xf32>1044 return1045}1046 1047// CHECK-LABEL: @vector_store_2d1048// CHECK-SAME: (%[[ARG0:.*]]: memref<4x4xf32, #spirv.storage_class<StorageBuffer>>1049// CHECK-SAME: %[[ARG1:.*]]: vector<4xf32>1050// CHECK: %[[S0:.+]] = builtin.unrealized_conversion_cast %[[ARG0]] : memref<4x4xf32, #spirv.storage_class<StorageBuffer>> to !spirv.ptr<!spirv.struct<(!spirv.array<16 x f32, stride=4> [0])>, StorageBuffer>1051// CHECK: %[[C0:.+]] = arith.constant 0 : index1052// CHECK: %[[S1:.+]] = builtin.unrealized_conversion_cast %[[C0]] : index to i321053// CHECK: %[[C1:.+]] = arith.constant 1 : index1054// CHECK: %[[S2:.+]] = builtin.unrealized_conversion_cast %[[C1]] : index to i321055// CHECK: %[[CST0_1:.+]] = spirv.Constant 0 : i321056// CHECK: %[[CST0_2:.+]] = spirv.Constant 0 : i321057// CHECK: %[[CST4:.+]] = spirv.Constant 4 : i321058// CHECK: %[[S3:.+]] = spirv.IMul %[[S1]], %[[CST4]] : i321059// CHECK: %[[CST1:.+]] = spirv.Constant 1 : i321060// CHECK: %[[S6:.+]] = spirv.IAdd %[[S2]], %[[S3]] : i321061// CHECK: %[[S7:.+]] = spirv.AccessChain %[[S0]][%[[CST0_1]], %[[S6]]] : !spirv.ptr<!spirv.struct<(!spirv.array<16 x f32, stride=4> [0])>, StorageBuffer>, i32, i321062// CHECK: %[[S8:.+]] = spirv.Bitcast %[[S7]] : !spirv.ptr<f32, StorageBuffer> to !spirv.ptr<vector<4xf32>, StorageBuffer>1063// CHECK: spirv.Store "StorageBuffer" %[[S8]], %[[ARG1]] : vector<4xf32>1064func.func @vector_store_2d(%arg0 : memref<4x4xf32, #spirv.storage_class<StorageBuffer>>, %arg1 : vector<4xf32>) {1065 %idx_0 = arith.constant 0 : index1066 %idx_1 = arith.constant 1 : index1067 vector.store %arg1, %arg0[%idx_0, %idx_1] : memref<4x4xf32, #spirv.storage_class<StorageBuffer>>, vector<4xf32>1068 return1069}1070 1071} // end module1072 1073// -----1074 1075// Ensure the case without module attributes not crash.1076 1077// CHECK-LABEL: @vector_load1078// CHECK: vector.load1079func.func @vector_load(%arg0 : memref<4xf32, #spirv.storage_class<StorageBuffer>>) -> vector<4xf32> {1080 %idx = arith.constant 0 : index1081 %0 = vector.load %arg0[%idx] : memref<4xf32, #spirv.storage_class<StorageBuffer>>, vector<4xf32>1082 return %0: vector<4xf32>1083}1084