brintos

brintos / llvm-project-archived public Read only

0
0
Text · 170.4 KiB · 084f49f Raw
3964 lines · plain
1// RUN: mlir-opt %s -canonicalize="test-convergence" -split-input-file -allow-unregistered-dialect | FileCheck %s2 3// CHECK-LABEL: create_vector_mask_to_constant_mask4func.func @create_vector_mask_to_constant_mask() -> (vector<4x3xi1>) {5  %c2 = arith.constant 2 : index6  %c3 = arith.constant 3 : index7  // CHECK: vector.constant_mask [3, 2] : vector<4x3xi1>8  %0 = vector.create_mask %c3, %c2 : vector<4x3xi1>9  return %0 : vector<4x3xi1>10}11 12// -----13 14// CHECK-LABEL: create_scalable_vector_mask_to_constant_mask15func.func @create_scalable_vector_mask_to_constant_mask() -> (vector<[8]xi1>) {16  %c-1 = arith.constant -1 : index17  // CHECK: arith.constant dense<false> : vector<[8]xi1>18  %0 = vector.create_mask %c-1 : vector<[8]xi1>19  return %0 : vector<[8]xi1>20}21 22// -----23 24// CHECK-LABEL: create_vector_mask_to_constant_mask_truncation25func.func @create_vector_mask_to_constant_mask_truncation() -> (vector<4x3xi1>) {26  %c2 = arith.constant 2 : index27  %c5 = arith.constant 5 : index28  // CHECK: vector.constant_mask [4, 2] : vector<4x3xi1>29  %0 = vector.create_mask %c5, %c2 : vector<4x3xi1>30  return %0 : vector<4x3xi1>31}32 33// -----34 35// CHECK-LABEL: create_vector_mask_to_constant_mask_truncation_neg36func.func @create_vector_mask_to_constant_mask_truncation_neg() -> (vector<4x3xi1>) {37  %cneg2 = arith.constant -2 : index38  %c5 = arith.constant 5 : index39  // CHECK: arith.constant dense<false> : vector<4x3xi1>40  %0 = vector.create_mask %c5, %cneg2 : vector<4x3xi1>41  return %0 : vector<4x3xi1>42}43 44// -----45 46// CHECK-LABEL: create_vector_mask_to_constant_mask_truncation_zero47func.func @create_vector_mask_to_constant_mask_truncation_zero() -> (vector<4x3xi1>) {48  %c2 = arith.constant 2 : index49  %c0 = arith.constant 0 : index50  // CHECK: arith.constant dense<false> : vector<4x3xi1>51  %0 = vector.create_mask %c0, %c2 : vector<4x3xi1>52  return %0 : vector<4x3xi1>53}54 55// -----56 57// CHECK-LABEL: create_vector_mask_to_constant_mask_scalable_all_true58func.func @create_vector_mask_to_constant_mask_scalable_all_true() -> (vector<8x[16]xi1>) {59  %c8 = arith.constant 8 : index60  %c16 = arith.constant 16 : index61  %0 = vector.vscale62  %1 = arith.muli %0, %c16 : index63  // CHECK: arith.constant dense<true> : vector<8x[16]xi1>64  %10 = vector.create_mask %c8, %1 : vector<8x[16]xi1>65  return %10 : vector<8x[16]xi1>66}67 68// -----69 70// CHECK-LABEL: create_mask_transpose_to_transposed_create_mask71//  CHECK-SAME: %[[DIM0:.*]]: index, %[[DIM1:.*]]: index, %[[DIM2:.*]]: index72func.func @create_mask_transpose_to_transposed_create_mask(73  %dim0: index, %dim1: index, %dim2: index) -> (vector<2x3x4xi1>, vector<4x2x3xi1>) {74  //     CHECK: vector.create_mask %[[DIM0]], %[[DIM1]], %[[DIM2]] : vector<2x3x4xi1>75  //     CHECK: vector.create_mask %[[DIM2]], %[[DIM0]], %[[DIM1]] : vector<4x2x3xi1>76  // CHECK-NOT: vector.transpose77  %0 = vector.create_mask %dim0, %dim1, %dim2 : vector<2x3x4xi1>78  %1 = vector.transpose %0, [2, 0, 1] : vector<2x3x4xi1> to vector<4x2x3xi1>79  return %0, %1 : vector<2x3x4xi1>, vector<4x2x3xi1>80}81 82// -----83 84// CHECK-LABEL: extract_from_create_mask85//  CHECK-SAME: %[[DIM0:.*]]: index, %[[DIM1:.*]]: index86func.func @extract_from_create_mask(%dim0: index, %dim1: index) -> vector<[4]x[4]xi1> {87  %c2 = arith.constant 2 : index88  %mask = vector.create_mask %c2, %dim0, %dim1 : vector<4x[4]x[4]xi1>89  // CHECK: vector.create_mask %[[DIM0]], %[[DIM1]] : vector<[4]x[4]xi1>90  // CHECK-NOT: vector.extract91  %extract = vector.extract %mask[1] : vector<[4]x[4]xi1> from vector<4x[4]x[4]xi1>92  return %extract : vector<[4]x[4]xi1>93}94 95// -----96 97// CHECK-LABEL: extract_from_create_mask_all_false98func.func @extract_from_create_mask_all_false(%dim0: index, %dim1: index) -> vector<[4]x[4]xi1> {99  %c2 = arith.constant 2 : index100  %mask = vector.create_mask %c2, %dim0, %dim1 : vector<4x[4]x[4]xi1>101  // CHECK: arith.constant dense<false> : vector<[4]x[4]xi1>102  // CHECK-NOT: vector.extract103  %extract = vector.extract %mask[2] : vector<[4]x[4]xi1> from vector<4x[4]x[4]xi1>104  return %extract : vector<[4]x[4]xi1>105}106 107// -----108 109// CHECK-LABEL: extract_from_create_mask_leading_scalable110//  CHECK-SAME: %[[DIM0:.*]]: index111func.func @extract_from_create_mask_leading_scalable(%dim0: index) -> vector<8xi1> {112  %c3 = arith.constant 3 : index113  %mask = vector.create_mask %c3, %dim0 : vector<[4]x8xi1>114  // CHECK: vector.create_mask %[[DIM0]] : vector<8xi1>115  // CHECK-NOT: vector.extract116  %extract = vector.extract %mask[1] : vector<8xi1> from vector<[4]x8xi1>117  return %extract : vector<8xi1>118}119 120// -----121 122// CHECK-LABEL: extract_from_create_mask_dynamic_position123//  CHECK-SAME: %[[DIM0:.*]]: index, %[[INDEX:.*]]: index124func.func @extract_from_create_mask_dynamic_position(%dim0: index, %index: index) -> vector<6xi1> {125  %c4 = arith.constant 4 : index126  %c3 = arith.constant 3 : index127  %mask = vector.create_mask %c3, %c4, %dim0 : vector<4x4x6xi1>128  // CHECK: vector.create_mask %[[DIM0]] : vector<6xi1>129  // CHECK-NOT: vector.extract130  %extract = vector.extract %mask[2, %index] : vector<6xi1> from vector<4x4x6xi1>131  return %extract : vector<6xi1>132}133 134// -----135 136// CHECK-LABEL: @extract_scalar_poison137func.func @extract_scalar_poison() -> f32 {138  // CHECK-NEXT: %[[UB:.*]] = ub.poison : f32139  //  CHECK-NOT: vector.extract140  // CHECK-NEXT: return %[[UB]] : f32141  %0 = ub.poison : vector<4x8xf32>142  %1 = vector.extract %0[2, 4] : f32 from vector<4x8xf32>143  return %1 : f32144}145 146// -----147 148// CHECK-LABEL: @extract_vector_poison149func.func @extract_vector_poison() -> vector<8xf32> {150  // CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<8xf32>151  //  CHECK-NOT: vector.extract152  // CHECK-NEXT: return %[[UB]] : vector<8xf32>153  %0 = ub.poison : vector<4x8xf32>154  %1 = vector.extract %0[2] : vector<8xf32> from vector<4x8xf32>155  return %1 : vector<8xf32>156}157 158// -----159 160// CHECK-LABEL: @extract_scalar_poison_idx161func.func @extract_scalar_poison_idx(%a: vector<4x5xf32>) -> f32 {162  // CHECK-NEXT: %[[UB:.*]] = ub.poison : f32163  //  CHECK-NOT: vector.extract164  // CHECK-NEXT: return %[[UB]] : f32165  %0 = vector.extract %a[-1, 0] : f32 from vector<4x5xf32>166  return %0 : f32167}168 169// -----170 171// Similar to the test above, but the index is not a static constant.172 173// CHECK-LABEL: @extract_scalar_poison_idx_non_cst174func.func @extract_scalar_poison_idx_non_cst(%a: vector<4x5xf32>) -> f32 {175  // CHECK-NEXT: %[[UB:.*]] = ub.poison : f32176  //  CHECK-NOT: vector.extract177  // CHECK-NEXT: return %[[UB]] : f32178  %c_neg_1 = arith.constant -1 : index179  %0 = vector.extract %a[%c_neg_1, 0] : f32 from vector<4x5xf32>180  return %0 : f32181}182 183// -----184 185// Similar to test above, but now the index is out-of-bounds.186 187// CHECK-LABEL: @no_fold_extract_scalar_oob_idx188func.func @no_fold_extract_scalar_oob_idx(%a: vector<4x5xf32>) -> f32 {189  //  CHECK: vector.extract190  %c_neg_2 = arith.constant -2 : index191  %0 = vector.extract %a[%c_neg_2, 0] : f32 from vector<4x5xf32>192  return %0 : f32193}194 195 196// -----197 198// CHECK-LABEL: @extract_vector_poison_idx199func.func @extract_vector_poison_idx(%a: vector<4x5xf32>) -> vector<5xf32> {200  // CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<5xf32>201  //  CHECK-NOT: vector.extract202  // CHECK-NEXT: return %[[UB]] : vector<5xf32>203  %0 = vector.extract %a[-1] : vector<5xf32> from vector<4x5xf32>204  return %0 : vector<5xf32>205}206 207// -----208 209// CHECK-LABEL: @extract_multiple_poison_idx210func.func @extract_multiple_poison_idx(%a: vector<4x5x8xf32>)211    -> vector<8xf32> {212  // CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<8xf32>213  //  CHECK-NOT: vector.extract214  // CHECK-NEXT: return %[[UB]] : vector<8xf32>215  %0 = vector.extract %a[-1, -1] : vector<8xf32> from vector<4x5x8xf32>216  return %0 : vector<8xf32>217}218 219// -----220 221// CHECK-LABEL: extract_from_create_mask_dynamic_position_all_false222//  CHECK-SAME: %[[DIM0:.*]]: index, %[[INDEX:.*]]: index223func.func @extract_from_create_mask_dynamic_position_all_false(%dim0: index, %index: index) -> vector<6xi1> {224  %c0 = arith.constant 0 : index225  %c1 = arith.constant 1 : index226  %mask = vector.create_mask %c1, %c0, %dim0 : vector<1x4x6xi1>227  // CHECK: arith.constant dense<false> : vector<6xi1>228  // CHECK-NOT: vector.extract229  %extract = vector.extract %mask[0, %index] : vector<6xi1> from vector<1x4x6xi1>230  return %extract : vector<6xi1>231}232 233// -----234 235// CHECK-LABEL: extract_from_create_mask_dynamic_position_unknown236//  CHECK-SAME: %[[DIM0:.*]]: index, %[[INDEX:.*]]: index237func.func @extract_from_create_mask_dynamic_position_unknown(%dim0: index, %index: index) -> vector<6xi1> {238  %c2 = arith.constant 2 : index239  %mask = vector.create_mask %c2, %dim0 : vector<4x6xi1>240  // CHECK: %[[C2:.*]] = arith.constant 2 : index241  // CHECK-NEXT: %[[MASK:.*]] = vector.create_mask %[[C2]], %[[DIM0]] : vector<4x6xi1>242  // CHECK-NEXT: vector.extract %[[MASK]][%[[INDEX]]] : vector<6xi1> from vector<4x6xi1>243  %extract = vector.extract %mask[%index] : vector<6xi1> from vector<4x6xi1>244  return %extract : vector<6xi1>245}246 247// -----248 249// CHECK-LABEL: extract_from_create_mask_mixed_position_unknown250//  CHECK-SAME: %[[DIM0:.*]]: index, %[[INDEX:.*]]: index251func.func @extract_from_create_mask_mixed_position_unknown(%dim0: index, %index0: index) -> vector<4xi1> {252  %c2 = arith.constant 2 : index253  %mask = vector.create_mask %c2, %c2, %dim0 : vector<2x4x4xi1>254  // CHECK: %[[C2:.*]] = arith.constant 2 : index255  // CHECK-NEXT: %[[MASK:.*]] = vector.create_mask %[[C2]], %[[C2]], %[[DIM0]] : vector<2x4x4xi1>256  // CHECK-NEXT: vector.extract %[[MASK]][1, %[[INDEX]]] : vector<4xi1> from vector<2x4x4xi1>257  %extract = vector.extract %mask[1, %index0] : vector<4xi1> from vector<2x4x4xi1>258  return %extract : vector<4xi1>259}260 261// -----262 263// CHECK-LABEL: extract_from_non_constant_create_mask264//  CHECK-SAME: %[[DIM0:.*]]: index265func.func @extract_from_non_constant_create_mask(%dim0: index) -> vector<[2]xi1> {266  %mask = vector.create_mask %dim0, %dim0 : vector<[2]x[2]xi1>267  // CHECK: %[[MASK:.*]] = vector.create_mask %[[DIM0]], %[[DIM0]] : vector<[2]x[2]xi1>268  // CHECK-NEXT: vector.extract %[[MASK]][0] : vector<[2]xi1> from vector<[2]x[2]xi1>269  %extract = vector.extract %mask[0] : vector<[2]xi1> from vector<[2]x[2]xi1>270  return %extract : vector<[2]xi1>271}272 273// -----274 275// CHECK-LABEL: constant_mask_to_true_splat276func.func @constant_mask_to_true_splat() -> vector<2x4xi1> {277  // CHECK: arith.constant dense<true>278  // CHECK-NOT: vector.constant_mask279  %0 = vector.constant_mask [2, 4] : vector<2x4xi1>280  return %0 : vector<2x4xi1>281}282 283// CHECK-LABEL: constant_mask_to_false_splat284func.func @constant_mask_to_false_splat() -> vector<2x4xi1> {285  // CHECK: arith.constant dense<false>286  // CHECK-NOT: vector.constant_mask287  %0 = vector.constant_mask [0, 0] : vector<2x4xi1>288  return %0 : vector<2x4xi1>289}290 291// CHECK-LABEL: constant_mask_to_true_splat_0d292func.func @constant_mask_to_true_splat_0d() -> vector<i1> {293  // CHECK: arith.constant dense<true>294  // CHECK-NOT: vector.constant_mask295  %0 = vector.constant_mask [1] : vector<i1>296  return %0 : vector<i1>297}298 299// CHECK-LABEL: constant_mask_transpose_to_transposed_constant_mask300func.func @constant_mask_transpose_to_transposed_constant_mask() -> (vector<2x3x4xi1>, vector<4x2x3xi1>) {301  //     CHECK: vector.constant_mask [1, 2, 3] : vector<2x3x4xi1>302  //     CHECK: vector.constant_mask [3, 1, 2] : vector<4x2x3xi1>303  // CHECK-NOT: vector.transpose304  %0 = vector.constant_mask [1, 2, 3] : vector<2x3x4xi1>305  %1 = vector.transpose %0, [2, 0, 1] : vector<2x3x4xi1> to vector<4x2x3xi1>306  return %0, %1 : vector<2x3x4xi1>, vector<4x2x3xi1>307}308 309// -----310 311func.func @extract_strided_slice_of_constant_mask() -> (vector<2x2xi1>) {312  %0 = vector.constant_mask [2, 2] : vector<4x3xi1>313  %1 = vector.extract_strided_slice %0314    {offsets = [0, 0], sizes = [2, 2], strides = [1, 1]}315      : vector<4x3xi1> to vector<2x2xi1>316  // CHECK: arith.constant dense<true> : vector<2x2xi1>317  return %1 : vector<2x2xi1>318}319 320// -----321 322func.func @extract_strided_slice_of_constant_mask() -> (vector<2x2xi1>) {323  %0 = vector.constant_mask [2, 2] : vector<4x3xi1>324  %1 = vector.extract_strided_slice %0325    {offsets = [1, 0], sizes = [2, 2], strides = [1, 1]}326      : vector<4x3xi1> to vector<2x2xi1>327  // CHECK: vector.constant_mask [1, 2] : vector<2x2xi1>328  return %1 : vector<2x2xi1>329}330 331// -----332 333func.func @extract_strided_slice_of_constant_mask() -> (vector<2x2xi1>) {334  %0 = vector.constant_mask [2, 2] : vector<4x3xi1>335  %1 = vector.extract_strided_slice %0336    {offsets = [0, 1], sizes = [2, 2], strides = [1, 1]}337      : vector<4x3xi1> to vector<2x2xi1>338  // CHECK: vector.constant_mask [2, 1] : vector<2x2xi1>339  return %1 : vector<2x2xi1>340}341 342// -----343 344func.func @extract_strided_slice_of_constant_mask() -> (vector<2x2xi1>) {345  %0 = vector.constant_mask [2, 2] : vector<4x3xi1>346  %1 = vector.extract_strided_slice %0347    {offsets = [2, 0], sizes = [2, 2], strides = [1, 1]}348      : vector<4x3xi1> to vector<2x2xi1>349  // CHECK: arith.constant dense<false> : vector<2x2xi1>350  return %1 : vector<2x2xi1>351}352 353// -----354 355func.func @extract_strided_slice_of_constant_mask() -> (vector<2x1xi1>) {356  %0 = vector.constant_mask [2, 2] : vector<4x3xi1>357  %1 = vector.extract_strided_slice %0358    {offsets = [0, 2], sizes = [2, 1], strides = [1, 1]}359      : vector<4x3xi1> to vector<2x1xi1>360  // CHECK: arith.constant dense<false> : vector<2x1xi1>361  return %1 : vector<2x1xi1>362}363 364// -----365 366func.func @extract_strided_slice_of_constant_mask() -> (vector<2x1xi1>) {367  %0 = vector.constant_mask [2, 2] : vector<4x3xi1>368  %1 = vector.extract_strided_slice %0369    {offsets = [0, 1], sizes = [2, 1], strides = [1, 1]}370      : vector<4x3xi1> to vector<2x1xi1>371  // CHECK: arith.constant dense<true> : vector<2x1xi1>372  return %1 : vector<2x1xi1>373}374 375// -----376 377func.func @extract_strided_slice_of_constant_mask() -> (vector<2x1xi1>) {378  %0 = vector.constant_mask [2, 2] : vector<4x3xi1>379  %1 = vector.extract_strided_slice %0380    {offsets = [1, 1], sizes = [2, 1], strides = [1, 1]}381      : vector<4x3xi1> to vector<2x1xi1>382  // CHECK: vector.constant_mask [1, 1] : vector<2x1xi1>383  return %1 : vector<2x1xi1>384}385 386// -----387 388// CHECK-LABEL: func.func @extract_strided_slice_of_create_mask389// CHECK-SAME: (%[[DIM0:.+]]: index, %[[DIM1:.+]]: index)390func.func @extract_strided_slice_of_create_mask(%dim0: index, %dim1: index) -> (vector<2x2xi1>) {391  %0 = vector.create_mask %dim0, %dim1 : vector<4x3xi1>392  %1 = vector.extract_strided_slice %0393    {offsets = [2, 1], sizes = [2, 2], strides = [1, 1]}394      : vector<4x3xi1> to vector<2x2xi1>395  // CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index396  // CHECK-DAG: %[[C2:.+]] = arith.constant 2 : index397  // CHECK-DAG: %[[A:.+]] = arith.subi %[[DIM0]], %[[C2]]398  // CHECK-DAG: %[[B:.+]] = arith.subi %[[DIM1]], %[[C1]]399  // CHECK: vector.create_mask %[[A]], %[[B]] : vector<2x2xi1>400  return %1 : vector<2x2xi1>401}402 403// -----404 405// CHECK-LABEL: func.func @extract_strided_slice_partial_of_create_mask406// CHECK-SAME: (%[[DIM0:.+]]: index, %[[DIM1:.+]]: index, %[[DIM2:.+]]: index)407func.func @extract_strided_slice_partial_of_create_mask(408  %dim0: index, %dim1: index, %dim2 : index) -> (vector<2x2x8xi1>) {409  %0 = vector.create_mask %dim0, %dim1, %dim2 : vector<4x3x8xi1>410  %1 = vector.extract_strided_slice %0411    {offsets = [2, 1], sizes = [2, 2], strides = [1, 1]}412      : vector<4x3x8xi1> to vector<2x2x8xi1>413  // CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index414  // CHECK-DAG: %[[C2:.+]] = arith.constant 2 : index415  // CHECK-DAG: %[[A:.+]] = arith.subi %[[DIM0]], %[[C2]]416  // CHECK-DAG: %[[B:.+]] = arith.subi %[[DIM1]], %[[C1]]417  // CHECK: vector.create_mask %[[A]], %[[B]], %[[DIM2]] : vector<2x2x8xi1>418  return %1 : vector<2x2x8xi1>419}420 421// -----422 423// CHECK-LABEL: extract_strided_fold424//  CHECK-SAME: (%[[ARG:.*]]: vector<4x3xi1>)425//  CHECK-NEXT:   return %[[ARG]] : vector<4x3xi1>426func.func @extract_strided_fold(%arg : vector<4x3xi1>) -> (vector<4x3xi1>) {427  %0 = vector.extract_strided_slice %arg428    {offsets = [0, 0], sizes = [4, 3], strides = [1, 1]}429      : vector<4x3xi1> to vector<4x3xi1>430  return %0 : vector<4x3xi1>431}432 433// -----434 435// CHECK-LABEL: extract_strided_fold_insert436//  CHECK-SAME: (%[[ARG:.*]]: vector<4x4xf32>437//  CHECK-NEXT:   return %[[ARG]] : vector<4x4xf32>438func.func @extract_strided_fold_insert(%a: vector<4x4xf32>, %b: vector<8x16xf32>)439  -> (vector<4x4xf32>) {440  %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1, 1]}441    : vector<4x4xf32> into vector<8x16xf32>442  %1 = vector.extract_strided_slice %0443    {offsets = [2, 2], sizes = [4, 4], strides = [1, 1]}444      : vector<8x16xf32> to vector<4x4xf32>445  return %1 : vector<4x4xf32>446}447 448// -----449 450// Case where the vector inserted is a subset of the vector extracted.451// CHECK-LABEL: extract_strided_fold_insert452//  CHECK-SAME: (%[[ARG0:.*]]: vector<6x4xf32>453//  CHECK-NEXT:   %[[EXT:.*]] = vector.extract_strided_slice %[[ARG0]]454//  CHECK-SAME:     {offsets = [0, 0], sizes = [4, 4], strides = [1, 1]}455//  CHECK-SAME:       : vector<6x4xf32> to vector<4x4xf32>456//  CHECK-NEXT:   return %[[EXT]] : vector<4x4xf32>457func.func @extract_strided_fold_insert(%a: vector<6x4xf32>, %b: vector<8x16xf32>)458  -> (vector<4x4xf32>) {459  %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1, 1]}460    : vector<6x4xf32> into vector<8x16xf32>461  %1 = vector.extract_strided_slice %0462    {offsets = [2, 2], sizes = [4, 4], strides = [1, 1]}463      : vector<8x16xf32> to vector<4x4xf32>464  return %1 : vector<4x4xf32>465}466 467// -----468 469// Negative test where the extract is not a subset of the element inserted.470// CHECK-LABEL: negative_extract_strided_fold471//  CHECK-SAME: (%[[ARG0:.*]]: vector<4x4xf32>, %[[ARG1:.*]]: vector<8x16xf32>472//       CHECK:   %[[INS:.*]] = vector.insert_strided_slice %[[ARG0]], %[[ARG1]]473//  CHECK-SAME:     {offsets = [2, 2], strides = [1, 1]}474//  CHECK-SAME:       : vector<4x4xf32> into vector<8x16xf32>475//       CHECK:   %[[EXT:.*]] = vector.extract_strided_slice %[[INS]]476//  CHECK-SAME:     {offsets = [2, 2], sizes = [6, 4], strides = [1, 1]}477//  CHECK-SAME:       : vector<8x16xf32> to vector<6x4xf32>478//  CHECK-NEXT:   return %[[EXT]] : vector<6x4xf32>479func.func @negative_extract_strided_fold(%a: vector<4x4xf32>, %b: vector<8x16xf32>)480  -> (vector<6x4xf32>) {481  %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1, 1]}482    : vector<4x4xf32> into vector<8x16xf32>483  %1 = vector.extract_strided_slice %0484    {offsets = [2, 2], sizes = [6, 4], strides = [1, 1]}485      : vector<8x16xf32> to vector<6x4xf32>486  return %1 : vector<6x4xf32>487}488 489// -----490 491// Case where we need to go through 2 level of insert element.492// CHECK-LABEL: extract_strided_fold_insert493//  CHECK-SAME: (%[[ARG0:.*]]: vector<2x8xf32>, %[[ARG1:.*]]: vector<1x4xf32>,494//  CHECK-NEXT:   %[[EXT:.*]] = vector.extract_strided_slice %[[ARG1]]495//  CHECK-SAME:     {offsets = [0, 0], sizes = [1, 1], strides = [1, 1]}496//  CHECK-SAME:       : vector<1x4xf32> to vector<1x1xf32>497//  CHECK-NEXT:   return %[[EXT]] : vector<1x1xf32>498func.func @extract_strided_fold_insert(%a: vector<2x8xf32>, %b: vector<1x4xf32>,499                                  %c : vector<1x4xf32>) -> (vector<1x1xf32>) {500  %0 = vector.insert_strided_slice %b, %a {offsets = [0, 1], strides = [1, 1]}501    : vector<1x4xf32> into vector<2x8xf32>502  %1 = vector.insert_strided_slice %c, %0 {offsets = [1, 0], strides = [1, 1]}503    : vector<1x4xf32> into vector<2x8xf32>504  %2 = vector.extract_strided_slice %1505      {offsets = [0, 1], sizes = [1, 1], strides = [1, 1]}506        : vector<2x8xf32> to vector<1x1xf32>507  return %2 : vector<1x1xf32>508}509 510// -----511 512// CHECK-LABEL: transpose_3D_identity513// CHECK-SAME: ([[ARG:%.*]]: vector<4x3x2xf32>)514func.func @transpose_3D_identity(%arg : vector<4x3x2xf32>) -> vector<4x3x2xf32> {515  // CHECK-NOT: transpose516  %0 = vector.transpose %arg, [0, 1, 2] : vector<4x3x2xf32> to vector<4x3x2xf32>517  // CHECK-NEXT: return [[ARG]]518  return %0 : vector<4x3x2xf32>519}520 521// -----522 523// CHECK-LABEL: transpose_2D_sequence524// CHECK-SAME: ([[ARG:%.*]]: vector<4x3xf32>)525func.func @transpose_2D_sequence(%arg : vector<4x3xf32>) -> vector<4x3xf32> {526  // CHECK-NOT: transpose527  %0 = vector.transpose %arg, [1, 0] : vector<4x3xf32> to vector<3x4xf32>528  %1 = vector.transpose %0, [0, 1] : vector<3x4xf32> to vector<3x4xf32>529  %2 = vector.transpose %1, [1, 0] : vector<3x4xf32> to vector<4x3xf32>530  %3 = vector.transpose %2, [0, 1] : vector<4x3xf32> to vector<4x3xf32>531  // CHECK: [[ADD:%.*]] = arith.addf [[ARG]], [[ARG]]532  %4 = arith.addf %2, %3 : vector<4x3xf32>533  // CHECK-NEXT: return [[ADD]]534  return %4 : vector<4x3xf32>535}536 537// -----538 539// CHECK-LABEL: transpose_3D_sequence540// CHECK-SAME: ([[ARG:%.*]]: vector<4x3x2xf32>)541func.func @transpose_3D_sequence(%arg : vector<4x3x2xf32>) -> vector<4x3x2xf32> {542  // CHECK: [[T0:%.*]] = vector.transpose [[ARG]], [2, 1, 0]543  %0 = vector.transpose %arg, [1, 2, 0] : vector<4x3x2xf32> to vector<3x2x4xf32>544  %1 = vector.transpose %0, [1, 0, 2] : vector<3x2x4xf32> to vector<2x3x4xf32>545  // CHECK: [[T1:%.*]] = vector.transpose %arg0, [2, 1, 0]546  %2 = vector.transpose %1, [2, 1, 0] : vector<2x3x4xf32> to vector<4x3x2xf32>547  %3 = vector.transpose %2, [2, 1, 0] : vector<4x3x2xf32> to vector<2x3x4xf32>548  // CHECK: [[MUL:%.*]] = arith.mulf [[T0]], [[T1]]549  %4 = arith.mulf %1, %3 : vector<2x3x4xf32>550  // CHECK: [[T5:%.*]] = vector.transpose [[MUL]], [2, 1, 0]551  %5 = vector.transpose %4, [2, 1, 0] : vector<2x3x4xf32> to vector<4x3x2xf32>552  // CHECK-NOT: transpose553  %6 = vector.transpose %3, [2, 1, 0] : vector<2x3x4xf32> to vector<4x3x2xf32>554  // CHECK: [[ADD:%.*]] = arith.addf [[T5]], [[ARG]]555  %7 = arith.addf %5, %6 : vector<4x3x2xf32>556  // CHECK-NEXT: return [[ADD]]557  return %7 : vector<4x3x2xf32>558}559 560// -----561 562// CHECK-LABEL: cast_transfers563func.func @cast_transfers(%A: memref<4x8xf32>) -> (vector<4x8xf32>) {564  %c0 = arith.constant 0 : index565  %f0 = arith.constant 0.0 : f32566  %0 = memref.cast %A : memref<4x8xf32> to memref<?x?xf32>567 568  // CHECK: vector.transfer_read %{{.*}} {in_bounds = [true, true]} : memref<4x8xf32>, vector<4x8xf32>569  %1 = vector.transfer_read %0[%c0, %c0], %f0 : memref<?x?xf32>, vector<4x8xf32>570 571  // CHECK: vector.transfer_write %{{.*}} {in_bounds = [true, true]} : vector<4x8xf32>, memref<4x8xf32>572  vector.transfer_write %1, %0[%c0, %c0] : vector<4x8xf32>, memref<?x?xf32>573  return %1 : vector<4x8xf32>574}575 576// -----577 578// CHECK-LABEL: cast_transfers579func.func @cast_transfers(%A: tensor<4x8xf32>) -> (vector<4x8xf32>) {580  %c0 = arith.constant 0 : index581  %f0 = arith.constant 0.0 : f32582  %0 = tensor.cast %A : tensor<4x8xf32> to tensor<?x?xf32>583 584  // CHECK: vector.transfer_read %{{.*}} {in_bounds = [true, true]} : tensor<4x8xf32>, vector<4x8xf32>585  %1 = vector.transfer_read %0[%c0, %c0], %f0 : tensor<?x?xf32>, vector<4x8xf32>586 587  return %1 : vector<4x8xf32>588}589 590// -----591 592// CHECK-LABEL: func @insert_extract_transpose_2d(593//  CHECK-SAME: %[[V:[a-zA-Z0-9]*]]: vector<2x3xf32>,594//  CHECK-SAME: %[[F0:[a-zA-Z0-9]*]]: f32,595//  CHECK-SAME: %[[F1:[a-zA-Z0-9]*]]: f32,596//  CHECK-SAME: %[[F2:[a-zA-Z0-9]*]]: f32,597//  CHECK-SAME: %[[F3:[a-zA-Z0-9]*]]: f32598func.func @insert_extract_transpose_2d(599    %v: vector<2x3xf32>, %f0: f32, %f1: f32, %f2: f32, %f3: f32)600-> (f32, f32, f32)601{602  %0 = vector.insert %f0, %v[0, 0] : f32 into vector<2x3xf32>603  %1 = vector.insert %f1, %0[0, 1] : f32 into vector<2x3xf32>604  %2 = vector.insert %f2, %1[1, 0] : f32 into vector<2x3xf32>605  %3 = vector.insert %f3, %2[1, 1] : f32 into vector<2x3xf32>606  %4 = vector.transpose %3, [1, 0] : vector<2x3xf32> to vector<3x2xf32>607  %5 = vector.insert %f3, %4[1, 0] : f32 into vector<3x2xf32>608  %6 = vector.transpose %5, [1, 0] : vector<3x2xf32> to vector<2x3xf32>609 610  // Expected %f2 from %2 = vector.insert %f2, %1[1, 0].611  %r1 = vector.extract %3[1, 0] : f32 from vector<2x3xf32>612 613  // Expected %f1 from %1 = vector.insert %f1, %0[0, 1] followed by614  // transpose [1, 0].615  %r2 = vector.extract %4[1, 0] : f32 from vector<3x2xf32>616 617  // Expected %f2 from %2 = vector.insert %f2, %1[1, 0] followed by double618  // transpose [1, 0].619  %r3 = vector.extract %6[1, 0] : f32 from vector<2x3xf32>620 621  // CHECK-NEXT: return %[[F2]], %[[F1]], %[[F2]] : f32, f32, f32622  return %r1, %r2, %r3 : f32, f32, f32623}624 625// -----626 627// CHECK-LABEL: insert_extract_chain628//  CHECK-SAME: %[[V334:[a-zA-Z0-9]*]]: vector<3x3x4xf32>629//  CHECK-SAME: %[[V34:[a-zA-Z0-9]*]]: vector<3x4xf32>630//  CHECK-SAME: %[[V4:[a-zA-Z0-9]*]]: vector<4xf32>631func.func @insert_extract_chain(%v334: vector<3x3x4xf32>, %v34: vector<3x4xf32>, %v4: vector<4xf32>)632    -> (vector<4xf32>, vector<4xf32>, vector<3x4xf32>, vector<3x4xf32>) {633  // CHECK-NEXT: %[[A34:.*]] = vector.insert634  %A34 = vector.insert %v34, %v334[0]: vector<3x4xf32> into vector<3x3x4xf32>635  // CHECK-NEXT: %[[B34:.*]] = vector.insert636  %B34 = vector.insert %v34, %A34[1]: vector<3x4xf32> into vector<3x3x4xf32>637  // CHECK-NEXT: %[[A4:.*]] = vector.insert638  %A4 = vector.insert %v4, %B34[1, 0]: vector<4xf32> into vector<3x3x4xf32>639  // CHECK-NEXT: %[[B4:.*]] = vector.insert640  %B4 = vector.insert %v4, %A4[1, 1]: vector<4xf32> into vector<3x3x4xf32>641 642  // Case 2.a. [1, 1] == insertpos ([1, 1])643  // Match %A4 insertionpos and fold to its source(i.e. %V4).644   %r0 = vector.extract %B4[1, 1]: vector<4xf32> from vector<3x3x4xf32>645 646  // Case 3.a. insertpos ([1]) is a prefix of [1, 0].647  // Traverse %B34 to its source(i.e. %V34@[*0*]).648  // CHECK-NEXT: %[[R1:.*]] = vector.extract %[[V34]][0]649   %r1 = vector.extract %B34[1, 0]: vector<4xf32> from vector<3x3x4xf32>650 651  // Case 4. [1] is a prefix of insertpos ([1, 1]).652  // Cannot traverse %B4.653  // CHECK-NEXT: %[[R2:.*]] = vector.extract %[[B4]][1]654   %r2 = vector.extract %B4[1]: vector<3x4xf32> from vector<3x3x4xf32>655 656  // Case 5. [0] is disjoint from insertpos ([1, 1]).657  // Traverse %B4 to its dest(i.e. %A4@[0]).658  // Traverse %A4 to its dest(i.e. %B34@[0]).659  // Traverse %B34 to its dest(i.e. %A34@[0]).660  // Match %A34 insertionpos and fold to its source(i.e. %V34).661   %r3 = vector.extract %B4[0]: vector<3x4xf32> from vector<3x3x4xf32>662 663  // CHECK: return %[[V4]], %[[R1]], %[[R2]], %[[V34]]664  return %r0, %r1, %r2, %r3:665    vector<4xf32>, vector<4xf32>, vector<3x4xf32>, vector<3x4xf32>666}667 668// -----669 670// CHECK-LABEL: func @insert_extract_transpose_3d(671//  CHECK-SAME: %[[V234:[a-zA-Z0-9]*]]: vector<2x3x4xf32>672func.func @insert_extract_transpose_3d(673  %v234: vector<2x3x4xf32>, %v43: vector<4x3xf32>, %f0: f32)674    -> (vector<4xf32>, vector<4xf32>, vector<4xf32>, vector<3x4xf32>) {675 676  %a432 = vector.transpose %v234, [2, 1, 0] : vector<2x3x4xf32> to vector<4x3x2xf32>677  %b432 = vector.insert %f0, %a432[0, 0, 1] : f32 into vector<4x3x2xf32>678  %c234 = vector.transpose %b432, [2, 1, 0] : vector<4x3x2xf32> to vector<2x3x4xf32>679  // Case 1. %c234 = transpose [2,1,0] posWithSentinels [1,2,-1] -> [-1,2,1]680  // Case 5. %b432 = insert [0,0,1] (inter([.,2,1], [.,0,1]) == 0) prop to %v432681  // Case 1. %a432 = transpose [2,1,0] posWithSentinels [-1,2,1] -> [1,2,-1]682  // can extract directly from %v234, the rest folds.683  // CHECK: %[[R0:.*]] = vector.extract %[[V234]][1, 2]684  %r0 = vector.extract %c234[1, 2] : vector<4xf32> from vector<2x3x4xf32>685 686  // CHECK-NEXT: vector.transpose687  // CHECK-NEXT: vector.insert688  // CHECK-NEXT: %[[F234:.*]] = vector.transpose689  %d432 = vector.transpose %v234, [2, 1, 0] : vector<2x3x4xf32> to vector<4x3x2xf32>690  %e432 = vector.insert %f0, %d432[0, 2, 1] : f32 into vector<4x3x2xf32>691  %f234 = vector.transpose %e432, [2, 1, 0] : vector<4x3x2xf32> to vector<2x3x4xf32>692  // Case 1. %c234 = transpose [2,1,0] posWithSentinels [1,2,-1] -> [-1,2,1]693  // Case 4. %b432 = insert [0,0,1] (inter([.,2,1], [.,2,1]) != 0)694  // Bail, cannot do better than the current.695  // CHECK: %[[R1:.*]] = vector.extract %[[F234]]696  %r1 = vector.extract %f234[1, 2] : vector<4xf32> from vector<2x3x4xf32>697 698  // CHECK-NEXT: vector.transpose699  // CHECK-NEXT: vector.insert700  // CHECK-NEXT: %[[H234:.*]] = vector.transpose701  %g243 = vector.transpose %v234, [0, 2, 1] : vector<2x3x4xf32> to vector<2x4x3xf32>702  %h243 = vector.insert %v43, %g243[0] : vector<4x3xf32> into vector<2x4x3xf32>703  %i234 = vector.transpose %h243, [0, 2, 1] : vector<2x4x3xf32> to vector<2x3x4xf32>704  // Case 1. %i234 = transpose [0,2,1] posWithSentinels [0,-1,-2] -> [0,-2,-1]705  // Case 3.b. %b432 = insert [0] is prefix of [0,.,.] but internal transpose.706  // Bail, cannot do better than the current.707  // CHECK: %[[R2:.*]] = vector.extract %[[H234]][0, 1]708  %r2 = vector.extract %i234[0, 1] : vector<4xf32> from vector<2x3x4xf32>709 710  // CHECK-NEXT: vector.transpose711  // CHECK-NEXT: vector.insert712  // CHECK-NEXT: %[[K234:.*]] = vector.transpose713  %j243 = vector.transpose %v234, [0, 2, 1] : vector<2x3x4xf32> to vector<2x4x3xf32>714  %k243 = vector.insert %v43, %j243[0] : vector<4x3xf32> into vector<2x4x3xf32>715  %l234 = vector.transpose %k243, [0, 2, 1] : vector<2x4x3xf32> to vector<2x3x4xf32>716  // Case 1. %i234 = transpose [0,2,1] posWithSentinels [0,-1,-2] -> [0,-2,-1]717  // Case 2.b. %b432 = insert [0] == [0,.,.] but internal transpose.718  // Bail, cannot do better than the current.719  // CHECK: %[[R3:.*]] = vector.extract %[[K234]][0]720  %r3 = vector.extract %l234[0] : vector<3x4xf32> from vector<2x3x4xf32>721 722  // CHECK-NEXT: return %[[R0]], %[[R1]], %[[R2]], %[[R3]]723  return %r0, %r1, %r2, %r3: vector<4xf32>, vector<4xf32>, vector<4xf32>, vector<3x4xf32>724}725 726// -----727 728// CHECK-LABEL: fold_extracts729//  CHECK-SAME:   %[[A:[a-zA-Z0-9]*]]: vector<3x4x5x6xf32>730func.func @fold_extracts(%a : vector<3x4x5x6xf32>) -> (f32, vector<4x5x6xf32>) {731  %b = vector.extract %a[0] : vector<4x5x6xf32> from vector<3x4x5x6xf32>732  %c = vector.extract %b[1, 2] : vector<6xf32> from vector<4x5x6xf32>733  //  CHECK-NEXT: vector.extract %[[A]][0, 1, 2, 3] : f32 from vector<3x4x5x6xf32>734  %d = vector.extract %c[3] : f32 from vector<6xf32>735 736  //  CHECK-NEXT: vector.extract %[[A]][0] : vector<4x5x6xf32> from vector<3x4x5x6xf32>737  %e = vector.extract %a[0] : vector<4x5x6xf32> from vector<3x4x5x6xf32>738 739  //  CHECK-NEXT: return740  return %d, %e : f32, vector<4x5x6xf32>741}742 743// -----744 745// CHECK-LABEL: fold_extract_transpose746//  CHECK-SAME:   %[[A:[a-zA-Z0-9]*]]: vector<3x4x5x6xf32>747//  CHECK-SAME:   %[[B:[a-zA-Z0-9]*]]: vector<3x6x5x6xf32>748func.func @fold_extract_transpose(749    %a : vector<3x4x5x6xf32>, %b : vector<3x6x5x6xf32>) -> (750      vector<6xf32>, vector<6xf32>, vector<6xf32>) {751  // [3] is a proper most minor identity map in transpose.752  // Permutation is a self inverse and we have.753  // [0, 2, 1] ^ -1 o [0, 1, 2] = [0, 2, 1] o [0, 1, 2]754  //                            = [0, 2, 1]755  //  CHECK-NEXT: vector.extract %[[A]][0, 2, 1] : vector<6xf32> from vector<3x4x5x6xf32>756  %0 = vector.transpose %a, [0, 2, 1, 3] : vector<3x4x5x6xf32> to vector<3x5x4x6xf32>757  %1 = vector.extract %0[0, 1, 2] : vector<6xf32> from vector<3x5x4x6xf32>758 759  // [3] is a proper most minor identity map in transpose.760  // Permutation is a not self inverse and we have.761  // [1, 2, 0] ^ -1 o [0, 1, 2] = [2, 0, 1] o [0, 1, 2]762  //                            = [2, 0, 1]763  //  CHECK-NEXT: vector.extract %[[A]][2, 0, 1] : vector<6xf32> from vector<3x4x5x6xf32>764  %2 = vector.transpose %a, [1, 2, 0, 3] : vector<3x4x5x6xf32> to vector<4x5x3x6xf32>765  %3 = vector.extract %2[0, 1, 2] : vector<6xf32> from vector<4x5x3x6xf32>766 767  // Not a minor identity map so intra-vector level has been permuted768  //  CHECK-NEXT: vector.transpose %[[B]], [0, 2, 3, 1]769  //  CHECK-NEXT: vector.extract %{{.*}}[0, 1, 2]770  %4 = vector.transpose %b, [0, 2, 3, 1] : vector<3x6x5x6xf32> to vector<3x5x6x6xf32>771  %5 = vector.extract %4[0, 1, 2] : vector<6xf32> from vector<3x5x6x6xf32>772 773  return %1, %3, %5 : vector<6xf32>, vector<6xf32>, vector<6xf32>774}775 776// -----777 778// CHECK-LABEL: fold_extract_broadcast_same_input_output_scalar779//  CHECK-SAME:   %[[A:.*]]: f32780//       CHECK:   return %[[A]] : f32781func.func @fold_extract_broadcast_same_input_output_scalar(%a : f32,782  %idx0 : index, %idx1 : index, %idx2 : index) -> f32 {783  %b = vector.broadcast %a : f32 to vector<1x2x4xf32>784  %r = vector.extract %b[%idx0, %idx1, %idx2] : f32 from vector<1x2x4xf32>785  return %r : f32786}787 788// -----789 790// CHECK-LABEL: fold_extract_broadcast_same_input_output_vec791//  CHECK-SAME:   %[[A:.*]]: vector<4xf32>792//       CHECK:   return %[[A]] : vector<4xf32>793func.func @fold_extract_broadcast_same_input_output_vec(%a : vector<4xf32>,794  %idx0 : index, %idx1 : index) -> vector<4xf32> {795  %b = vector.broadcast %a : vector<4xf32> to vector<1x2x4xf32>796  %r = vector.extract %b[%idx0, %idx1] : vector<4xf32> from vector<1x2x4xf32>797  return %r : vector<4xf32>798}799 800// -----801 802// CHECK-LABEL: fold_extract_broadcast_0dvec_input_scalar_output803//  CHECK-SAME:   %[[A:.*]]: vector<f32>804//       CHECK:   %[[B:.+]] = vector.extract %[[A]][] : f32 from vector<f32>805//       CHECK:   return %[[B]] : f32806func.func @fold_extract_broadcast_0dvec_input_scalar_output(%a : vector<f32>,807  %idx0 : index, %idx1 : index, %idx2: index) -> f32 {808  %b = vector.broadcast %a : vector<f32> to vector<1x2x4xf32>809  %r = vector.extract %b[%idx0, %idx1, %idx2] : f32 from vector<1x2x4xf32>810  return %r : f32811}812 813// -----814 815// CHECK-LABEL: negative_fold_extract_broadcast816//       CHECK:   vector.broadcast %{{.*}} : vector<1x1xf32> to vector<1x1x4xf32>817//       CHECK:   vector.extract %{{.*}}[0, 0] : vector<4xf32> from vector<1x1x4xf32>818func.func @negative_fold_extract_broadcast(%a : vector<1x1xf32>) -> vector<4xf32> {819  %b = vector.broadcast %a : vector<1x1xf32> to vector<1x1x4xf32>820  %r = vector.extract %b[0, 0] : vector<4xf32> from vector<1x1x4xf32>821  return %r : vector<4xf32>822}823 824// -----825 826// CHECK-LABEL: fold_extract_splatlike827//  CHECK-SAME:   %[[A:.*]]: f32828//       CHECK:   return %[[A]] : f32829func.func @fold_extract_splatlike(%a : f32, %idx0 : index, %idx1 : index, %idx2 : index) -> f32 {830  %b = vector.broadcast %a : f32 to vector<1x2x4xf32>831  %r = vector.extract %b[%idx0, %idx1, %idx2] : f32 from vector<1x2x4xf32>832  return %r : f32833}834 835// -----836 837// CHECK-LABEL: fold_extract_vector_from_splat838//       CHECK: vector.broadcast {{.*}} f32 to vector<4xf32>839func.func @fold_extract_vector_from_splat(%a : f32, %idx0 : index, %idx1 : index) -> vector<4xf32> {840  %b = vector.broadcast %a : f32 to vector<1x2x4xf32>841  %r = vector.extract %b[%idx0, %idx1] : vector<4xf32> from vector<1x2x4xf32>842  return %r : vector<4xf32>843}844 845// -----846 847// CHECK-LABEL: fold_extract_broadcast_dim1_broadcasting848//  CHECK-SAME:   %[[A:.*]]: vector<2x1xf32>849//  CHECK-SAME:   %[[IDX:.*]]: index, %[[IDX1:.*]]: index, %[[IDX2:.*]]: index850//       CHECK:   %[[R:.*]] = vector.extract %[[A]][%[[IDX1]], 0] : f32 from vector<2x1xf32>851//       CHECK:   return %[[R]] : f32852func.func @fold_extract_broadcast_dim1_broadcasting(%a : vector<2x1xf32>,853  %idx : index, %idx1 : index, %idx2 : index) -> f32 {854  %b = vector.broadcast %a : vector<2x1xf32> to vector<1x2x4xf32>855  %r = vector.extract %b[%idx, %idx1, %idx2] : f32 from vector<1x2x4xf32>856  return %r : f32857}858 859// -----860 861// CHECK-LABEL: fold_extract_broadcast_to_lower_rank862//  CHECK-SAME:   %[[A:.*]]: vector<2x4xf32>863//  CHECK-SAME:   %[[IDX0:.*]]: index, %[[IDX1:.*]]: index864//       CHECK:   %[[B:.+]] = vector.extract %[[A]][%[[IDX1]]] : vector<4xf32> from vector<2x4xf32>865//       CHECK:   return %[[B]] : vector<4xf32>866// rank(extract_output) < rank(broadcast_input)867func.func @fold_extract_broadcast_to_lower_rank(%a : vector<2x4xf32>,868  %idx0 : index, %idx1 : index) -> vector<4xf32> {869  %b = vector.broadcast %a : vector<2x4xf32> to vector<1x2x4xf32>870  %r = vector.extract %b[%idx0, %idx1] : vector<4xf32> from vector<1x2x4xf32>871  return %r : vector<4xf32>872}873 874// -----875 876// Test where the shape_cast is broadcast-like.877// CHECK-LABEL: fold_extract_shape_cast_to_lower_rank878//  CHECK-SAME:   %[[A:.*]]: vector<2x4xf32>879//  CHECK-SAME:   %[[IDX0:.*]]: index, %[[IDX1:.*]]: index880//       CHECK:   %[[B:.+]] = vector.extract %[[A]][%[[IDX1]]] : vector<4xf32> from vector<2x4xf32>881//       CHECK:   return %[[B]] : vector<4xf32>882func.func @fold_extract_shape_cast_to_lower_rank(%a : vector<2x4xf32>,883  %idx0 : index, %idx1 : index) -> vector<4xf32> {884  %b = vector.shape_cast %a : vector<2x4xf32> to vector<1x2x4xf32>885  %r = vector.extract %b[%idx0, %idx1] : vector<4xf32> from vector<1x2x4xf32>886  return %r : vector<4xf32>887}888 889// -----890 891// Test where the shape_cast is not broadcast-like, even though it prepends 1s.892// CHECK-LABEL: negative_fold_extract_shape_cast_to_lower_rank893//  CHECK-NEXT: vector.shape_cast894//  CHECK-NEXT: vector.extract895//  CHECK-NEXT: return896func.func @negative_fold_extract_shape_cast_to_lower_rank(%a : vector<2x4xf32>,897  %idx0 : index, %idx1 : index) -> vector<2xf32> {898  %b = vector.shape_cast %a : vector<2x4xf32> to vector<1x4x2xf32>899  %r = vector.extract %b[%idx0, %idx1] : vector<2xf32> from vector<1x4x2xf32>900  return %r : vector<2xf32>901}902 903// -----904 905// CHECK-LABEL: fold_extract_broadcast_to_higher_rank906//       CHECK:   %[[B:.*]] = vector.broadcast %{{.*}} : f32 to vector<4xf32>907//       CHECK:   return %[[B]] : vector<4xf32>908// rank(extract_output) > rank(broadcast_input)909func.func @fold_extract_broadcast_to_higher_rank(%a : f32, %idx0 : index, %idx1 : index)910  -> vector<4xf32> {911  %b = vector.broadcast %a : f32 to vector<1x2x4xf32>912  %r = vector.extract %b[%idx0, %idx1] : vector<4xf32> from vector<1x2x4xf32>913  return %r : vector<4xf32>914}915 916// -----917 918// CHECK-LABEL: fold_extract_broadcast_to_equal_rank919//  CHECK-SAME:   %[[A:.*]]: vector<1xf32>920//       CHECK:   %[[R:.*]] = vector.broadcast %[[A]] : vector<1xf32> to vector<8xf32>921//       CHECK:   return %[[R]] : vector<8xf32>922// rank(extract_output) == rank(broadcast_input)923func.func @fold_extract_broadcast_to_equal_rank(%a : vector<1xf32>, %idx0 : index)924  -> vector<8xf32> {925  %b = vector.broadcast %a : vector<1xf32> to vector<1x8xf32>926  %r = vector.extract %b[%idx0] : vector<8xf32> from vector<1x8xf32>927  return %r : vector<8xf32>928}929 930// -----931 932// CHECK-LABEL: fold_extract_broadcastlike_shape_cast933//  CHECK-SAME:   %[[A:.*]]: vector<1xf32>934//       CHECK:   %[[R:.*]] = vector.broadcast %[[A]] : vector<1xf32> to vector<1x1xf32>935//       CHECK:   return %[[R]] : vector<1x1xf32>936func.func @fold_extract_broadcastlike_shape_cast(%a : vector<1xf32>, %idx0 : index)937  -> vector<1x1xf32> {938  %s = vector.shape_cast %a : vector<1xf32> to vector<1x1x1xf32>939  %r = vector.extract %s[%idx0] : vector<1x1xf32> from vector<1x1x1xf32>940  return %r : vector<1x1xf32>941}942 943// -----944 945// CHECK-LABEL: @fold_extract_shuffle946//  CHECK-SAME:   %[[A:.*]]: vector<8xf32>, %[[B:.*]]: vector<8xf32>947//   CHECK-NOT:   vector.shuffle948//       CHECK:   vector.extract %[[A]][0] : f32 from vector<8xf32>949//       CHECK:   vector.extract %[[B]][0] : f32 from vector<8xf32>950//       CHECK:   vector.extract %[[A]][7] : f32 from vector<8xf32>951//       CHECK:   vector.extract %[[B]][7] : f32 from vector<8xf32>952func.func @fold_extract_shuffle(%a : vector<8xf32>, %b : vector<8xf32>)953                                -> (f32, f32, f32, f32) {954  %shuffle = vector.shuffle %a, %b [0, 8, 7, 15] : vector<8xf32>, vector<8xf32>955  %e0 = vector.extract %shuffle[0] : f32 from vector<4xf32>956  %e1 = vector.extract %shuffle[1] : f32 from vector<4xf32>957  %e2 = vector.extract %shuffle[2] : f32 from vector<4xf32>958  %e3 = vector.extract %shuffle[3] : f32 from vector<4xf32>959  return %e0, %e1, %e2, %e3 : f32, f32, f32, f32960}961 962// -----963 964// CHECK-LABEL: func @fold_extract_shapecast965//  CHECK-SAME: (%[[A0:.*]]: vector<5x1x3x2xf32>, %[[A1:.*]]: vector<8x4x2xf32>966//       CHECK:   %[[R0:.*]] = vector.extract %[[A0]][1, 0, 1, 1] : f32 from vector<5x1x3x2xf32>967//       CHECK:   %[[R1:.*]] = vector.extract %[[A0]][1, 0, 2] : vector<2xf32> from vector<5x1x3x2xf32>968//       CHECK:   %[[R2:.*]] = vector.extract %[[A1]][7] : vector<4x2xf32> from vector<8x4x2xf32>969//       CHECK:   return %[[R0]], %[[R1]], %[[R2]], %[[A1]] : f32, vector<2xf32>, vector<4x2xf32>, vector<8x4x2xf32>970func.func @fold_extract_shapecast(%arg0 : vector<5x1x3x2xf32>,971                             %arg1 : vector<8x4x2xf32>)972  -> (f32, vector<2xf32>, vector<4x2xf32>, vector<8x4x2xf32>) {973  %0 = vector.shape_cast %arg0 : vector<5x1x3x2xf32> to vector<15x2xf32>974  %1 = vector.shape_cast %arg1 : vector<8x4x2xf32> to vector<4x2x4x2xf32>975  %2 = vector.shape_cast %arg1 : vector<8x4x2xf32> to vector<1x8x4x2xf32>976  %r1 = vector.extract %0[4, 1] : f32 from vector<15x2xf32>977  %r2 = vector.extract %0[5] : vector<2xf32> from vector<15x2xf32>978  %r3 = vector.extract %1[3, 1] : vector<4x2xf32> from vector<4x2x4x2xf32>979  %r4 = vector.extract %2[0] : vector<8x4x2xf32> from vector<1x8x4x2xf32>980  return %r1, %r2, %r3, %r4 : f32, vector<2xf32>, vector<4x2xf32>, vector<8x4x2xf32>981}982 983// -----984 985// CHECK-LABEL: fold_extract_shapecast_0d_result986//  CHECK-SAME: %[[IN:.*]]: vector<1x1x1xf32>987//       CHECK:   %[[R:.*]] = vector.extract %[[IN]][0, 0, 0] : f32 from vector<1x1x1xf32>988//       CHECK:   return %[[R]] : f32989func.func @fold_extract_shapecast_0d_result(%arg0 : vector<1x1x1xf32>) -> f32 {990  %0 = vector.shape_cast %arg0 : vector<1x1x1xf32> to vector<f32>991  %r = vector.extract %0[] : f32 from vector<f32>992  return %r : f32993}994 995// -----996 997// CHECK-LABEL: fold_extract_shapecast_0d_source998//  CHECK-SAME: %[[IN:.*]]: vector<f32>999//       CHECK:   %[[R:.*]] = vector.extract %[[IN]][] : f32 from vector<f32>1000//       CHECK:   return %[[R]] : f321001func.func @fold_extract_shapecast_0d_source(%arg0 : vector<f32>) -> f32 {1002  %0 = vector.shape_cast %arg0 : vector<f32> to vector<1xf32>1003  %r = vector.extract %0[0] : f32 from vector<1xf32>1004  return %r : f321005}1006 1007// -----1008 1009// CHECK-LABEL: negative_fold_extract_shapecast1010//       CHECK:   %[[V:.*]] = vector.shape_cast %{{.*}} : vector<16xf32> to vector<2x4x2xf32>1011//       CHECK:   %[[R:.*]] = vector.extract %[[V]][1] : vector<4x2xf32> from vector<2x4x2xf32>1012//       CHECK:   return %[[R]] : vector<4x2xf32>1013func.func @negative_fold_extract_shapecast(%arg0 : vector<16xf32>) -> vector<4x2xf32> {1014  %0 = vector.shape_cast %arg0 : vector<16xf32> to vector<2x4x2xf32>1015  %r = vector.extract %0[1] : vector<4x2xf32> from vector<2x4x2xf32>1016  return %r : vector<4x2xf32>1017}1018 1019// -----1020 1021// CHECK-LABEL: fold_extract_shapecast_to_shapecast1022//  CHECK-SAME: (%[[ARG:.+]]: vector<3x4xf32>)1023//       CHECK:   %[[R:.+]] = vector.shape_cast %[[ARG]] : vector<3x4xf32> to vector<12xf32>1024//       CHECK:   return %[[R]]1025func.func @fold_extract_shapecast_to_shapecast(%arg0 : vector<3x4xf32>) -> vector<12xf32> {1026  %0 = vector.shape_cast %arg0 : vector<3x4xf32> to vector<1x12xf32>1027  %r = vector.extract %0[0] : vector<12xf32> from vector<1x12xf32>1028  return %r : vector<12xf32>1029}1030 1031// -----1032 1033// CHECK-LABEL: func @extract_no_fold_scalar_to_0d(1034//  CHECK-SAME:     %[[v:.*]]: vector<f32>)1035//       CHECK:   %[[extract:.*]] = vector.extract %[[v]][] : f32 from vector<f32>1036//       CHECK:   return %[[extract]]1037func.func @extract_no_fold_scalar_to_0d(%v: vector<f32>) -> f32 {1038  %0 = vector.extract %v[] : f32 from vector<f32>1039  return %0 : f321040}1041 1042// -----1043 1044// CHECK-LABEL: func @insert_fold_same_rank(1045//  CHECK-SAME:     %[[v:.*]]: vector<2x2xf32>)1046//       CHECK:      %[[CST:.+]] = arith.constant1047//  CHECK-SAME:                    : vector<2x2xf32>1048//       CHECK-NOT:  vector.insert1049//       CHECK:   return %[[CST]]1050func.func @insert_fold_same_rank(%v: vector<2x2xf32>) -> vector<2x2xf32> {1051  %cst = arith.constant dense<0.000000e+00> : vector<2x2xf32>1052  %0 = vector.insert %cst, %v [] : vector<2x2xf32> into vector<2x2xf32>1053  return %0 : vector<2x2xf32>1054}1055 1056// -----1057 1058// CHECK-LABEL: func @insert_no_fold_scalar_to_0d(1059//  CHECK-SAME:     %[[v:.*]]: vector<f32>)1060//       CHECK:   %[[cst:.*]] = arith.constant dense<0.000000e+00> : vector<f32>1061//       CHECK:   return %[[cst]]1062func.func @insert_no_fold_scalar_to_0d(%v: vector<f32>) -> vector<f32> {1063  %cst = arith.constant 0.000000e+00 : f321064  %0 = vector.insert %cst, %v [] : f32 into vector<f32>1065  return %0 : vector<f32>1066}1067 1068// -----1069 1070// CHECK-LABEL: fold_expand_collapse1071//       CHECK:   %[[A:.*]] = vector.shape_cast %{{.*}} : vector<1x1x64xf32> to vector<8x8xf32>1072//       CHECK:   return %[[A]] : vector<8x8xf32>1073func.func @dont_fold_expand_collapse(%arg0: vector<1x1x64xf32>) -> vector<8x8xf32> {1074    %0 = vector.shape_cast %arg0 : vector<1x1x64xf32> to vector<1x1x8x8xf32>1075    %1 = vector.shape_cast %0 : vector<1x1x8x8xf32> to vector<8x8xf32>1076    return %1 : vector<8x8xf32>1077}1078 1079// -----1080 1081// CHECK-LABEL: func @fold_broadcast_shapecast1082//  CHECK-SAME: (%[[V:.+]]: vector<4xf32>)1083//       CHECK:   return %[[V]]1084func.func @fold_broadcast_shapecast(%arg0: vector<4xf32>) -> vector<4xf32> {1085    %0 = vector.broadcast %arg0 : vector<4xf32> to vector<1x1x4xf32>1086    %1 = vector.shape_cast %0 : vector<1x1x4xf32> to vector<4xf32>1087    return %1 : vector<4xf32>1088}1089 1090// -----1091 1092// CHECK-LABEL: func @canonicalize_broadcast_shapecast_scalar1093//       CHECK:   vector.broadcast1094//   CHECK-NOT:   vector.shape_cast1095func.func @canonicalize_broadcast_shapecast_scalar(%arg0: f32) -> vector<1xf32> {1096    %0 = vector.broadcast %arg0 : f32 to vector<1x1x1xf32>1097    %1 = vector.shape_cast %0 : vector<1x1x1xf32> to vector<1xf32>1098    return %1 : vector<1xf32>1099}1100 1101// -----1102 1103// CHECK-LABEL: func @dont_fold_broadcast_shapecast_diff_shape1104//       CHECK:   vector.broadcast1105//       CHECK:   vector.shape_cast1106func.func @dont_fold_broadcast_shapecast_diff_shape(%arg0: vector<4xf32>) -> vector<8xf32> {1107    %0 = vector.broadcast %arg0 : vector<4xf32> to vector<1x2x4xf32>1108    %1 = vector.shape_cast %0 : vector<1x2x4xf32> to vector<8xf32>1109    return %1 : vector<8xf32>1110}1111 1112// -----1113 1114// CHECK-LABEL: func @canonicalize_broadcast_shapecast_to_broadcast1115//       CHECK:   vector.broadcast1116//   CHECK-NOT:   vector.shape_cast1117func.func @canonicalize_broadcast_shapecast_to_broadcast(%arg0: vector<3xf32>) -> vector<8x3xf32> {1118    %0 = vector.broadcast %arg0 : vector<3xf32> to vector<2x4x3xf32>1119    %1 = vector.shape_cast %0 : vector<2x4x3xf32> to vector<8x3xf32>1120    return %1 : vector<8x3xf32>1121}1122 1123// -----1124 1125// CHECK-LABEL: func @canonicalize_broadcast_shapecast_to_broadcast_ones1126//       CHECK:   vector.broadcast {{.*}} vector<1x1xi8> to vector<1x1x6x1x4xi8>1127//   CHECK-NOT:   vector.shape_cast1128func.func @canonicalize_broadcast_shapecast_to_broadcast_ones(%arg0: vector<1x1xi8>) -> vector<1x1x6x1x4xi8> {1129  %0 = vector.broadcast %arg0 : vector<1x1xi8> to vector<6x4xi8>1130  %1 = vector.shape_cast %0 : vector<6x4xi8> to vector<1x1x6x1x4xi8>1131  return %1 : vector<1x1x6x1x4xi8>1132}1133 1134// -----1135 1136// CHECK-LABEL: func @canonicalize_broadcast_shapecast_to_broadcast_scalar1137//       CHECK:   vector.broadcast {{.*}} f32 to vector<3x4x1xf32>1138//   CHECK-NOT:   vector.shape_cast1139func.func @canonicalize_broadcast_shapecast_to_broadcast_scalar(%arg0: f32) -> vector<3x4x1xf32> {1140  %0 = vector.broadcast %arg0 : f32 to vector<12xf32>1141  %1 = vector.shape_cast %0 : vector<12xf32> to vector<3x4x1xf32>1142  return %1 : vector<3x4x1xf32>1143}1144 1145// -----1146 1147// In this test, broadcast (2)->(1,2,1) is not legal, but shape_cast (2)->(1,2,1) is.1148// CHECK-LABEL: func @canonicalize_broadcast_shapecast_to_shapcast1149//   CHECK-NOT:   vector.broadcast1150//       CHECK:   vector.shape_cast {{.+}} : vector<2xf32> to vector<1x2x1xf32>1151func.func @canonicalize_broadcast_shapecast_to_shapcast(%arg0 : vector<2xf32>) -> vector<1x2x1xf32> {1152  %0 = vector.broadcast %arg0 : vector<2xf32> to vector<1x2xf32>1153  %1 = vector.shape_cast %0 : vector<1x2xf32> to vector<1x2x1xf32>1154  return %1 : vector<1x2x1xf32>1155}1156 1157// -----1158 1159// In this test, broadcast (1)->(1,1) and shape_cast (1)->(1,1) are both legal. shape_cast is chosen.1160// CHECK-LABEL: func @canonicalize_broadcast_shapecast_both_possible1161//   CHECK-NOT:   vector.broadcast1162//       CHECK:   vector.shape_cast {{.+}} : vector<1xf32> to vector<1x1xf32>1163func.func @canonicalize_broadcast_shapecast_both_possible(%arg0: vector<1xf32>) -> vector<1x1xf32> {1164    %0 = vector.broadcast %arg0 : vector<1xf32> to vector<1x1x1xf32>1165    %1 = vector.shape_cast %0 : vector<1x1x1xf32> to vector<1x1xf32>1166    return %1 : vector<1x1xf32>1167}1168 1169// -----1170 1171// CHECK-LABEL: func @canonicalize_shapecast_broadcast_to_broadcast_prepend_dim1172//   CHECK-NOT:   vector.shape_cast1173//       CHECK:   vector.broadcast {{.+}} : vector<2xf32> to vector<32x2xf32>1174func.func @canonicalize_shapecast_broadcast_to_broadcast_prepend_dim(%arg0 : vector<2xf32>) -> vector<32x2xf32> {1175  %0 = vector.shape_cast %arg0 : vector<2xf32> to vector<1x2xf32>1176  %1 = vector.broadcast %0 : vector<1x2xf32> to vector<32x2xf32>1177  return %1 : vector<32x2xf32>1178}1179 1180// -----1181 1182// CHECK-LABEL:   func.func @canonicalize_shapecast_broadcast_to_broadcast_prepend_dim2(1183// CHECK-SAME:      %[[ARG0:.*]]: vector<2x1xf32>) -> vector<32x2x1xf32> {1184// CHECK:           %[[VAL_0:.*]] = vector.broadcast %[[ARG0]] : vector<2x1xf32> to vector<32x2x1xf32>1185// CHECK:           return %[[VAL_0]] : vector<32x2x1xf32>1186// CHECK:         }1187func.func @canonicalize_shapecast_broadcast_to_broadcast_prepend_dim2(%arg0 : vector<2x1xf32>) -> vector<32x2x1xf32> {1188  %0 = vector.shape_cast %arg0 : vector<2x1xf32> to vector<1x2x1xf32>1189  %1 = vector.broadcast %0 : vector<1x2x1xf32> to vector<32x2x1xf32>1190  return %1 : vector<32x2x1xf32>1191}1192 1193// -----1194 1195// CHECK-LABEL:   func.func @canonicalize_shapecast_broadcast_to_broadcast_prepend_dim3(1196// CHECK-SAME:      %[[ARG0:.*]]: vector<2x1xf32>) -> vector<32x2x4xf32> {1197// CHECK:           %[[VAL_0:.*]] = vector.broadcast %[[ARG0]] : vector<2x1xf32> to vector<32x2x4xf32>1198// CHECK:           return %[[VAL_0]] : vector<32x2x4xf32>1199// CHECK:         }1200func.func @canonicalize_shapecast_broadcast_to_broadcast_prepend_dim3(%arg0 : vector<2x1xf32>) -> vector<32x2x4xf32> {1201  %0 = vector.shape_cast %arg0 : vector<2x1xf32> to vector<1x2x1xf32>1202  %1 = vector.broadcast %0 : vector<1x2x1xf32> to vector<32x2x4xf32>1203  return %1 : vector<32x2x4xf32>1204}1205 1206// -----1207 1208// CHECK-LABEL:   func.func @canonicalize_shapecast_broadcast_to_broadcast_remove_leading_dim(1209// CHECK-SAME:      %[[ARG0:.*]]: vector<1x2xf32>) -> vector<32x2xf32> {1210// CHECK:           %[[VAL_0:.*]] = vector.broadcast %[[ARG0]] : vector<1x2xf32> to vector<32x2xf32>1211// CHECK:           return %[[VAL_0]] : vector<32x2xf32>1212// CHECK:         }1213func.func @canonicalize_shapecast_broadcast_to_broadcast_remove_leading_dim(%arg0 : vector<1x2xf32>) -> vector<32x2xf32> {1214  %0 = vector.shape_cast %arg0 : vector<1x2xf32> to vector<2xf32>1215  %1 = vector.broadcast %0 : vector<2xf32> to vector<32x2xf32>1216  return %1 : vector<32x2xf32>1217}1218 1219// -----1220 1221// CHECK-LABEL: func @negative_canonicalize_shapecast_broadcast_invalid_shape1222//       CHECK:   vector.shape_cast {{.+}} : vector<64xf32> to vector<4x16xf32>1223//       CHECK:   vector.broadcast {{.+}} : vector<4x16xf32> to vector<2x4x16xf32>1224func.func @negative_canonicalize_shapecast_broadcast_invalid_shape(%arg0 : vector<64xf32>) -> vector<2x4x16xf32> {1225  %0 = vector.shape_cast %arg0 : vector<64xf32> to vector<4x16xf32>1226  %1 = vector.broadcast %0 : vector<4x16xf32> to vector<2x4x16xf32>1227  return %1 : vector<2x4x16xf32>1228}1229 1230// -----1231 1232// CHECK-LABEL: func @negative_canonicalize_shapecast_broadcast_invalid_broadcasted_dims1233//       CHECK:   vector.shape_cast {{.+}} : vector<2x1xf32> to vector<1x2xf32>1234//       CHECK:   vector.broadcast {{.+}} : vector<1x2xf32> to vector<2x2xf32>1235func.func @negative_canonicalize_shapecast_broadcast_invalid_broadcasted_dims(%arg0 : vector<2x1xf32>) -> vector<2x2xf32> {1236  %0 = vector.shape_cast %arg0 : vector<2x1xf32> to vector<1x2xf32>1237  %1 = vector.broadcast %0 : vector<1x2xf32> to vector<2x2xf32>1238  return %1 : vector<2x2xf32>1239}1240 1241// -----1242 1243// CHECK-LABEL:   func.func @negative_canonicalize_shapecast_broadcast_to_broadcast_append_dim(1244// CHECK-SAME:      %[[ARG0:.*]]: vector<2xf32>) -> vector<2x4xf32> {1245// CHECK:           %[[VAL_0:.*]] = vector.shape_cast %[[ARG0]] : vector<2xf32> to vector<2x1xf32>1246// CHECK:           %[[VAL_1:.*]] = vector.broadcast %[[VAL_0]] : vector<2x1xf32> to vector<2x4xf32>1247// CHECK:           return %[[VAL_1]] : vector<2x4xf32>1248// CHECK:         }1249func.func @negative_canonicalize_shapecast_broadcast_to_broadcast_append_dim(%arg0 : vector<2xf32>) -> vector<2x4xf32> {1250  %0 = vector.shape_cast %arg0 : vector<2xf32> to vector<2x1xf32>1251  %1 = vector.broadcast %0 : vector<2x1xf32> to vector<2x4xf32>1252  return %1 : vector<2x4xf32>1253}1254 1255// -----1256 1257// CHECK-LABEL:   func.func @negative_canonicalize_shapecast_broadcast_to_broadcast_remove_trailing_dim(1258// CHECK-SAME:      %[[ARG0:.*]]: vector<2x1xf32>) -> vector<32x2xf32> {1259// CHECK:           %[[VAL_0:.*]] = vector.shape_cast %[[ARG0]] : vector<2x1xf32> to vector<2xf32>1260// CHECK:           %[[VAL_1:.*]] = vector.broadcast %[[VAL_0]] : vector<2xf32> to vector<32x2xf32>1261// CHECK:           return %[[VAL_1]] : vector<32x2xf32>1262// CHECK:         }1263func.func @negative_canonicalize_shapecast_broadcast_to_broadcast_remove_trailing_dim(%arg0 : vector<2x1xf32>) -> vector<32x2xf32> {1264  %0 = vector.shape_cast %arg0 : vector<2x1xf32> to vector<2xf32>1265  %1 = vector.broadcast %0 : vector<2xf32> to vector<32x2xf32>1266  return %1 : vector<32x2xf32>1267}1268 1269// -----1270 1271// CHECK-LABEL: fold_vector_transfer_masks1272func.func @fold_vector_transfer_masks(%A: memref<?x?xf32>) -> (vector<4x8xf32>, vector<4x[4]xf32>) {1273  // CHECK: %[[C0:.+]] = arith.constant 0 : index1274  %c0 = arith.constant 0 : index1275  // CHECK: %[[F0:.+]] = arith.constant 0.000000e+00 : f321276  %f0 = arith.constant 0.0 : f321277 1278  %mask = vector.constant_mask [8, 4] : vector<8x4xi1>1279 1280  %arith_all_true_mask = arith.constant dense<true> : vector<4x[4]xi1>1281 1282  // CHECK: vector.transfer_read %{{.*}}, %[[F0]] {permutation_map1283  %1 = vector.transfer_read %A[%c0, %c0], %f0, %mask1284      {permutation_map = affine_map<(d0, d1) -> (d1, d0)>} : memref<?x?xf32>, vector<4x8xf32>1285 1286  // CHECK: vector.transfer_write {{.*}}[%[[C0]], %[[C0]]] {permutation_map1287  vector.transfer_write %1, %A[%c0, %c0], %mask1288      {permutation_map = affine_map<(d0, d1) -> (d1, d0)>} : vector<4x8xf32>, memref<?x?xf32>1289 1290  // CHECK: vector.transfer_read %{{.*}}, %[[F0]] :1291  %2 = vector.transfer_read %A[%c0, %c0], %f0, %arith_all_true_mask : memref<?x?xf32>, vector<4x[4]xf32>1292 1293  // CHECK: vector.transfer_write {{.*}}[%[[C0]], %[[C0]]] :1294  vector.transfer_write %2, %A[%c0, %c0], %arith_all_true_mask : vector<4x[4]xf32>, memref<?x?xf32>1295 1296  // CHECK: return1297  return %1, %2 : vector<4x8xf32>, vector<4x[4]xf32>1298}1299 1300// -----1301 1302// CHECK-LABEL: fold_vector_transfers1303func.func @fold_vector_transfers(%A: memref<?x8xf32>) -> (vector<4x8xf32>, vector<4x9xf32>) {1304  %c0 = arith.constant 0 : index1305  %f0 = arith.constant 0.0 : f321306 1307  // CHECK: vector.transfer_read %{{.*}} {in_bounds = [false, true]}1308  %1 = vector.transfer_read %A[%c0, %c0], %f0 : memref<?x8xf32>, vector<4x8xf32>1309 1310  // CHECK: vector.transfer_write %{{.*}} {in_bounds = [false, true]}1311  vector.transfer_write %1, %A[%c0, %c0] : vector<4x8xf32>, memref<?x8xf32>1312 1313  // Both dims may be out-of-bounds, attribute is elided.1314  // CHECK: vector.transfer_read %{{.*}}1315  // CHECK-NOT: in_bounds1316  %2 = vector.transfer_read %A[%c0, %c0], %f0 : memref<?x8xf32>, vector<4x9xf32>1317 1318  // Both dims may be out-of-bounds, attribute is elided.1319  // CHECK: vector.transfer_write %{{.*}}1320  // CHECK-NOT: in_bounds1321  vector.transfer_write %2, %A[%c0, %c0] : vector<4x9xf32>, memref<?x8xf32>1322 1323  // CHECK: return1324  return %1, %2 : vector<4x8xf32>, vector<4x9xf32>1325}1326 1327// -----1328 1329// CHECK-LABEL: bitcast_folding1330//  CHECK-SAME:   %[[A:.*]]: vector<4x8xf32>1331//  CHECK-SAME:   %[[B:.*]]: vector<2xi32>1332//  CHECK:        return %[[A]], %[[B]] : vector<4x8xf32>, vector<2xi32>1333func.func @bitcast_folding(%I1: vector<4x8xf32>, %I2: vector<2xi32>) -> (vector<4x8xf32>, vector<2xi32>) {1334  %0 = vector.bitcast %I1 : vector<4x8xf32> to vector<4x8xf32>1335  %1 = vector.bitcast %I2 : vector<2xi32> to vector<4xi16>1336  %2 = vector.bitcast %1 : vector<4xi16> to vector<2xi32>1337  return %0, %2 : vector<4x8xf32>, vector<2xi32>1338}1339 1340// -----1341 1342// CHECK-LABEL: func @bitcast_f16_to_f321343//              bit pattern: 0x400040001344//       CHECK-DAG: %[[CST1:.+]] = arith.constant dense<2.00390625> : vector<4xf32>1345//              bit pattern: 0x000000001346//       CHECK-DAG: %[[CST0:.+]] = arith.constant dense<0.000000e+00> : vector<4xf32>1347//       CHECK: return %[[CST0]], %[[CST1]]1348func.func @bitcast_f16_to_f32() -> (vector<4xf32>, vector<4xf32>) {1349  %cst0 = arith.constant dense<0.0> : vector<8xf16> // bit pattern: 0x00001350  %cst1 = arith.constant dense<2.0> : vector<8xf16> // bit pattern: 0x40001351  %cast0 = vector.bitcast %cst0: vector<8xf16> to vector<4xf32>1352  %cast1 = vector.bitcast %cst1: vector<8xf16> to vector<4xf32>1353  return %cast0, %cast1: vector<4xf32>, vector<4xf32>1354}1355 1356// -----1357 1358// CHECK-LABEL: func @bitcast_i8_to_i321359//              bit pattern: 0xA0A0A0A01360//       CHECK-DAG: %[[CST1:.+]] = arith.constant dense<-1600085856> : vector<4xi32>1361//              bit pattern: 0x000000001362//       CHECK-DAG: %[[CST0:.+]] = arith.constant dense<0> : vector<4xi32>1363//       CHECK: return %[[CST0]], %[[CST1]]1364func.func @bitcast_i8_to_i32() -> (vector<4xi32>, vector<4xi32>) {1365  %cst0 = arith.constant dense<0> : vector<16xi8> // bit pattern: 0x001366  %cst1 = arith.constant dense<160> : vector<16xi8> // bit pattern: 0xA01367  %cast0 = vector.bitcast %cst0: vector<16xi8> to vector<4xi32>1368  %cast1 = vector.bitcast %cst1: vector<16xi8> to vector<4xi32>1369  return %cast0, %cast1: vector<4xi32>, vector<4xi32>1370}1371 1372// -----1373 1374// CHECK-LABEL: broadcast_poison1375//       CHECK:  %[[POISON:.*]] = ub.poison : vector<4x6xi8>1376//       CHECK:  return %[[POISON]] : vector<4x6xi8>1377func.func @broadcast_poison() -> vector<4x6xi8> {1378  %poison = ub.poison : vector<6xi8>1379  %broadcast = vector.broadcast %poison : vector<6xi8> to vector<4x6xi8>1380  return %broadcast : vector<4x6xi8>1381}1382 1383// -----1384 1385// CHECK-LABEL:  broadcast_splat_constant1386//       CHECK:  %[[CONST:.*]] = arith.constant dense<1> : vector<4x6xi8>1387//       CHECK:  return %[[CONST]] : vector<4x6xi8>1388func.func @broadcast_splat_constant() -> vector<4x6xi8> {1389  %cst = arith.constant dense<1> : vector<6xi8>1390  %broadcast = vector.broadcast %cst : vector<6xi8> to vector<4x6xi8>1391  return %broadcast : vector<4x6xi8>1392}1393 1394// -----1395 1396// CHECK-LABEL: broadcast_folding11397//       CHECK: %[[CST:.*]] = arith.constant dense<42> : vector<4xi32>1398//   CHECK-NOT: vector.broadcast1399//       CHECK: return %[[CST]]1400func.func @broadcast_folding1() -> vector<4xi32> {1401  %0 = arith.constant 42 : i321402  %1 = vector.broadcast %0 : i32 to vector<4xi32>1403  return %1 : vector<4xi32>1404}1405 1406// -----1407 1408// CHECK-LABEL: @broadcast_folding21409//       CHECK: %[[CST:.*]] = arith.constant dense<42> : vector<4x16xi32>1410//   CHECK-NOT: vector.broadcast1411//       CHECK: return %[[CST]]1412func.func @broadcast_folding2() -> vector<4x16xi32> {1413  %0 = arith.constant 42 : i321414  %1 = vector.broadcast %0 : i32 to vector<16xi32>1415  %2 = vector.broadcast %1 : vector<16xi32> to vector<4x16xi32>1416  return %2 : vector<4x16xi32>1417}1418 1419// -----1420 1421// CHECK-LABEL: @fold_consecutive_broadcasts(1422//  CHECK-SAME:                              %[[ARG0:.*]]: i321423//       CHECK: %[[RESULT:.*]] = vector.broadcast %[[ARG0]] : i32 to vector<4x16xi32>1424//       CHECK: return %[[RESULT]]1425func.func @fold_consecutive_broadcasts(%a : i32) -> vector<4x16xi32> {1426  %1 = vector.broadcast %a : i32 to vector<16xi32>1427  %2 = vector.broadcast %1 : vector<16xi32> to vector<4x16xi32>1428  return %2 : vector<4x16xi32>1429}1430 1431// -----1432 1433// CHECK-LABEL: shape_cast_splat_constant1434//       CHECK-DAG: %[[CST1:.*]] = arith.constant dense<1> : vector<3x4x2xi32>1435//       CHECK-DAG: %[[CST0:.*]] = arith.constant dense<2.000000e+00> : vector<20x2xf32>1436//       CHECK: return %[[CST0]], %[[CST1]] : vector<20x2xf32>, vector<3x4x2xi32>1437func.func @shape_cast_splat_constant() -> (vector<20x2xf32>, vector<3x4x2xi32>) {1438  %cst = arith.constant dense<2.000000e+00> : vector<5x4x2xf32>1439  %cst_1 = arith.constant dense<1> : vector<12x2xi32>1440  %0 = vector.shape_cast %cst : vector<5x4x2xf32> to vector<20x2xf32>1441  %1 = vector.shape_cast %cst_1 : vector<12x2xi32> to vector<3x4x2xi32>1442  return %0, %1 : vector<20x2xf32>, vector<3x4x2xi32>1443}1444 1445// -----1446 1447// Test of shape_cast's fold method:1448// shape_cast(constant) -> constant.1449//1450// CHECK-LABEL: @shape_cast_dense_int_constant1451//               CHECK: %[[CST:.*]] = arith.constant1452// CHECK-SAME{LITERAL}: dense<[[2, 3, 5], [7, 11, 13]]>1453//               CHECK: return %[[CST]] : vector<2x3xi8>1454func.func @shape_cast_dense_int_constant() -> vector<2x3xi8> {1455  %cst = arith.constant dense<[2, 3, 5, 7, 11, 13]> : vector<6xi8>1456  %0 = vector.shape_cast %cst : vector<6xi8> to vector<2x3xi8>1457  return %0 : vector<2x3xi8>1458}1459 1460// -----1461 1462// Test of shape_cast fold's method:1463// (shape_cast(const_x), const_x) -> (const_x_folded, const_x)1464//1465// CHECK-LABEL: @shape_cast_dense_float_constant1466//  CHECK-DAG: %[[CST0:.*]] = {{.*}}1.000000e+00, 2.000000e+00{{.*}} vector<1x2xf32>1467//  CHECK-DAG: %[[CST1:.*]] = {{.*}}1.000000e+00, 2.000000e+00{{.*}} vector<2xf32>1468//      CHECK: return %[[CST1]], %[[CST0]] : vector<2xf32>, vector<1x2xf32>1469func.func @shape_cast_dense_float_constant() -> (vector<2xf32>, vector<1x2xf32>){1470  %cst = arith.constant dense<[[1.0, 2.0]]> : vector<1x2xf32>1471  %0 = vector.shape_cast %cst : vector<1x2xf32> to vector<2xf32>1472  return %0, %cst : vector<2xf32>, vector<1x2xf32>1473}1474 1475// -----1476 1477// CHECK-LABEL: shape_cast_poison1478//       CHECK-DAG: %[[CST1:.*]] = ub.poison : vector<3x4x2xi32>1479//       CHECK-DAG: %[[CST0:.*]] = ub.poison : vector<20x2xf32>1480//       CHECK: return %[[CST0]], %[[CST1]] : vector<20x2xf32>, vector<3x4x2xi32>1481func.func @shape_cast_poison() -> (vector<20x2xf32>, vector<3x4x2xi32>) {1482  %poison = ub.poison : vector<5x4x2xf32>1483  %poison_1 = ub.poison : vector<12x2xi32>1484  %0 = vector.shape_cast %poison : vector<5x4x2xf32> to vector<20x2xf32>1485  %1 = vector.shape_cast %poison_1 : vector<12x2xi32> to vector<3x4x2xi32>1486  return %0, %1 : vector<20x2xf32>, vector<3x4x2xi32>1487}1488 1489// -----1490 1491// CHECK-LABEL: extract_strided_constant1492//       CHECK-DAG: %[[CST1:.*]] = arith.constant dense<1> : vector<2x13x3xi32>1493//       CHECK-DAG: %[[CST0:.*]] = arith.constant dense<2.000000e+00> : vector<12x2xf32>1494//       CHECK: return %[[CST0]], %[[CST1]] : vector<12x2xf32>, vector<2x13x3xi32>1495func.func @extract_strided_constant() -> (vector<12x2xf32>, vector<2x13x3xi32>) {1496  %cst = arith.constant dense<2.000000e+00> : vector<29x7xf32>1497  %cst_1 = arith.constant dense<1> : vector<4x37x9xi32>1498  %0 = vector.extract_strided_slice %cst1499    {offsets = [2, 3], sizes = [12, 2], strides = [1, 1]}1500      : vector<29x7xf32> to vector<12x2xf32>1501  %1 = vector.extract_strided_slice %cst_11502    {offsets = [1, 2, 5], sizes = [2, 13, 3], strides = [1, 1, 1]}1503      : vector<4x37x9xi32> to vector<2x13x3xi32>1504  return %0, %1 : vector<12x2xf32>, vector<2x13x3xi32>1505}1506 1507// -----1508 1509// CHECK-LABEL: extract_strided_broadcast1510//       CHECK:   %[[B:.*]] = vector.broadcast %{{.*}} : vector<4xf16> to vector<2x4xf16>1511//  CHECK-NEXT:   return %[[B]] : vector<2x4xf16>1512func.func @extract_strided_broadcast(%arg0: vector<4xf16>) -> vector<2x4xf16> {1513 %0 = vector.broadcast %arg0 : vector<4xf16> to vector<16x4xf16>1514 %1 = vector.extract_strided_slice %01515  {offsets = [0, 0], sizes = [2, 4], strides = [1, 1]} :1516  vector<16x4xf16> to vector<2x4xf16>1517  return %1 : vector<2x4xf16>1518}1519 1520// -----1521 1522// CHECK-LABEL: extract_strided_broadcast21523//       CHECK:   %[[E:.*]] = vector.extract_strided_slice %{{.*}} {offsets = [0], sizes = [2], strides = [1]} : vector<4xf16> to vector<2xf16>1524//  CHECK-NEXT:   %[[B:.*]] = vector.broadcast %[[E]] : vector<2xf16> to vector<2x2xf16>1525//  CHECK-NEXT:   return %[[B]] : vector<2x2xf16>1526func.func @extract_strided_broadcast2(%arg0: vector<4xf16>) -> vector<2x2xf16> {1527 %0 = vector.broadcast %arg0 : vector<4xf16> to vector<16x4xf16>1528 %1 = vector.extract_strided_slice %01529  {offsets = [0, 0], sizes = [2, 2], strides = [1, 1]} :1530  vector<16x4xf16> to vector<2x2xf16>1531  return %1 : vector<2x2xf16>1532}1533 1534// -----1535 1536// CHECK-LABEL: func @extract_strided_broadcast31537//  CHECK-SAME: (%[[ARG:.+]]: vector<1xf32>)1538//       CHECK: %[[V:.+]] = vector.broadcast %[[ARG]] : vector<1xf32> to vector<1x4xf32>1539//       CHECK: return %[[V]]1540func.func @extract_strided_broadcast3(%arg0: vector<1xf32>) -> vector<1x4xf32> {1541 %0 = vector.broadcast %arg0 : vector<1xf32> to vector<1x8xf32>1542 %1 = vector.extract_strided_slice %01543      {offsets = [0, 4], sizes = [1, 4], strides = [1, 1]}1544      : vector<1x8xf32> to vector<1x4xf32>1545  return %1 : vector<1x4xf32>1546}1547 1548// -----1549 1550// CHECK-LABEL: func @extract_strided_broadcast41551//  CHECK-SAME: (%[[ARG:.+]]: f32)1552//       CHECK: %[[V:.+]] = vector.broadcast %[[ARG]] : f32 to vector<1x4xf32>1553//       CHECK: return %[[V]]1554func.func @extract_strided_broadcast4(%arg0: f32) -> vector<1x4xf32> {1555 %0 = vector.broadcast %arg0 : f32 to vector<1x8xf32>1556 %1 = vector.extract_strided_slice %01557      {offsets = [0, 4], sizes = [1, 4], strides = [1, 1]}1558      : vector<1x8xf32> to vector<1x4xf32>1559  return %1 : vector<1x4xf32>1560}1561 1562// -----1563 1564// Check the case where the same dimension is both broadcasted and sliced 1565// CHECK-LABEL: func @extract_strided_broadcast51566//  CHECK-SAME: (%[[ARG:.+]]: vector<2x1xf32>)1567//       CHECK: %[[V:.+]] = vector.broadcast %[[ARG]] : vector<2x1xf32> to vector<2x4xf32>1568//       CHECK: return %[[V]]1569func.func @extract_strided_broadcast5(%arg0: vector<2x1xf32>) -> vector<2x4xf32> {1570 %0 = vector.broadcast %arg0 : vector<2x1xf32> to vector<2x8xf32>1571 %1 = vector.extract_strided_slice %01572      {offsets = [0, 4], sizes = [2, 4], strides = [1, 1]}1573      : vector<2x8xf32> to vector<2x4xf32>1574  return %1 : vector<2x4xf32>1575}1576 1577// -----1578 1579// CHECK-LABEL: consecutive_shape_cast1580//       CHECK:   %[[C:.*]] = vector.shape_cast %{{.*}} : vector<16xf16> to vector<4x4xf16>1581//  CHECK-NEXT:   return %[[C]] : vector<4x4xf16>1582func.func @consecutive_shape_cast(%arg0: vector<16xf16>) -> vector<4x4xf16> {1583  %0 = vector.shape_cast %arg0 : vector<16xf16> to vector<2x8xf16>1584  %1 = vector.shape_cast %0 : vector<2x8xf16> to vector<4x4xf16>1585  return %1 : vector<4x4xf16>1586}1587 1588// -----1589 1590// CHECK-LABEL: func @dead_transfer_op1591//   CHECK-NOT:   vector.transfer_read1592//   CHECK-NOT:   vector.transfer_write1593//       CHECK:   return1594func.func @dead_transfer_op(%arg0 : tensor<4x4xf32>, %arg1 : memref<4x4xf32>,1595                       %v0 : vector<1x4xf32>) {1596  %c0 = arith.constant 0 : index1597  %cf0 = arith.constant 0.0 : f321598  %r = vector.transfer_read %arg1[%c0, %c0], %cf0 :1599    memref<4x4xf32>, vector<1x4xf32>1600  %w = vector.transfer_write %v0, %arg0[%c0, %c0] :1601    vector<1x4xf32>, tensor<4x4xf32>1602  return1603}1604 1605// -----1606 1607// CHECK-LABEL: func @dead_load1608//   CHECK-NOT:   vector.maskedload1609//   CHECK-NOT:   vector.gather1610//   CHECK-NOT:   vector.expandload1611//       CHECK:   return1612func.func @dead_load(%base: memref<?xf32>, %indices: vector<16xi32>,1613                          %mask: vector<16xi1>, %passthru: vector<16xf32>) {1614  %c0 = arith.constant 0 : index1615  %0 = vector.maskedload %base[%c0], %mask, %passthru :1616    memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32>1617  %1 = vector.gather %base[%c0][%indices], %mask, %passthru :1618    memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32>1619  %2 = vector.expandload %base[%c0], %mask, %passthru :1620    memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32>1621  return1622}1623 1624// -----1625 1626#contraction_accesses0 = [1627  affine_map<(i, j, k) -> (i, k)>,1628  affine_map<(i, j, k) -> (k, j)>,1629  affine_map<(i, j, k) -> (i, j)>1630]1631#contraction_trait0 = {1632  indexing_maps = #contraction_accesses0,1633  iterator_types = ["parallel", "parallel", "reduction"]1634}1635 1636// CHECK-LABEL: func @contractions1637//  CHECK-SAME:   %[[A:[0-9a-zA-Z]+]]: vector<2x3xf32>1638//  CHECK-SAME:   %[[B:[0-9a-zA-Z]+]]: vector<3x4xf32>1639//  CHECK-SAME:   %[[C:[0-9a-zA-Z]+]]: vector<2x4xf32>1640//  CHECK-SAME:   %[[A_I8:[0-9a-zA-Z]+]]: vector<2x3xi8>1641//  CHECK-SAME:   %[[B_I8:[0-9a-zA-Z]+]]: vector<3x4xi8>1642//  CHECK-SAME:   %[[C_I8:[0-9a-zA-Z]+]]: vector<2x4xi8>1643func.func @contractions(%a: vector<2x3xf32>, %b: vector<3x4xf32>, %c: vector<2x4xf32>,1644                   %a_i8: vector<2x3xi8>, %b_i8: vector<3x4xi8>, %c_i8: vector<2x4xi8>)1645  -> (vector<2x4xf32>, vector<2x4xi8>)1646{1647  // CHECK-NOT: arith.constant1648  %vf_0 = arith.constant dense <0.0>: vector<2x4xf32>1649  // CHECK-NOT: arith.addf1650  //     CHECK: %[[D:.*]] = vector.contract {{.*}} %[[A]], %[[B]], %[[C]]1651  %0 = vector.contract #contraction_trait0 %a, %b, %vf_0:1652    vector<2x3xf32>, vector<3x4xf32> into vector<2x4xf32>1653  // CHECK-NOT: arith.addf1654  %1 = arith.addf %0, %c: vector<2x4xf32>1655 1656  // CHECK-NOT: arith.constant1657  %vi8_0 = arith.constant dense <0>: vector<2x4xi8>1658  // CHECK-NOT: arith.addi1659  //     CHECK: %[[D_I8:.*]] = vector.contract {{.*}} %[[A_I8]], %[[B_I8]], %[[C_I8]]1660  %i8_0 = vector.contract #contraction_trait0 %a_i8, %b_i8, %vi8_0:1661    vector<2x3xi8>, vector<3x4xi8> into vector<2x4xi8>1662  // CHECK-NOT: arith.addi1663  %i8_1 = arith.addi %i8_0, %c_i8: vector<2x4xi8>1664 1665  // CHECK: return %[[D]], %[[D_I8]]1666  return %1, %i8_1: vector<2x4xf32>, vector<2x4xi8>1667}1668 1669// -----1670 1671// CHECK-LABEL: func @transfer_folding_11672//  CHECK-SAME:   %[[T0:[0-9a-zA-Z]+]]: tensor<2x3x4xf32>1673//  CHECK-SAME:   %[[T1:[0-9a-zA-Z]+]]: tensor<2x3x4xf32>1674func.func @transfer_folding_1(%t0: tensor<2x3x4xf32>, %t1: tensor<2x3x4xf32>)1675  -> (tensor<2x3x4xf32>, tensor<2x3x4xf32>, tensor<2x3x4xf32>)1676{1677  %c0 = arith.constant 0 : index1678  %pad = arith.constant 0.0 : f321679  %v = vector.transfer_read %t0[%c0, %c0, %c0], %pad {in_bounds = [true, true, true]} :1680    tensor<2x3x4xf32>, vector<2x3x4xf32>1681 1682  %r0 = vector.transfer_write %v, %t1[%c0, %c0, %c0] {in_bounds = [true, true, true]} :1683    vector<2x3x4xf32>, tensor<2x3x4xf32>1684 1685  %t2 = "test.constant"() { value = dense<6.0> : tensor<2x3x4xf32>} : () -> (tensor<2x3x4xf32>)1686  %r1 = vector.transfer_write %v, %t2[%c0, %c0, %c0] {in_bounds = [true, true, true]} :1687    vector<2x3x4xf32>, tensor<2x3x4xf32>1688 1689 1690  // CHECK-NEXT: some_op_that_may_have_side_effects1691  %t3 = "some_op_that_may_have_side_effects"() : () -> (tensor<2x3x4xf32>)1692  %r2 = vector.transfer_write %v, %t0[%c0, %c0, %c0] {in_bounds = [true, true, true]} :1693    vector<2x3x4xf32>, tensor<2x3x4xf32>1694 1695  // CHECK-NEXT: return %[[T0]], %[[T0]], %[[T0]]1696  return %r0, %r1, %r2: tensor<2x3x4xf32>, tensor<2x3x4xf32>, tensor<2x3x4xf32>1697}1698 1699// -----1700 1701// CHECK-LABEL: func @store_after_load_tensor1702//  CHECK-SAME: (%[[ARG:.*]]: tensor<4x4xf32>)1703//   CHECK-NOT:   vector.transfer_read1704//   CHECK-NOT:   vector.transfer_write1705//       CHECK:   return %[[ARG]] : tensor<4x4xf32>1706func.func @store_after_load_tensor(%arg0 : tensor<4x4xf32>) -> tensor<4x4xf32> {1707  %c1 = arith.constant 1 : index1708  %c0 = arith.constant 0 : index1709  %cf0 = arith.constant 0.0 : f321710  %0 = vector.transfer_read %arg0[%c1, %c0], %cf0 :1711    tensor<4x4xf32>, vector<1x4xf32>1712  %w0 = vector.transfer_write %0, %arg0[%c1, %c0] :1713    vector<1x4xf32>, tensor<4x4xf32>1714  return %w0 : tensor<4x4xf32>1715}1716 1717// -----1718 1719// CHECK-LABEL: func @negative_store_after_load_tensor1720//       CHECK:   vector.transfer_read1721//       CHECK:   vector.transfer_write1722//       CHECK:   return1723func.func @negative_store_after_load_tensor(%arg0 : tensor<4x4xf32>) -> tensor<4x4xf32> {1724  %c1 = arith.constant 1 : index1725  %c0 = arith.constant 0 : index1726  %cf0 = arith.constant 0.0 : f321727  %0 = vector.transfer_read %arg0[%c1, %c0], %cf0 :1728    tensor<4x4xf32>, vector<1x4xf32>1729  %w0 = vector.transfer_write %0, %arg0[%c0, %c0] :1730    vector<1x4xf32>, tensor<4x4xf32>1731  return %w0 : tensor<4x4xf32>1732}1733 1734// -----1735 1736// CHECK-LABEL: func @store_to_load_tensor1737//  CHECK-SAME: (%[[ARG:.*]]: tensor<4x4xf32>, %[[V0:.*]]: vector<1x4xf32>, %[[V1:.*]]: vector<1x4xf32>)1738//   CHECK-NOT:   vector.transfer_write1739//   CHECK-NOT:   vector.transfer_read1740//       CHECK:   return %[[V0]] : vector<1x4xf32>1741func.func @store_to_load_tensor(%arg0 : tensor<4x4xf32>,1742  %v0 : vector<1x4xf32>, %v1 : vector<1x4xf32>) -> vector<1x4xf32> {1743  %c1 = arith.constant 1 : index1744  %c2 = arith.constant 2 : index1745  %c0 = arith.constant 0 : index1746  %cf0 = arith.constant 0.0 : f321747  %w0 = vector.transfer_write %v0, %arg0[%c1, %c0] {in_bounds = [true, true]} :1748    vector<1x4xf32>, tensor<4x4xf32>1749  %w1 = vector.transfer_write %v1, %w0[%c2, %c0] {in_bounds = [true, true]} :1750    vector<1x4xf32>, tensor<4x4xf32>1751  %0 = vector.transfer_read %w1[%c1, %c0], %cf0 {in_bounds = [true, true]} :1752    tensor<4x4xf32>, vector<1x4xf32>1753  return %0 : vector<1x4xf32>1754}1755 1756// -----1757 1758// CHECK-LABEL: func @negative_store_to_load_tensor1759//       CHECK:   vector.transfer_write1760//       CHECK:   vector.transfer_write1761//       CHECK:   %[[V:.*]] = vector.transfer_read1762//       CHECK:   return %[[V]] : vector<1x4xf32>1763func.func @negative_store_to_load_tensor(%arg0 : tensor<4x4xf32>,1764  %v0 : vector<1x4xf32>, %v1 : vector<1x4xf32>, %i : index) -> vector<1x4xf32> {1765  %c1 = arith.constant 1 : index1766  %c2 = arith.constant 2 : index1767  %c0 = arith.constant 0 : index1768  %cf0 = arith.constant 0.0 : f321769  %w0 = vector.transfer_write %v0, %arg0[%c1, %c0] {in_bounds = [true, true]} :1770    vector<1x4xf32>, tensor<4x4xf32>1771  %w1 = vector.transfer_write %v0, %w0[%i, %i] {in_bounds = [true, true]} :1772    vector<1x4xf32>, tensor<4x4xf32>1773  %0 = vector.transfer_read %w1[%c1, %c0], %cf0 {in_bounds = [true, true]} :1774    tensor<4x4xf32>, vector<1x4xf32>1775  return %0 : vector<1x4xf32>1776}1777 1778// -----1779 1780// CHECK-LABEL: func @store_to_load_tensor_broadcast1781//  CHECK-SAME: (%[[ARG:.*]]: tensor<4x4xf32>, %[[V0:.*]]: vector<4x2xf32>)1782//       CHECK:   %[[B:.*]] = vector.broadcast %[[V0]] : vector<4x2xf32> to vector<6x4x2xf32>1783//       CHECK:   %[[T:.*]] = vector.transpose %[[B]], [1, 2, 0] : vector<6x4x2xf32> to vector<4x2x6xf32>1784//       CHECK:   return %[[T]] : vector<4x2x6xf32>1785func.func @store_to_load_tensor_broadcast(%arg0 : tensor<4x4xf32>,1786  %v0 : vector<4x2xf32>) -> vector<4x2x6xf32> {1787  %c0 = arith.constant 0 : index1788  %cf0 = arith.constant 0.0 : f321789  %w0 = vector.transfer_write %v0, %arg0[%c0, %c0] {in_bounds = [true, true]} :1790    vector<4x2xf32>, tensor<4x4xf32>1791  %0 = vector.transfer_read %w0[%c0, %c0], %cf0 {in_bounds = [true, true, true],1792  permutation_map = affine_map<(d0, d1) -> (d0, d1, 0)>} :1793    tensor<4x4xf32>, vector<4x2x6xf32>1794  return %0 : vector<4x2x6xf32>1795}1796 1797// -----1798 1799// CHECK-LABEL: func @negative_store_to_load_tensor_memref1800//   CHECK-NOT:   vector.broadcast1801//   CHECK-NOT:   vector.transpose1802//       CHECK:   vector.transfer_write1803//       CHECK:   vector.transfer_read1804func.func @negative_store_to_load_tensor_memref(1805    %arg0 : tensor<?x?xf32>,1806    %arg1 : memref<?x?xf32>,1807    %v0 : vector<4x2xf32>1808  ) -> vector<4x2xf32>1809{1810  %c0 = arith.constant 0 : index1811  %cf0 = arith.constant 0.0 : f321812  vector.transfer_write %v0, %arg1[%c0, %c0] {in_bounds = [true, true]} :1813    vector<4x2xf32>, memref<?x?xf32>1814  %0 = vector.transfer_read %arg0[%c0, %c0], %cf0 {in_bounds = [true, true]} :1815    tensor<?x?xf32>, vector<4x2xf32>1816  return %0 : vector<4x2xf32>1817}1818 1819// -----1820 1821// CHECK-LABEL: func @negative_store_to_load_tensor_no_actual_broadcast1822//   CHECK-NOT:   vector.broadcast1823//   CHECK-NOT:   vector.transpose1824//       CHECK:   vector.transfer_write1825//       CHECK:   vector.transfer_read1826func.func @negative_store_to_load_tensor_no_actual_broadcast(%arg0 : tensor<?x?xf32>,1827  %v0 : vector<4x2xf32>) -> vector<4x2xf32> {1828  %c0 = arith.constant 0 : index1829  %cf0 = arith.constant 0.0 : f321830  %w0 = vector.transfer_write %v0, %arg0[%c0, %c0] :1831    vector<4x2xf32>, tensor<?x?xf32>1832  %0 = vector.transfer_read %w0[%c0, %c0], %cf0 {in_bounds = [true, true]} :1833    tensor<?x?xf32>, vector<4x2xf32>1834  return %0 : vector<4x2xf32>1835}1836 1837// -----1838 1839// CHECK-LABEL: func @negative_store_to_load_tensor_broadcast_out_of_bounds1840//   CHECK-NOT:   vector.broadcast1841//   CHECK-NOT:   vector.transpose1842//       CHECK:   vector.transfer_write1843//       CHECK:   vector.transfer_read1844func.func @negative_store_to_load_tensor_broadcast_out_of_bounds(%arg0 : tensor<?x?xf32>,1845  %v0 : vector<4x2xf32>) -> vector<4x2x6xf32> {1846  %c0 = arith.constant 0 : index1847  %cf0 = arith.constant 0.0 : f321848  %w0 = vector.transfer_write %v0, %arg0[%c0, %c0] :1849    vector<4x2xf32>, tensor<?x?xf32>1850  %0 = vector.transfer_read %w0[%c0, %c0], %cf0 {in_bounds = [true, true, true],1851  permutation_map = affine_map<(d0, d1) -> (d0, d1, 0)>} :1852    tensor<?x?xf32>, vector<4x2x6xf32>1853  return %0 : vector<4x2x6xf32>1854}1855 1856// -----1857 1858// CHECK-LABEL: func @negative_store_to_load_tensor_broadcast_masked1859//   CHECK-NOT:   vector.broadcast1860//   CHECK-NOT:   vector.transpose1861//       CHECK:   vector.transfer_write1862//       CHECK:   vector.transfer_read1863func.func @negative_store_to_load_tensor_broadcast_masked(1864    %arg0 : tensor<?x?xf32>, %v0 : vector<4x2xf32>, %mask : vector<4x2xi1>)1865  -> vector<4x2x6xf32>1866{1867  %c0 = arith.constant 0 : index1868  %cf0 = arith.constant 0.0 : f321869  %w0 = vector.transfer_write %v0, %arg0[%c0, %c0], %mask {in_bounds = [true, true]} :1870    vector<4x2xf32>, tensor<?x?xf32>1871  %0 = vector.transfer_read %w0[%c0, %c0], %cf0 {in_bounds = [true, true, true],1872  permutation_map = affine_map<(d0, d1) -> (d0, d1, 0)>} :1873    tensor<?x?xf32>, vector<4x2x6xf32>1874  return %0 : vector<4x2x6xf32>1875}1876 1877// -----1878 1879// CHECK-LABEL: func @store_to_load_tensor_broadcast_scalable1880//  CHECK-SAME: (%[[ARG:.*]]: tensor<?xf32>, %[[V0:.*]]: vector<[4]xf32>)1881//       CHECK:   %[[B:.*]] = vector.broadcast %[[V0]] : vector<[4]xf32> to vector<6x[4]xf32>1882//       CHECK:   return %[[B]] : vector<6x[4]xf32>1883func.func @store_to_load_tensor_broadcast_scalable(%arg0 : tensor<?xf32>,1884  %v0 : vector<[4]xf32>) -> vector<6x[4]xf32> {1885  %c0 = arith.constant 0 : index1886  %cf0 = arith.constant 0.0 : f321887  %w0 = vector.transfer_write %v0, %arg0[%c0] {in_bounds = [true]} :1888    vector<[4]xf32>, tensor<?xf32>1889  %0 = vector.transfer_read %w0[%c0], %cf0 {in_bounds = [true, true],1890  permutation_map = affine_map<(d0) -> (0, d0)>} :1891    tensor<?xf32>, vector<6x[4]xf32>1892  return %0 : vector<6x[4]xf32>1893}1894 1895// -----1896 1897// CHECK-LABEL: func @store_to_load_tensor_perm_broadcast1898//  CHECK-SAME: (%[[ARG:.*]]: tensor<4x4x4xf32>, %[[V0:.*]]: vector<4x1xf32>)1899//       CHECK:   %[[B:.*]] = vector.broadcast %[[V0]] : vector<4x1xf32> to vector<100x5x4x1xf32>1900//       CHECK:   %[[T:.*]] = vector.transpose %[[B]], [3, 0, 2, 1] : vector<100x5x4x1xf32> to vector<1x100x4x5xf32>1901//       CHECK:   return %[[T]] : vector<1x100x4x5xf32>1902func.func @store_to_load_tensor_perm_broadcast(%arg0 : tensor<4x4x4xf32>,1903  %v0 : vector<4x1xf32>) -> vector<1x100x4x5xf32> {1904  %c0 = arith.constant 0 : index1905  %cf0 = arith.constant 0.0 : f321906  %w0 = vector.transfer_write %v0, %arg0[%c0, %c0, %c0] {in_bounds = [true, true],1907  permutation_map = affine_map<(d0, d1, d2) -> (d2, d1)>} :1908    vector<4x1xf32>, tensor<4x4x4xf32>1909  %0 = vector.transfer_read %w0[%c0, %c0, %c0], %cf0 {in_bounds = [true, true, true, true],1910  permutation_map = affine_map<(d0, d1, d2) -> (d1, 0, d2, 0)>} :1911    tensor<4x4x4xf32>, vector<1x100x4x5xf32>1912  return %0 : vector<1x100x4x5xf32>1913}1914 1915// -----1916 1917 1918// CHECK-LABEL: func @dead_store_tensor1919//   CHECK-DAG:      %[[C0:.*]] = arith.constant 0 : index1920//   CHECK-DAG:      %[[C1:.*]] = arith.constant 1 : index1921//   CHECK-DAG:      %[[C2:.*]] = arith.constant 2 : index1922//   CHECK-NOT:   vector.transfer_write {{.*}}, {{.*}}[%[[C1]], %[[C0]]1923//       CHECK:   vector.transfer_write {{.*}}, {{.*}}[%[[C2]], %[[C0]]1924//       CHECK:   %[[VTW:.*]] = vector.transfer_write {{.*}}, {{.*}}[%[[C1]], %[[C0]]1925//       CHECK:   return %[[VTW]] : tensor<4x4xf32>1926func.func @dead_store_tensor(%arg0 : tensor<4x4xf32>,1927  %v0 : vector<1x4xf32>, %v1 : vector<1x4xf32>, %i : index) -> tensor<4x4xf32> {1928  %c1 = arith.constant 1 : index1929  %c2 = arith.constant 2 : index1930  %c0 = arith.constant 0 : index1931  %cf0 = arith.constant 0.0 : f321932  %w0 = vector.transfer_write %v0, %arg0[%c1, %c0] {in_bounds = [true, true]} :1933    vector<1x4xf32>, tensor<4x4xf32>1934  %w1 = vector.transfer_write %v0, %w0[%c2, %c0] {in_bounds = [true, true]} :1935    vector<1x4xf32>, tensor<4x4xf32>1936  %w2 = vector.transfer_write %v1, %w1[%c1, %c0] {in_bounds = [true, true]} :1937    vector<1x4xf32>, tensor<4x4xf32>1938  return %w2 : tensor<4x4xf32>1939}1940 1941// -----1942 1943// CHECK-LABEL: func @negative_dead_store_tensor1944//   CHECK-DAG:      %[[C0:.*]] = arith.constant 0 : index1945//   CHECK-DAG:      %[[C1:.*]] = arith.constant 1 : index1946//       CHECK:   vector.transfer_write1947//       CHECK:   vector.transfer_write1948//       CHECK:   vector.transfer_read1949//       CHECK:   %[[VTW:.*]] = vector.transfer_write {{.*}}, {{.*}}[%[[C1]], %[[C0]]]1950//       CHECK:   return %[[VTW]] : tensor<4x4xf32>1951func.func @negative_dead_store_tensor(%arg0 : tensor<4x4xf32>,1952  %v0 : vector<1x4xf32>, %v1 : vector<1x4xf32>, %i : index) -> tensor<4x4xf32> {1953  %c1 = arith.constant 1 : index1954  %c2 = arith.constant 2 : index1955  %c0 = arith.constant 0 : index1956  %cf0 = arith.constant 0.0 : f321957  %w0 = vector.transfer_write %v0, %arg0[%c1, %c0] {in_bounds = [true, true]} :1958    vector<1x4xf32>, tensor<4x4xf32>1959  %w1 = vector.transfer_write %v0, %w0[%c2, %c0] {in_bounds = [true, true]} :1960    vector<1x4xf32>, tensor<4x4xf32>1961  %0 = vector.transfer_read %w1[%i, %i], %cf0 {in_bounds = [true, true]} :1962    tensor<4x4xf32>, vector<1x4xf32>1963  %x = arith.addf %0, %0 : vector<1x4xf32>1964  %w2 = vector.transfer_write %x, %w0[%c1, %c0] {in_bounds = [true, true]} :1965    vector<1x4xf32>, tensor<4x4xf32>1966  return %w2 : tensor<4x4xf32>1967}1968 1969// -----1970 1971//       CHECK: #[[$MAP:[0-9a-z]+]] = affine_map<(d0, d1) -> (d1, d0)>1972 1973// CHECK-LABEL: func @swap_extract_slice_transfer_write1974//  CHECK-SAME:   %[[VEC:.*]]: vector<8x4xf32>1975//  CHECK-SAME:   %[[INIT_TENSOR:.*]]: tensor<4x8xf32>,1976//  CHECK-SAME:   %[[ITER_ARG:.*]]: tensor<64x64xf32>,1977//  CHECK-SAME:   %[[IV:.*]]: index, %[[SZ:.*]]: index)1978func.func @swap_extract_slice_transfer_write(%arg0 : vector<8x4xf32>,1979                                             %arg1 : tensor<4x8xf32>,1980                                             %arg2 : tensor<64x64xf32>,1981                                             %iv : index, %sz : index) -> tensor<64x64xf32> {1982  //       CHECK:   %[[C0:.*]] = arith.constant 0 : index1983  %c0 = arith.constant 0 : index1984 1985  //       CHECK:   %[[T0:.*]] = tensor.extract_slice %[[ITER_ARG]]1986  //  CHECK-SAME:                 [%[[IV]], 16] [%[[SZ]], 8]1987  //       CHECK:   %[[T1:.*]] = vector.transfer_write %[[VEC]]1988  //  CHECK-SAME:                 %[[T0]][%[[C0]], %[[C0]]]1989  //  CHECK-SAME:                 in_bounds = [true, false]1990  //  CHECK-SAME:                 permutation_map = #[[$MAP]]1991  //       CHECK:   %[[T2:.*]] = tensor.insert_slice %[[T1]] into %[[ITER_ARG]]1992  //  CHECK-SAME:                 [%[[IV]], 16] [%[[SZ]], 8]1993  %0 = vector.transfer_write %arg0, %arg1[%c0, %c0] {in_bounds = [true, true], permutation_map = affine_map<(d0, d1) -> (d1, d0)>} : vector<8x4xf32>, tensor<4x8xf32>1994  %1 = tensor.extract_slice %0[0, 0] [%sz, 8] [1, 1] : tensor<4x8xf32> to tensor<?x8xf32>1995  %2 = tensor.insert_slice %1 into %arg2[%iv, 16] [%sz, 8] [1, 1] : tensor<?x8xf32> into tensor<64x64xf32>1996 1997  //       CHECK:   return %[[T2]]1998  func.return %2 : tensor<64x64xf32>1999}2000 2001// -----2002 2003// CHECK-LABEL: func @do_not_swap_extract_slice_transfer_write2004//  CHECK-SAME:   %[[VEC:.*]]: vector<8xf32>,2005//  CHECK-SAME:   %[[VEC_SMALL:.*]]: vector<4xf32>,2006//  CHECK-SAME:   %[[INIT_TENSOR:.*]]: tensor<8xf32>,2007//  CHECK-SAME:   %[[ITER_ARG:.*]]: tensor<64xf32>,2008//  CHECK-SAME:   %[[IV:.*]]: index, %[[SZ:.*]]: index)2009func.func @do_not_swap_extract_slice_transfer_write(%arg0 : vector<8xf32>,2010                                                    %arg1 : vector<4xf32>,2011                                                    %arg2 : tensor<8xf32>,2012                                                    %arg3 : tensor<64xf32>,2013                                                    %iv : index, %sz : index) -> (tensor<64xf32>, tensor<64xf32>, tensor<64xf32>) {2014  //       CHECK:   %[[C0:.*]] = arith.constant 0 : index2015  %c0 = arith.constant 0 : index2016 2017  // Don't swap if the extracted and inserted slices do not match.2018  //       CHECK:   %[[T0:.*]] = vector.transfer_write %[[VEC]]2019  //       CHECK:   %[[T1:.*]] = tensor.extract_slice %[[T0]]2020  //       CHECK:   %[[T2:.*]] = tensor.insert_slice %[[T1]]2021  %0 = vector.transfer_write %arg0, %arg2[%c0] {in_bounds = [true]} : vector<8xf32>, tensor<8xf32>2022  %1 = tensor.extract_slice %0[0] [%iv] [1] : tensor<8xf32> to tensor<?xf32>2023  %2 = tensor.insert_slice %1 into %arg3[%iv] [%sz] [1] : tensor<?xf32> into tensor<64xf32>2024 2025  // Don't swap if the TransferWriteOp takes a small vector.2026  //       CHECK:   %[[T3:.*]] = vector.transfer_write %[[VEC_SMALL]]2027  //       CHECK:   %[[T4:.*]] = tensor.extract_slice %[[T3]]2028  //       CHECK:   %[[T5:.*]] = tensor.insert_slice %[[T4]]2029  %3 = vector.transfer_write %arg1, %arg2[%c0] {in_bounds = [true]} : vector<4xf32>, tensor<8xf32>2030  %4 = tensor.extract_slice %3[0] [%sz] [1] : tensor<8xf32> to tensor<?xf32>2031  %5 = tensor.insert_slice %4 into %arg3[%iv] [%sz] [1] : tensor<?xf32> into tensor<64xf32>2032 2033  // Don't swap if the one of the operations is rank-reducing.2034  //       CHECK:   %[[T6:.*]] = vector.transfer_write %[[VEC]]2035  //       CHECK:   %[[T7:.*]] = tensor.extract_slice %[[T6]]2036  //       CHECK:   %[[T8:.*]] = tensor.insert_slice %[[T7]]2037  %6 = vector.transfer_write %arg0, %arg2[%c0] {in_bounds = [true]} : vector<8xf32>, tensor<8xf32>2038  %7 = tensor.extract_slice %6[0] [1] [1] : tensor<8xf32> to tensor<f32>2039  %8 = tensor.insert_slice %7 into %arg3[%iv] [1] [1] : tensor<f32> into tensor<64xf32>2040 2041  //       CHECK:   return %[[T2]], %[[T5]], %[[T8]]2042  func.return %2, %5, %8 : tensor<64xf32>, tensor<64xf32>, tensor<64xf32>2043}2044 2045// -----2046 2047// CHECK-LABEL: func @vector_multi_reduction_single_parallel(2048//  CHECK-SAME:     %[[v:.*]]: vector<2xf32>,2049func.func @vector_multi_reduction_single_parallel(%arg0: vector<2xf32>, %acc: vector<2xf32>) -> vector<2xf32> {2050    %0 = vector.multi_reduction <mul>, %arg0, %acc [] : vector<2xf32> to vector<2xf32>2051 2052//       CHECK:     return %[[v]] : vector<2xf32>2053    return %0 : vector<2xf32>2054}2055 2056// -----2057 2058// CHECK-LABEL: func @masked_vector_multi_reduction_single_parallel(2059//  CHECK-SAME:     %[[VAL_0:.*]]: vector<2xf32>, %{{.*}}: vector<2xf32>,2060func.func @masked_vector_multi_reduction_single_parallel(%arg0: vector<2xf32>, %acc: vector<2xf32>, %mask: vector<2xi1>) -> vector<2xf32> {2061    %0 = vector.mask %mask { vector.multi_reduction <mul>, %arg0, %acc [] : vector<2xf32> to vector<2xf32> } : vector<2xi1> -> vector<2xf32>2062//       CHECK:   return %[[VAL_0]] : vector<2xf32>2063    return %0 : vector<2xf32>2064}2065 2066// -----2067 2068// CHECK-LABEL: func @vector_multi_reduction_unit_dimensions(2069//  CHECK-SAME: %[[SOURCE:.+]]: vector<5x1x4x1x20xf32>, %[[ACC:.+]]: vector<5x4x20xf32>2070func.func @vector_multi_reduction_unit_dimensions(%source: vector<5x1x4x1x20xf32>, %acc: vector<5x4x20xf32>) -> vector<5x4x20xf32> {2071//       CHECK:   %[[CAST:.+]] = vector.shape_cast  %[[SOURCE]] : vector<5x1x4x1x20xf32> to vector<5x4x20xf32>2072//       CHECK:   %[[RESULT:.+]] = arith.mulf  %[[ACC]], %[[CAST]] : vector<5x4x20xf32>2073    %0 = vector.multi_reduction <mul>, %source, %acc [1, 3] : vector<5x1x4x1x20xf32> to vector<5x4x20xf32>2074 2075//       CHECK:     return %[[RESULT]] : vector<5x4x20xf32>2076    return %0 : vector<5x4x20xf32>2077}2078 2079// -----2080 2081// CHECK-LABEL:   func.func @vector_multi_reduction_scalable(2082// CHECK-SAME:     %[[VAL_0:.*]]: vector<1x[4]x1xf32>,2083// CHECK-SAME:     %[[VAL_1:.*]]: vector<1x[4]xf32>,2084// CHECK-SAME:     %[[VAL_2:.*]]: vector<1x[4]x1xi1>)2085func.func @vector_multi_reduction_scalable(%source: vector<1x[4]x1xf32>,2086                                           %acc: vector<1x[4]xf32>,2087                                           %mask: vector<1x[4]x1xi1>) -> vector<1x[4]xf32> {2088// CHECK:           %[[VAL_3:.*]] = vector.shape_cast %[[VAL_2]] : vector<1x[4]x1xi1> to vector<1x[4]xi1>2089// CHECK:           %[[VAL_4:.*]] = vector.shape_cast %[[VAL_0]] : vector<1x[4]x1xf32> to vector<1x[4]xf32>2090// CHECK:           %[[VAL_5:.*]] = arith.addf %[[VAL_1]], %[[VAL_4]] : vector<1x[4]xf32>2091// CHECK:           %[[VAL_6:.*]] = arith.select %[[VAL_3]], %[[VAL_5]], %[[VAL_4]] : vector<1x[4]xi1>, vector<1x[4]xf32>2092    %0 = vector.mask %mask { vector.multi_reduction <add>, %source, %acc [2] : vector<1x[4]x1xf32> to vector<1x[4]xf32> } :2093          vector<1x[4]x1xi1> -> vector<1x[4]xf32>2094 2095    return %0 : vector<1x[4]xf32>2096}2097 2098// -----2099 2100// CHECK-LABEL: func @masked_vector_multi_reduction_unit_dimensions2101//  CHECK-SAME: %[[VAL_0:.*]]: vector<5x1x4x1x20xf32>, %[[VAL_1:.*]]: vector<5x4x20xf32>,2102//  CHECK-SAME: %[[VAL_2:.*]]: vector<5x1x4x1x20xi1>)2103func.func @masked_vector_multi_reduction_unit_dimensions(%source: vector<5x1x4x1x20xf32>,2104                                                         %acc: vector<5x4x20xf32>,2105                                                         %mask: vector<5x1x4x1x20xi1>) -> vector<5x4x20xf32> {2106//       CHECK:   %[[VAL_3:.*]] = vector.shape_cast %[[VAL_2]] : vector<5x1x4x1x20xi1> to vector<5x4x20xi1>2107//       CHECK:   %[[VAL_4:.*]] = vector.shape_cast %[[VAL_0]] : vector<5x1x4x1x20xf32> to vector<5x4x20xf32>2108//       CHECK:   %[[VAL_5:.*]] = arith.mulf %[[VAL_1]], %[[VAL_4]] : vector<5x4x20xf32>2109//       CHECK:   %[[VAL_6:.*]] = arith.select %[[VAL_3]], %[[VAL_5]], %[[VAL_4]] : vector<5x4x20xi1>, vector<5x4x20xf32>2110%0 = vector.mask %mask { vector.multi_reduction <mul>, %source, %acc [1, 3] : vector<5x1x4x1x20xf32> to vector<5x4x20xf32> } :2111           vector<5x1x4x1x20xi1> -> vector<5x4x20xf32>2112    return %0 : vector<5x4x20xf32>2113}2114 2115// -----2116 2117// CHECK-LABEL: func @vector_multi_reduction_unit_dimensions_fail(2118//  CHECK-SAME: %[[SRC:.+]]: vector<5x1x4x1x20xf32>, %[[ACCUM:.+]]: vector<5x1x20xf32>2119func.func @vector_multi_reduction_unit_dimensions_fail(%source: vector<5x1x4x1x20xf32>, %acc: vector<5x1x20xf32>) -> vector<5x1x20xf32> {2120//       CHECK:   %[[RES:.+]] = vector.multi_reduction  <mul>, %[[SRC]], %[[ACCUM]] [1, 2] : vector<5x1x4x1x20xf32> to vector<5x1x20xf32>2121    %0 = vector.multi_reduction <mul>, %source, %acc [1, 2] : vector<5x1x4x1x20xf32> to vector<5x1x20xf32>2122 2123//       CHECK:     return %[[RES]] : vector<5x1x20xf32>2124    return %0 : vector<5x1x20xf32>2125}2126 2127// -----2128 2129// CHECK-LABEL: func @vector_multi_reduction_unit_dimensions_single_elem(2130//  CHECK-SAME: %[[SOURCE:.+]]: vector<1x1x1xf32>, %[[ACC:.+]]: f322131func.func @vector_multi_reduction_unit_dimensions_single_elem(%source: vector<1x1x1xf32>, %acc: f32) -> f32 {2132//       CHECK:   %[[CAST:.+]] = vector.extract  %[[SOURCE]][0, 0, 0] : f32 from vector<1x1x1xf32>2133//       CHECK:   %[[RESULT:.+]] = arith.mulf  %[[ACC]], %[[CAST]] : f322134    %0 = vector.multi_reduction <mul>, %source, %acc [0,1,2] : vector<1x1x1xf32> to f322135 2136//       CHECK:     return %[[RESULT]] : f322137    return %0 : f322138}2139 2140// -----2141 2142// CHECK-LABEL: func @masked_vector_multi_reduction_unit_dimensions_single_elem(2143//  CHECK-SAME: %[[VAL_0:.*]]: vector<1x1x1xf32>, %[[VAL_1:.*]]: f32,2144//  CHECK-SAME: %[[VAL_2:.*]]: vector<1x1x1xi1>)2145func.func @masked_vector_multi_reduction_unit_dimensions_single_elem(%source: vector<1x1x1xf32>, %acc: f32, %mask: vector<1x1x1xi1>) -> f32 {2146      // CHECK:           %[[VAL_3:.*]] = vector.extract %[[VAL_2]][0, 0, 0] : i1 from vector<1x1x1xi1>2147      // CHECK:           %[[VAL_4:.*]] = vector.extract %[[VAL_0]][0, 0, 0] : f32 from vector<1x1x1xf32>2148      // CHECK:           %[[VAL_5:.*]] = arith.mulf %[[VAL_1]], %[[VAL_4]] : f322149      // CHECK:           %[[VAL_6:.*]] = arith.select %[[VAL_3]], %[[VAL_5]], %[[VAL_4]] : f322150  %0 = vector.mask %mask { vector.multi_reduction <mul>, %source, %acc [0,1,2] : vector<1x1x1xf32> to f32 } : vector<1x1x1xi1> -> f322151    return %0 : f322152}2153 2154// -----2155 2156// CHECK-LABEL: func @insert_strided_slice_full_range2157//  CHECK-SAME: %[[SOURCE:.+]]: vector<16x16xf16>, %{{.+}}: vector<16x16xf16>2158func.func @insert_strided_slice_full_range(%source: vector<16x16xf16>, %dest: vector<16x16xf16>) -> vector<16x16xf16> {2159  %0 = vector.insert_strided_slice %source, %dest {offsets = [0, 0], strides = [1, 1]} : vector<16x16xf16> into vector<16x16xf16>2160  // CHECK: return %[[SOURCE]]2161  return %0: vector<16x16xf16>2162}2163 2164// -----2165 2166// CHECK-LABEL: extract_strided_splatlike2167//       CHECK:   %[[B:.*]] = vector.broadcast %{{.*}} f16 to vector<2x4xf16>2168//  CHECK-NEXT:   return %[[B]] : vector<2x4xf16>2169func.func @extract_strided_splatlike(%arg0: f16) -> vector<2x4xf16> {2170 %0 = vector.broadcast %arg0 : f16 to vector<16x4xf16>2171 %1 = vector.extract_strided_slice %02172  {offsets = [1, 0], sizes = [2, 4], strides = [1, 1]} :2173  vector<16x4xf16> to vector<2x4xf16>2174  return %1 : vector<2x4xf16>2175}2176 2177// -----2178 2179// CHECK-LABEL: func @insert_extract_to_broadcast2180//  CHECK-SAME: (%[[ARG0:.*]]: vector<1x1x4xf32>, %[[ARG1:.*]]: vector<4xf32>)2181//       CHECK:   %[[V0:.*]] = vector.extract %[[ARG0]][0, 0] : vector<4xf32> from vector<1x1x4xf32>2182//       CHECK:   %[[V1:.*]] = vector.broadcast %[[ARG1]] : vector<4xf32> to vector<1x1x4xf32>2183//       CHECK:   return %[[V0]], %[[V1]] : vector<4xf32>, vector<1x1x4xf32>2184func.func @insert_extract_to_broadcast(%arg0 : vector<1x1x4xf32>,2185  %arg1 : vector<4xf32>) -> (vector<4xf32>, vector<1x1x4xf32>) {2186  %0 = vector.extract %arg0[0, 0] : vector<4xf32> from vector<1x1x4xf32>2187  %1 = vector.insert %arg1, %arg0 [0, 0] : vector<4xf32> into vector<1x1x4xf32>2188  return %0, %1 : vector<4xf32>, vector<1x1x4xf32>2189}2190 2191// -----2192 2193// CHECK-LABEL: func.func @extract_splat_constant2194//   CHECK-DAG:   %[[CST1:.*]] = arith.constant 1 : i322195//   CHECK-DAG:   %[[CST0:.*]] = arith.constant dense<2.000000e+00> : vector<7xf32>2196//  CHECK-NEXT:   return %[[CST0]], %[[CST1]] : vector<7xf32>, i322197func.func @extract_splat_constant() -> (vector<7xf32>, i32) {2198  %cst = arith.constant dense<2.000000e+00> : vector<29x7xf32>2199  %cst_1 = arith.constant dense<1> : vector<4x37x9xi32>2200  %0 = vector.extract %cst[2] : vector<7xf32> from vector<29x7xf32>2201  %1 = vector.extract %cst_1[1, 4, 5] : i32 from vector<4x37x9xi32>2202  return %0, %1 : vector<7xf32>, i322203}2204 2205// -----2206 2207// CHECK-LABEL: func.func @extract_1d_constant2208//   CHECK-DAG: %[[I32CST:.*]] = arith.constant 3 : i322209//   CHECK-DAG: %[[IDXCST:.*]] = arith.constant 1 : index2210//   CHECK-DAG: %[[F32CST:.*]] = arith.constant 2.000000e+00 : f322211//  CHECK-NEXT: return %[[I32CST]], %[[IDXCST]], %[[F32CST]] : i32, index, f322212func.func @extract_1d_constant() -> (i32, index, f32) {2213  %icst = arith.constant dense<[1, 2, 3, 4]> : vector<4xi32>2214  %e = vector.extract %icst[2] : i32 from vector<4xi32>2215  %idx_cst = arith.constant dense<[0, 1, 2]> : vector<3xindex>2216  %f = vector.extract %idx_cst[1] : index from vector<3xindex>2217  %fcst = arith.constant dense<[2.000000e+00, 3.000000e+00, 4.000000e+00]> : vector<3xf32>2218  %g = vector.extract %fcst[0] : f32 from vector<3xf32>2219  return %e, %f, %g : i32, index, f322220}2221 2222// -----2223 2224// CHECK-LABEL: func.func @extract_2d_constant2225//   CHECK-DAG: %[[ACST:.*]] = arith.constant 0 : i322226//   CHECK-DAG: %[[BCST:.*]] = arith.constant 2 : i322227//   CHECK-DAG: %[[CCST:.*]] = arith.constant 3 : i322228//   CHECK-DAG: %[[DCST:.*]] = arith.constant 5 : i322229//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]] : i32, i32, i32, i322230func.func @extract_2d_constant() -> (i32, i32, i32, i32) {2231  %cst = arith.constant dense<[[0, 1, 2], [3, 4, 5]]> : vector<2x3xi32>2232  %a = vector.extract %cst[0, 0] : i32 from vector<2x3xi32>2233  %b = vector.extract %cst[0, 2] : i32 from vector<2x3xi32>2234  %c = vector.extract %cst[1, 0] : i32 from vector<2x3xi32>2235  %d = vector.extract %cst[1, 2] : i32 from vector<2x3xi32>2236  return %a, %b, %c, %d : i32, i32, i32, i322237}2238 2239// -----2240 2241// CHECK-LABEL: func.func @extract_vector_2d_constant2242//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<[0, 1, 2]> : vector<3xi32>2243//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<[3, 4, 5]> : vector<3xi32>2244//  CHECK-NEXT: return %[[ACST]], %[[BCST]] : vector<3xi32>, vector<3xi32>2245func.func @extract_vector_2d_constant() -> (vector<3xi32>, vector<3xi32>) {2246  %cst = arith.constant dense<[[0, 1, 2], [3, 4, 5]]> : vector<2x3xi32>2247  %a = vector.extract %cst[0] : vector<3xi32> from vector<2x3xi32>2248  %b = vector.extract %cst[1] : vector<3xi32> from vector<2x3xi32>2249  return %a, %b : vector<3xi32>, vector<3xi32>2250}2251 2252// -----2253 2254// CHECK-LABEL: func.func @extract_3d_constant2255//   CHECK-DAG: %[[ACST:.*]] = arith.constant 0 : i322256//   CHECK-DAG: %[[BCST:.*]] = arith.constant 1 : i322257//   CHECK-DAG: %[[CCST:.*]] = arith.constant 9 : i322258//   CHECK-DAG: %[[DCST:.*]] = arith.constant 10 : i322259//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]] : i32, i32, i32, i322260func.func @extract_3d_constant() -> (i32, i32, i32, i32) {2261  %cst = arith.constant dense<[[[0, 1], [2, 3], [4, 5]], [[6, 7], [8, 9], [10, 11]]]> : vector<2x3x2xi32>2262  %a = vector.extract %cst[0, 0, 0] : i32 from vector<2x3x2xi32>2263  %b = vector.extract %cst[0, 0, 1] : i32 from vector<2x3x2xi32>2264  %c = vector.extract %cst[1, 1, 1] : i32 from vector<2x3x2xi32>2265  %d = vector.extract %cst[1, 2, 0] : i32 from vector<2x3x2xi32>2266  return %a, %b, %c, %d : i32, i32, i32, i322267}2268 2269// -----2270 2271// CHECK-LABEL: func.func @extract_vector_3d_constant2272//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<{{\[\[0, 1\], \[2, 3\], \[4, 5\]\]}}> : vector<3x2xi32>2273//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<{{\[\[6, 7\], \[8, 9\], \[10, 11\]\]}}> : vector<3x2xi32>2274//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<[8, 9]> : vector<2xi32>2275//   CHECK-DAG: %[[DCST:.*]] = arith.constant dense<[10, 11]> : vector<2xi32>2276//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]] : vector<3x2xi32>, vector<3x2xi32>, vector<2xi32>, vector<2xi32>2277func.func @extract_vector_3d_constant() -> (vector<3x2xi32>, vector<3x2xi32>, vector<2xi32>, vector<2xi32>) {2278  %cst = arith.constant dense<[[[0, 1], [2, 3], [4, 5]], [[6, 7], [8, 9], [10, 11]]]> : vector<2x3x2xi32>2279  %a = vector.extract %cst[0] : vector<3x2xi32> from vector<2x3x2xi32>2280  %b = vector.extract %cst[1] : vector<3x2xi32> from vector<2x3x2xi32>2281  %c = vector.extract %cst[1, 1] : vector<2xi32> from vector<2x3x2xi32>2282  %d = vector.extract %cst[1, 2] : vector<2xi32> from vector<2x3x2xi32>2283  return %a, %b, %c, %d : vector<3x2xi32>, vector<3x2xi32>, vector<2xi32>, vector<2xi32>2284}2285 2286// -----2287 2288// CHECK-LABEL: func.func @extract_splat_vector_3d_constant2289//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<0> : vector<2xi32>2290//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<4> : vector<2xi32>2291//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<5> : vector<2xi32>2292//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]] : vector<2xi32>, vector<2xi32>, vector<2xi32>2293func.func @extract_splat_vector_3d_constant() -> (vector<2xi32>, vector<2xi32>, vector<2xi32>) {2294  %cst = arith.constant dense<[[[0, 0], [1, 1], [2, 2]], [[3, 3], [4, 4], [5, 5]]]> : vector<2x3x2xi32>2295  %a = vector.extract %cst[0, 0] : vector<2xi32> from vector<2x3x2xi32>2296  %b = vector.extract %cst[1, 1] : vector<2xi32> from vector<2x3x2xi32>2297  %c = vector.extract %cst[1, 2] : vector<2xi32> from vector<2x3x2xi32>2298  return %a, %b, %c : vector<2xi32>, vector<2xi32>, vector<2xi32>2299}2300 2301// -----2302 2303// CHECK-LABEL: func.func @extract_strided_slice_1d_constant2304//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<[0, 1, 2]> : vector<3xi32>2305//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<[1, 2]> : vector<2xi32>2306//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<2> : vector<1xi32>2307//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]] : vector<3xi32>, vector<2xi32>, vector<1xi32>2308func.func @extract_strided_slice_1d_constant() -> (vector<3xi32>, vector<2xi32>, vector<1xi32>) {2309  %cst = arith.constant dense<[0, 1, 2]> : vector<3xi32>2310  %a = vector.extract_strided_slice %cst2311   {offsets = [0], sizes = [3], strides = [1]} : vector<3xi32> to vector<3xi32>2312  %b = vector.extract_strided_slice %cst2313   {offsets = [1], sizes = [2], strides = [1]} : vector<3xi32> to vector<2xi32>2314  %c = vector.extract_strided_slice %cst2315   {offsets = [2], sizes = [1], strides = [1]} : vector<3xi32> to vector<1xi32>2316  return %a, %b, %c : vector<3xi32>, vector<2xi32>, vector<1xi32>2317}2318 2319// -----2320 2321// CHECK-LABEL: func.func @extract_strided_slice_2d_constant2322//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<0> : vector<1x1xi32>2323//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<{{\[\[4, 5\]\]}}> : vector<1x2xi32>2324//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<{{\[\[1, 2\], \[4, 5\]\]}}> : vector<2x2xi32>2325//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]] : vector<1x1xi32>, vector<1x2xi32>, vector<2x2xi32>2326func.func @extract_strided_slice_2d_constant() -> (vector<1x1xi32>, vector<1x2xi32>, vector<2x2xi32>) {2327  %cst = arith.constant dense<[[0, 1, 2], [3, 4, 5]]> : vector<2x3xi32>2328  %a = vector.extract_strided_slice %cst2329   {offsets = [0, 0], sizes = [1, 1], strides = [1, 1]} : vector<2x3xi32> to vector<1x1xi32>2330  %b = vector.extract_strided_slice %cst2331   {offsets = [1, 1], sizes = [1, 2], strides = [1, 1]} : vector<2x3xi32> to vector<1x2xi32>2332  %c = vector.extract_strided_slice %cst2333   {offsets = [0, 1], sizes = [2, 2], strides = [1, 1]} : vector<2x3xi32> to vector<2x2xi32>2334  return %a, %b, %c : vector<1x1xi32>, vector<1x2xi32>, vector<2x2xi32>2335}2336 2337// -----2338 2339// CHECK-LABEL: func.func @extract_strided_slice_3d_constant2340//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<{{\[\[\[8, 9\], \[10, 11\]\]\]}}> : vector<1x2x2xi32>2341//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<{{\[\[\[2, 3\]\]\]}}> : vector<1x1x2xi32>2342//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<{{\[\[\[6, 7\]\], \[\[10, 11\]\]\]}}> : vector<2x1x2xi32>2343//   CHECK-DAG: %[[DCST:.*]] = arith.constant dense<11> : vector<1x1x1xi32>2344//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]]2345func.func @extract_strided_slice_3d_constant() -> (vector<1x2x2xi32>, vector<1x1x2xi32>, vector<2x1x2xi32>, vector<1x1x1xi32>) {2346  %cst = arith.constant dense<[[[0, 1], [2, 3]], [[4, 5], [6, 7]], [[8, 9], [10, 11]]]> : vector<3x2x2xi32>2347  %a = vector.extract_strided_slice %cst2348   {offsets = [2], sizes = [1], strides = [1]} : vector<3x2x2xi32> to vector<1x2x2xi32>2349  %b = vector.extract_strided_slice %cst2350   {offsets = [0, 1], sizes = [1, 1], strides = [1, 1]} : vector<3x2x2xi32> to vector<1x1x2xi32>2351  %c = vector.extract_strided_slice %cst2352   {offsets = [1, 1, 0], sizes = [2, 1, 2], strides = [1, 1, 1]} : vector<3x2x2xi32> to vector<2x1x2xi32>2353  %d = vector.extract_strided_slice %cst2354   {offsets = [2, 1, 1], sizes = [1, 1, 1], strides = [1, 1, 1]} : vector<3x2x2xi32> to vector<1x1x1xi32>2355  return %a, %b, %c, %d : vector<1x2x2xi32>, vector<1x1x2xi32>, vector<2x1x2xi32>, vector<1x1x1xi32>2356}2357 2358// -----2359 2360// CHECK-LABEL: extract_extract_strided2361//  CHECK-SAME: %[[A:.*]]: vector<32x16x4xf16>2362//       CHECK: %[[V:.*]] = vector.extract %[[A]][9, 7] : vector<4xf16> from vector<32x16x4xf16>2363//       CHECK: return %[[V]] : vector<4xf16>2364func.func @extract_extract_strided(%arg0: vector<32x16x4xf16>) -> vector<4xf16> {2365 %1 = vector.extract_strided_slice %arg02366  {offsets = [7, 3], sizes = [10, 8], strides = [1, 1]} :2367  vector<32x16x4xf16> to vector<10x8x4xf16>2368  %2 = vector.extract %1[2, 4] : vector<4xf16> from vector<10x8x4xf16>2369  return %2 : vector<4xf16>2370}2371 2372// -----2373 2374// CHECK-LABEL: extract_insert_strided2375//  CHECK-SAME: %[[A:.*]]: vector<6x4xf32>2376//       CHECK: %[[V:.*]] = vector.extract %[[A]][0, 2] : f32 from vector<6x4xf32>2377//       CHECK: return %[[V]] : f322378func.func @extract_insert_strided(%a: vector<6x4xf32>, %b: vector<8x16xf32>)2379  -> f32 {2380  %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1, 1]}2381    : vector<6x4xf32> into vector<8x16xf32>2382  %2 = vector.extract %0[2, 4] : f32 from vector<8x16xf32>2383  return %2 : f322384}2385 2386// -----2387 2388// CHECK-LABEL: extract_insert_rank_reduce2389//  CHECK-SAME: %[[A:.*]]: vector<4xf32>2390//       CHECK: %[[V:.*]] = vector.extract %[[A]][2] : f32 from vector<4xf32>2391//       CHECK: return %[[V]] : f322392func.func @extract_insert_rank_reduce(%a: vector<4xf32>, %b: vector<8x16xf32>)2393  -> f32 {2394  %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1]}2395    : vector<4xf32> into vector<8x16xf32>2396  %2 = vector.extract %0[2, 4] : f32 from vector<8x16xf32>2397  return %2 : f322398}2399 2400// -----2401 2402// CHECK-LABEL: negative_extract_insert2403//       CHECK: vector.insert_strided_slice2404//       CHECK: vector.extract2405func.func @negative_extract_insert(%a: vector<2x15xf32>, %b: vector<12x8x16xf32>)2406  -> vector<16xf32> {2407  %0 = vector.insert_strided_slice %a, %b {offsets = [4, 2, 0], strides = [1, 1]}2408    : vector<2x15xf32> into vector<12x8x16xf32>2409  %2 = vector.extract %0[4, 2] : vector<16xf32> from vector<12x8x16xf32>2410  return %2 : vector<16xf32>2411}2412 2413// -----2414 2415// CHECK-LABEL: extract_insert_chain2416//  CHECK-SAME: (%[[A:.*]]: vector<2x16xf32>, %[[B:.*]]: vector<12x8x16xf32>, %[[C:.*]]: vector<2x16xf32>)2417//       CHECK: %[[V:.*]] = vector.extract %[[C]][0] : vector<16xf32> from vector<2x16xf32>2418//       CHECK: return %[[V]] : vector<16xf32>2419func.func @extract_insert_chain(%a: vector<2x16xf32>, %b: vector<12x8x16xf32>, %c: vector<2x16xf32>)2420  -> vector<16xf32> {2421  %0 = vector.insert_strided_slice %c, %b {offsets = [4, 2, 0], strides = [1, 1]}2422    : vector<2x16xf32> into vector<12x8x16xf32>2423  %1 = vector.insert_strided_slice %a, %0 {offsets = [0, 2, 0], strides = [1, 1]}2424    : vector<2x16xf32> into vector<12x8x16xf32>2425  %2 = vector.extract %1[4, 2] : vector<16xf32> from vector<12x8x16xf32>2426  return %2 : vector<16xf32>2427}2428 2429// -----2430 2431// CHECK-LABEL: extract_from_extract_chain_should_not_fold_dynamic_extracts2432//  CHECK-SAME: (%[[VEC:.*]]: vector<2x4xf32>, %[[IDX:.*]]: index)2433//       CHECK: %[[A:.*]] = vector.extract %[[VEC]][%[[IDX]]] : vector<4xf32> from vector<2x4xf32>2434//       CHECK: %[[B:.*]] = vector.extract %[[A]][1] : f32 from vector<4xf32>2435func.func @extract_from_extract_chain_should_not_fold_dynamic_extracts(%v: vector<2x4xf32>, %index: index) -> f32 {2436  %0 = vector.extract %v[%index] : vector<4xf32> from vector<2x4xf32>2437  %1 = vector.extract %0[1] : f32 from vector<4xf32>2438  return %1 : f322439}2440 2441// -----2442 2443// CHECK-LABEL: extract_extract_strided22444//  CHECK-SAME: %[[A:.*]]: vector<2x4xf32>2445//       CHECK: %[[V:.*]] = vector.extract %[[A]][1] : vector<4xf32> from vector<2x4xf32>2446//       CHECK: return %[[V]] : vector<4xf32>2447func.func @extract_extract_strided2(%A: vector<2x4xf32>)2448  -> (vector<4xf32>) {2449 %0 = vector.extract_strided_slice %A {offsets = [1, 0], sizes = [1, 4], strides = [1, 1]} : vector<2x4xf32> to vector<1x4xf32>2450 %1 = vector.extract %0[0] : vector<4xf32> from vector<1x4xf32>2451 return %1 : vector<4xf32>2452}2453 2454// -----2455 2456// CHECK-LABEL: func @splatlike_fold2457//  CHECK-NEXT: [[V:%.*]] = arith.constant dense<1.000000e+00> : vector<4xf32>2458//  CHECK-NEXT: return [[V]] : vector<4xf32>2459func.func @splatlike_fold() -> vector<4xf32> {2460  %c = arith.constant 1.0 : f322461  %v = vector.broadcast %c : f32 to vector<4xf32>2462  return %v : vector<4xf32>2463 2464}2465 2466// -----2467 2468// CHECK-LABEL: func @shuffle_1d2469//       CHECK:   %[[V:.+]] = arith.constant dense<[3, 2, 5, 1]> : vector<4xi32>2470//       CHECK:   return %[[V]]2471func.func @shuffle_1d() -> vector<4xi32> {2472  %v0 = arith.constant dense<[0, 1, 2]> : vector<3xi32>2473  %v1 = arith.constant dense<[3, 4, 5]> : vector<3xi32>2474  %shuffle = vector.shuffle %v0, %v1 [3, 2, 5, 1] : vector<3xi32>, vector<3xi32>2475  return %shuffle : vector<4xi32>2476}2477 2478// -----2479 2480// Ensure shuffle dense resource elements not crash.2481 2482// CHECK-LABEL: func.func @shuffle_1d_dense_resource2483//       CHECK:    vector.shuffle2484func.func @shuffle_1d_dense_resource() -> vector<4xi32> {2485  %v0 = arith.constant dense_resource<__elided__> : vector<3xi32>2486  %v1 = arith.constant dense_resource<__elided__> : vector<3xi32>2487  %shuffle = vector.shuffle %v0, %v1 [3, 2, 5, 1] : vector<3xi32>, vector<3xi32>2488  return %shuffle : vector<4xi32>2489}2490 2491// -----2492 2493// Check that poison indices pick the first element of the first non-poison2494// input vector. That is, %v[0] (i.e., 5) in this test.2495 2496// CHECK-LABEL: func @shuffle_1d_poison_idx2497//       CHECK:   %[[V:.+]] = arith.constant dense<[13, 10, 15, 10]> : vector<4xi32>2498//       CHECK:   return %[[V]]2499func.func @shuffle_1d_poison_idx() -> vector<4xi32> {2500  %v0 = arith.constant dense<[10, 11, 12]> : vector<3xi32>2501  %v1 = arith.constant dense<[13, 14, 15]> : vector<3xi32>2502  %shuffle = vector.shuffle %v0, %v1 [3, -1, 5, -1] : vector<3xi32>, vector<3xi32>2503  return %shuffle : vector<4xi32>2504}2505 2506// -----2507 2508// CHECK-LABEL: func @shuffle_1d_rhs_lhs_poison2509//   CHECK-NOT:   vector.shuffle2510//       CHECK:   %[[V:.+]] = ub.poison : vector<4xi32>2511//       CHECK:   return %[[V]]2512func.func @shuffle_1d_rhs_lhs_poison() -> vector<4xi32> {2513  %v0 = ub.poison : vector<3xi32>2514  %v1 = ub.poison : vector<3xi32>2515  %shuffle = vector.shuffle %v0, %v1 [3, 1, 5, 4] : vector<3xi32>, vector<3xi32>2516  return %shuffle : vector<4xi32>2517}2518 2519// -----2520 2521// CHECK-LABEL: func @shuffle_1d_lhs_poison2522//   CHECK-NOT:   vector.shuffle2523//       CHECK:   %[[V:.+]] = arith.constant dense<[11, 12, 11, 11]> : vector<4xi32>2524//       CHECK:   return %[[V]]2525func.func @shuffle_1d_lhs_poison() -> vector<4xi32> {2526  %v0 = arith.constant dense<[11, 12, 13]> : vector<3xi32>2527  %v1 = ub.poison : vector<3xi32>2528  %shuffle = vector.shuffle %v0, %v1 [3, 1, 5, 4] : vector<3xi32>, vector<3xi32>2529  return %shuffle : vector<4xi32>2530}2531 2532// -----2533 2534// CHECK-LABEL: func @shuffle_1d_rhs_poison2535//   CHECK-NOT:   vector.shuffle2536//       CHECK:   %[[V:.+]] = arith.constant dense<[11, 11, 13, 12]> : vector<4xi32>2537//       CHECK:   return %[[V]]2538func.func @shuffle_1d_rhs_poison() -> vector<4xi32> {2539  %v0 = ub.poison : vector<3xi32>2540  %v1 = arith.constant dense<[11, 12, 13]> : vector<3xi32>2541  %shuffle = vector.shuffle %v0, %v1 [3, 1, 5, 4] : vector<3xi32>, vector<3xi32>2542  return %shuffle : vector<4xi32>2543}2544 2545// -----2546 2547// CHECK-LABEL: func @shuffle_canonicalize_0d2548func.func @shuffle_canonicalize_0d(%v0 : vector<i32>, %v1 : vector<i32>) -> vector<1xi32> {2549  // CHECK: vector.broadcast %{{.*}} : vector<i32> to vector<1xi32>2550  %shuffle = vector.shuffle %v0, %v1 [0] : vector<i32>, vector<i32>2551  return %shuffle : vector<1xi32>2552}2553 2554// -----2555 2556// CHECK-LABEL: func @shuffle_fold12557//       CHECK:   %arg0 : vector<4xi32>2558func.func @shuffle_fold1(%v0 : vector<4xi32>, %v1 : vector<2xi32>) -> vector<4xi32> {2559  %shuffle = vector.shuffle %v0, %v1 [0, 1, 2, 3] : vector<4xi32>, vector<2xi32>2560  return %shuffle : vector<4xi32>2561}2562 2563// -----2564 2565// CHECK-LABEL: func @shuffle_fold22566//       CHECK:   %arg1 : vector<2xi32>2567func.func @shuffle_fold2(%v0 : vector<4xi32>, %v1 : vector<2xi32>) -> vector<2xi32> {2568  %shuffle = vector.shuffle %v0, %v1 [4, 5] : vector<4xi32>, vector<2xi32>2569  return %shuffle : vector<2xi32>2570}2571 2572// -----2573 2574// CHECK-LABEL: func @shuffle_fold32575//       CHECK:   return %arg0 : vector<4x5x6xi32>2576func.func @shuffle_fold3(%v0 : vector<4x5x6xi32>, %v1 : vector<2x5x6xi32>) -> vector<4x5x6xi32> {2577  %shuffle = vector.shuffle %v0, %v1 [0, 1, 2, 3] : vector<4x5x6xi32>, vector<2x5x6xi32>2578  return %shuffle : vector<4x5x6xi32>2579}2580 2581// -----2582 2583// CHECK-LABEL: func @shuffle_fold42584//       CHECK:   return %arg1 : vector<2x5x6xi32>2585func.func @shuffle_fold4(%v0 : vector<4x5x6xi32>, %v1 : vector<2x5x6xi32>) -> vector<2x5x6xi32> {2586  %shuffle = vector.shuffle %v0, %v1 [4, 5] : vector<4x5x6xi32>, vector<2x5x6xi32>2587  return %shuffle : vector<2x5x6xi32>2588}2589 2590// -----2591 2592// CHECK-LABEL: func @shuffle_nofold12593//       CHECK:   %[[V:.+]] = vector.shuffle %arg0, %arg1 [0, 1, 2, 3, 4] : vector<4xi32>, vector<2xi32>2594//       CHECK:   return %[[V]]2595func.func @shuffle_nofold1(%v0 : vector<4xi32>, %v1 : vector<2xi32>) -> vector<5xi32> {2596  %shuffle = vector.shuffle %v0, %v1 [0, 1, 2, 3, 4] : vector<4xi32>, vector<2xi32>2597  return %shuffle : vector<5xi32>2598}2599 2600// -----2601 2602// CHECK-LABEL: func @transpose_splatlike_constant2603//       CHECK:   %[[CST:.+]] = arith.constant dense<5.000000e+00> : vector<8x4xf32>2604//       CHECK:   return %[[CST]]2605func.func @transpose_splatlike_constant() -> vector<8x4xf32> {2606  %cst = arith.constant dense<5.0> : vector<4x8xf32>2607  %0 = vector.transpose %cst, [1, 0] : vector<4x8xf32> to vector<8x4xf32>2608  return %0 : vector<8x4xf32>2609}2610 2611// -----2612 2613// CHECK-LABEL:   func @transpose_splatlike2(2614//  CHECK-SAME:     %[[VAL_0:.*]]: f32) -> vector<3x4xf32> {2615//       CHECK:     %[[VAL_1:.*]] = vector.broadcast %[[VAL_0]] : f32 to vector<3x4xf32>2616//       CHECK:     return %[[VAL_1]] : vector<3x4xf32>2617//       CHECK:     }2618func.func @transpose_splatlike2(%arg : f32) -> vector<3x4xf32> {2619  %splat = vector.broadcast %arg : f32 to vector<4x3xf32>2620  %0 = vector.transpose %splat, [1, 0] : vector<4x3xf32> to vector<3x4xf32>2621  return %0 : vector<3x4xf32>2622}2623 2624// -----2625 2626// CHECK-LABEL: transpose_poison2627//       CHECK:  %[[POISON:.*]] = ub.poison : vector<4x6xi8>2628//       CHECK:  return %[[POISON]] : vector<4x6xi8>2629func.func @transpose_poison() -> vector<4x6xi8> {2630  %poison = ub.poison : vector<6x4xi8>2631  %transpose = vector.transpose %poison, [1, 0] : vector<6x4xi8> to vector<4x6xi8>2632  return %transpose : vector<4x6xi8>2633}2634 2635// -----2636 2637// CHECK-LABEL: func.func @insert_1d_constant2638//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<[9, 1, 2]> : vector<3xi32>2639//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<[0, 9, 2]> : vector<3xi32>2640//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<[0, 1, 9]> : vector<3xi32>2641//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]] : vector<3xi32>, vector<3xi32>, vector<3xi32>2642func.func @insert_1d_constant() -> (vector<3xi32>, vector<3xi32>, vector<3xi32>) {2643  %vcst = arith.constant dense<[0, 1, 2]> : vector<3xi32>2644  %icst = arith.constant 9 : i322645  %a = vector.insert %icst, %vcst[0] : i32 into vector<3xi32>2646  %b = vector.insert %icst, %vcst[1] : i32 into vector<3xi32>2647  %c = vector.insert %icst, %vcst[2] : i32 into vector<3xi32>2648  return %a, %b, %c : vector<3xi32>, vector<3xi32>, vector<3xi32>2649}2650 2651// -----2652 2653// CHECK-LABEL: func.func @insert_2d_constant2654//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<{{\[\[99, 1, 2\], \[3, 4, 5\]\]}}> : vector<2x3xi32>2655//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<{{\[\[0, 1, 2\], \[3, 4, 99\]\]}}> : vector<2x3xi32>2656//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<{{\[\[90, 91, 92\], \[3, 4, 5\]\]}}> : vector<2x3xi32>2657//   CHECK-DAG: %[[DCST:.*]] = arith.constant dense<{{\[\[0, 1, 2\], \[90, 91, 92\]\]}}> : vector<2x3xi32>2658//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]]2659func.func @insert_2d_constant() -> (vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>) {2660  %vcst = arith.constant dense<[[0, 1, 2], [3, 4, 5]]> : vector<2x3xi32>2661  %cst_scalar = arith.constant 99 : i322662  %cst_1d = arith.constant dense<[90, 91, 92]> : vector<3xi32>2663  %a = vector.insert %cst_scalar, %vcst[0, 0] : i32 into vector<2x3xi32>2664  %b = vector.insert %cst_scalar, %vcst[1, 2] : i32 into vector<2x3xi32>2665  %c = vector.insert %cst_1d, %vcst[0] : vector<3xi32> into vector<2x3xi32>2666  %d = vector.insert %cst_1d, %vcst[1] : vector<3xi32> into vector<2x3xi32>2667  return %a, %b, %c, %d : vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>2668}2669 2670// -----2671 2672// +---------------------------------------------------------------------------2673// Tests for InsertChainFullyInitialized .2674// +---------------------------------------------------------------------------2675// This pattern should fire when all vector elements are overwritten by vector.insert2676// at static positions, replacing the insert chain with vector.from_elements.2677// CHECK-LABEL: func.func @fully_insert_scalar_to_vector(2678//  CHECK-SAME: %[[DEST:.+]]: vector<2xi64>, %[[SRC1:.+]]: i64, %[[SRC2:.+]]: i64)2679//       CHECK: %[[RES:.+]] = vector.from_elements %[[SRC1]], %[[SRC2]] : vector<2xi64>2680//  CHECK-NEXT: return %[[RES]]2681func.func @fully_insert_scalar_to_vector(%dest : vector<2xi64>, %src1 : i64, %src2 : i64) -> vector<2xi64> {2682  %v1 = vector.insert %src1, %dest[0] : i64 into vector<2xi64>2683  %v2 = vector.insert %src2, %v1[1] : i64 into vector<2xi64>2684  return %v2 : vector<2xi64>2685}2686 2687// -----2688 2689// Same as the above test, but with vector insertions.2690// CHECK-LABEL: func.func @fully_insert_vector_to_vector(2691//  CHECK-SAME: %[[DEST:.+]]: vector<2x2xi64>, %[[SRC1:.+]]: vector<2xi64>, %[[SRC2:.+]]: vector<2xi64>)2692//       CHECK: %[[ELE1:.+]]:2 = vector.to_elements %[[SRC1]] : vector<2xi64>2693//       CHECK: %[[ELE2:.+]]:2 = vector.to_elements %[[SRC2]] : vector<2xi64>2694//       CHECK: %[[RES:.+]] = vector.from_elements %[[ELE1]]#0, %[[ELE1]]#1, %[[ELE2]]#0, %[[ELE2]]#1 : vector<2x2xi64>2695//  CHECK-NEXT: return %[[RES]]2696func.func @fully_insert_vector_to_vector(%dest : vector<2x2xi64>, %src1 : vector<2xi64>, %src2 : vector<2xi64>) -> vector<2x2xi64> {2697  %v1 = vector.insert %src1, %dest[0] : vector<2xi64> into vector<2x2xi64>2698  %v2 = vector.insert %src2, %v1[1] : vector<2xi64> into vector<2x2xi64>2699  return %v2 : vector<2x2xi64>2700}2701 2702// -----2703 2704// Test InsertChainFullyInitialized pattern with overlapping insertions.2705// 1. The first op inserts %src2 at [0,0].2706// 2. The second op inserts %src1 at [0,0], [0,1], overwriting %src2 at [0,0].2707// 3. The third op inserts %src1 at [1,0], [1,1].2708// 4. The fourth op inserts %src2 at [1,1], overwriting the existing value at [1,1].2709// CHECK-LABEL: func.func @fully_insert_to_vector_overlap_1(2710//  CHECK-SAME: %[[DEST:.+]]: vector<2x2xi64>, %[[SRC1:.+]]: vector<2xi64>, %[[SRC2:.+]]: i64)2711//       CHECK: %[[ELE1:.+]]:2 = vector.to_elements %[[SRC1]] : vector<2xi64>2712//       CHECK: %[[ELE2:.+]]:2 = vector.to_elements %[[SRC1]] : vector<2xi64>2713//       CHECK: %[[RES:.+]] = vector.from_elements %[[ELE1]]#0, %[[ELE1]]#1, %[[ELE2]]#0, %[[SRC2]] : vector<2x2xi64>2714//  CHECK-NEXT: return %[[RES]]2715func.func @fully_insert_to_vector_overlap_1(%dest : vector<2x2xi64>, %src1 : vector<2xi64>, %src2 : i64) -> vector<2x2xi64> {2716  %v0 = vector.insert %src2, %dest[0, 0] : i64 into vector<2x2xi64>2717  %v1 = vector.insert %src1, %v0[0] : vector<2xi64> into vector<2x2xi64>2718  %v2 = vector.insert %src1, %v1[1] : vector<2xi64> into vector<2x2xi64>2719  %v3 = vector.insert %src2, %v2[1, 1] : i64 into vector<2x2xi64>2720  return %v3 : vector<2x2xi64>2721}2722 2723// -----2724 2725// Test InsertChainFullyInitialized pattern with overlapping insertions.2726// The vector inserted at last should overwrite the previously inserted scalars.2727// CHECK-LABEL: func.func @fully_insert_to_vector_overlap_2(2728//  CHECK-SAME: %[[DEST:.+]]: vector<2x2xi64>, %[[SRC1:.+]]: i64, %[[SRC2:.+]]: i64, %[[SRC3:.+]]: vector<2xi64>, %[[SRC4:.+]]: vector<2xi64>)2729//       CHECK: %[[ELE1:.+]]:2 = vector.to_elements %[[SRC3]] : vector<2xi64>2730//       CHECK: %[[ELE2:.+]]:2 = vector.to_elements %[[SRC4]] : vector<2xi64>2731//       CHECK: %[[RES:.+]] = vector.from_elements %[[ELE1]]#0, %[[ELE1]]#1, %[[ELE2]]#0, %[[ELE2]]#1 : vector<2x2xi64>2732//  CHECK-NEXT: return %[[RES]]2733func.func @fully_insert_to_vector_overlap_2(%dest : vector<2x2xi64>, %src1 : i64, %src2 : i64, %src3 : vector<2xi64>, %src4 : vector<2xi64>) -> vector<2x2xi64> {2734  %v0 = vector.insert %src1, %dest[0, 0] : i64 into vector<2x2xi64>2735  %v1 = vector.insert %src2, %v0[0, 1] : i64 into vector<2x2xi64>2736  %v2 = vector.insert %src3, %v1[0] : vector<2xi64> into vector<2x2xi64>2737  %v3 = vector.insert %src4, %v2[1] : vector<2xi64> into vector<2x2xi64>2738  return %v3 : vector<2x2xi64>2739}2740 2741// -----2742 2743// Negative test for InsertChainFullyInitialized pattern when only some elements are overwritten.2744// CHECK-LABEL: func.func @negative_partially_insert_vector_to_vector(2745//  CHECK-SAME: %[[DEST:.+]]: vector<2x2xi64>, %[[SRC1:.+]]: vector<2xi64>, %[[SRC2:.+]]: i64)2746//       CHECK: %[[V0:.+]] = vector.insert %[[SRC1]], %[[DEST]] [0] : vector<2xi64> into vector<2x2xi64>2747//       CHECK: %[[V1:.+]] = vector.insert %[[SRC2]], %[[V0]] [0, 0] : i64 into vector<2x2xi64>2748//       CHECK: return %[[V1]]2749func.func @negative_partially_insert_vector_to_vector(%dest : vector<2x2xi64>, %src1 : vector<2xi64>, %src2 : i64) -> vector<2x2xi64> {2750  %v1 = vector.insert %src1, %dest[0] : vector<2xi64> into vector<2x2xi64>2751  %v2 = vector.insert %src2, %v1[0, 0] : i64 into vector<2x2xi64>2752  return %v2 : vector<2x2xi64>2753}2754 2755// -----2756 2757// Negative test when intermediate results have more than one user.2758// CHECK-LABEL: func.func @negative_intermediate_insert_multiple_users(2759//  CHECK-SAME: %[[DEST:.+]]: vector<3xi64>, %[[SRC1:.+]]: i64, %[[SRC2:.+]]: i64, %[[SRC3:.+]]: i64, %[[SRC4:.+]]: i64)2760//       CHECK: %[[V0:.+]] = vector.insert %[[SRC1]], %[[DEST]] [0] : i64 into vector<3xi64>2761//       CHECK: %[[V1:.+]] = vector.insert %[[SRC2]], %[[V0]] [1] : i64 into vector<3xi64>2762//       CHECK: %[[V2:.+]] = vector.insert %[[SRC3]], %[[V1]] [2] : i64 into vector<3xi64>2763//       CHECK: %[[V3:.+]] = vector.insert %[[SRC4]], %[[V1]] [2] : i64 into vector<3xi64>2764func.func @negative_intermediate_insert_multiple_users(%dest : vector<3xi64>, %src1 : i64, %src2 : i64, %src3 : i64, %src4 : i64) -> (vector<3xi64>, vector<3xi64>) {2765  %v1 = vector.insert %src1, %dest[0] : i64 into vector<3xi64>2766  %v2 = vector.insert %src2, %v1[1] : i64 into vector<3xi64>2767  %v3_0 = vector.insert %src3, %v2[2] : i64 into vector<3xi64>2768  %v3_1 = vector.insert %src4, %v2[2] : i64 into vector<3xi64>2769  return %v3_0, %v3_1 : vector<3xi64>, vector<3xi64>2770}2771 2772// +---------------------------------------------------------------------------2773// End of  Tests For InsertChainFullyInitialized.2774// +---------------------------------------------------------------------------2775 2776// -----2777 2778// CHECK-LABEL: func.func @insert_2d_splat_constant2779//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<0> : vector<2x3xi32>2780//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<{{\[\[99, 0, 0\], \[0, 0, 0\]\]}}> : vector<2x3xi32>2781//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<{{\[\[0, 0, 0\], \[0, 99, 0\]\]}}> : vector<2x3xi32>2782//   CHECK-DAG: %[[DCST:.*]] = arith.constant dense<{{\[\[33, 33, 33\], \[0, 0, 0\]\]}}> : vector<2x3xi32>2783//   CHECK-DAG: %[[ECST:.*]] = arith.constant dense<{{\[\[0, 0, 0\], \[33, 33, 33\]\]}}> : vector<2x3xi32>2784//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]], %[[ECST]]2785func.func @insert_2d_splat_constant()2786  -> (vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>) {2787  %vcst = arith.constant dense<0> : vector<2x3xi32>2788  %cst_zero = arith.constant 0 : i322789  %cst_scalar = arith.constant 99 : i322790  %cst_1d = arith.constant dense<33> : vector<3xi32>2791  %a = vector.insert %cst_zero, %vcst[0, 0] : i32 into vector<2x3xi32>2792  %b = vector.insert %cst_scalar, %vcst[0, 0] : i32 into vector<2x3xi32>2793  %c = vector.insert %cst_scalar, %vcst[1, 1] : i32 into vector<2x3xi32>2794  %d = vector.insert %cst_1d, %vcst[0] : vector<3xi32> into vector<2x3xi32>2795  %e = vector.insert %cst_1d, %vcst[1] : vector<3xi32> into vector<2x3xi32>2796  return %a, %b, %c, %d, %e : vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>, vector<2x3xi32>2797}2798 2799// -----2800 2801// CHECK-LABEL: func @reduce_one_element_vector_extract2802//  CHECK-SAME: (%[[V:.+]]: vector<1xf32>)2803//       CHECK:   %[[S:.+]] = vector.extract %[[V]][0] : f32 from vector<1xf32>2804//       CHECK:   return %[[S]] : f322805func.func @reduce_one_element_vector_extract(%a : vector<1xf32>) -> f32 {2806  %s = vector.reduction <add>, %a : vector<1xf32> into f322807  return %s : f322808}2809 2810// -----2811 2812// CHECK-LABEL: func @masked_reduce_one_element_vector_extract2813//  CHECK-SAME: %[[VAL_0:.*]]: vector<1xf32>, %[[VAL_1:.*]]: vector<1xi1>)2814func.func @masked_reduce_one_element_vector_extract(%a : vector<1xf32>, %mask : vector<1xi1>) -> f32 {2815//       CHECK:   %[[VAL_2:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<1xf32>2816  %s = vector.mask %mask { vector.reduction <add>, %a : vector<1xf32> into f32 }2817         : vector<1xi1> -> f322818  return %s : f322819}2820 2821// -----2822 2823// CHECK-LABEL: func @reduce_one_element_vector_addf2824//  CHECK-SAME: (%[[V:.+]]: vector<1xf32>, %[[B:.+]]: f32)2825//       CHECK:   %[[A:.+]] = vector.extract %[[V]][0] : f32 from vector<1xf32>2826//       CHECK:   %[[S:.+]] = arith.addf %[[A]], %arg1 : f322827//       CHECK:   return %[[S]]2828func.func @reduce_one_element_vector_addf(%a : vector<1xf32>, %b: f32) -> f32 {2829  %s = vector.reduction <add>, %a, %b : vector<1xf32> into f322830  return %s : f322831}2832 2833// -----2834 2835// CHECK-LABEL: func @reduce_one_element_vector_addf_fastmath2836//  CHECK-SAME: (%[[V:.+]]: vector<1xf32>, %[[B:.+]]: f32)2837//       CHECK:   %[[A:.+]] = vector.extract %[[V]][0] : f32 from vector<1xf32>2838//       CHECK:   %[[S:.+]] = arith.addf %[[A]], %arg1 fastmath<nnan,ninf> : f322839//       CHECK:   return %[[S]]2840func.func @reduce_one_element_vector_addf_fastmath(%a : vector<1xf32>, %b: f32) -> f32 {2841  %s = vector.reduction <add>, %a, %b fastmath<nnan,ninf> : vector<1xf32> into f322842  return %s : f322843}2844 2845// -----2846 2847// CHECK-LABEL: func @masked_reduce_one_element_vector_addf2848//  CHECK-SAME: %[[VAL_0:.*]]: vector<1xf32>, %[[VAL_1:.*]]: f32,2849//  CHECK-SAME: %[[VAL_2:.*]]: vector<1xi1>)2850func.func @masked_reduce_one_element_vector_addf(%a: vector<1xf32>,2851                                                 %b: f32,2852                                                 %mask: vector<1xi1>) -> f32 {2853//       CHECK:   %[[VAL_3:.*]] = vector.extract %[[VAL_2]][0] : i1 from vector<1xi1>2854//       CHECK:   %[[VAL_4:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<1xf32>2855//       CHECK:   %[[VAL_5:.*]] = arith.addf %[[VAL_4]], %[[VAL_1]] : f322856//       CHECK:   %[[VAL_6:.*]] = arith.select %[[VAL_3]], %[[VAL_5]], %[[VAL_1]] : f322857  %s = vector.mask %mask { vector.reduction <add>, %a, %b : vector<1xf32> into f32 }2858         : vector<1xi1> -> f322859  return %s : f322860}2861 2862// -----2863 2864// CHECK-LABEL: func @reduce_one_element_vector_mulf2865//  CHECK-SAME: (%[[V:.+]]: vector<1xf32>, %[[B:.+]]: f32)2866//       CHECK:   %[[A:.+]] = vector.extract %[[V]][0] : f32 from vector<1xf32>2867//       CHECK:   %[[S:.+]] = arith.mulf %[[A]], %arg1 : f322868//       CHECK:   return %[[S]]2869func.func @reduce_one_element_vector_mulf(%a : vector<1xf32>, %b: f32) -> f32 {2870  %s = vector.reduction <mul>, %a, %b : vector<1xf32> into f322871  return %s : f322872}2873 2874// -----2875 2876// CHECK-LABEL: func @dont_reduce_one_element_vector2877//       CHECK: vector.reduction2878func.func @dont_reduce_one_element_vector(%a : vector<4xf32>) -> f32 {2879  %s = vector.reduction <add>, %a : vector<4xf32> into f322880  return %s : f322881}2882 2883// -----2884 2885// CHECK-LABEL: func @reduce_one_element_vector_maximumf2886//  CHECK-SAME: (%[[V:.+]]: vector<1xf32>, %[[B:.+]]: f32)2887//       CHECK:   %[[A:.+]] = vector.extract %[[V]][0] : f32 from vector<1xf32>2888//       CHECK:   %[[S:.+]] = arith.maximumf %[[A]], %[[B]] : f322889//       CHECK:   return %[[S]]2890func.func @reduce_one_element_vector_maximumf(%a : vector<1xf32>, %b: f32) -> f32 {2891  %s = vector.reduction <maximumf>, %a, %b : vector<1xf32> into f322892  return %s : f322893}2894 2895// -----2896 2897// CHECK-LABEL: func @bitcast(2898//  CHECK-SAME:               %[[ARG:.*]]: vector<4x8xf32>) -> vector<4x16xi16> {2899//       CHECK: vector.bitcast %[[ARG:.*]] : vector<4x8xf32> to vector<4x16xi16>2900func.func @bitcast(%a: vector<4x8xf32>) -> vector<4x16xi16> {2901  %0 = vector.bitcast %a : vector<4x8xf32> to vector<4x8xi32>2902  %1 = vector.bitcast %0 : vector<4x8xi32> to vector<4x16xi16>2903  return %1 : vector<4x16xi16>2904}2905 2906// -----2907 2908// CHECK-LABEL: @insert_strided_slice_splatlike2909//  CHECK-SAME: (%[[ARG:.*]]: f32)2910//  CHECK-NEXT:   %[[SPLAT:.*]] = vector.broadcast %[[ARG]] : f32 to vector<8x16xf32>2911//  CHECK-NEXT:   return %[[SPLAT]] : vector<8x16xf32>2912func.func @insert_strided_slice_splatlike(%x: f32) -> (vector<8x16xf32>) {2913  %splat0 = vector.broadcast %x : f32 to vector<4x4xf32>2914  %splat1 = vector.broadcast %x : f32 to vector<8x16xf32>2915  %0 = vector.insert_strided_slice %splat0, %splat1 {offsets = [2, 2], strides = [1, 1]}2916    : vector<4x4xf32> into vector<8x16xf32>2917  return %0 : vector<8x16xf32>2918}2919 2920 2921// -----2922 2923// CHECK-LABEL: @insert_extract_strided_slice2924//  CHECK-SAME: (%[[ARG:.*]]: vector<8x16xf32>)2925//  CHECK-NEXT:   return %[[ARG]] : vector<8x16xf32>2926func.func @insert_extract_strided_slice(%x: vector<8x16xf32>) -> (vector<8x16xf32>) {2927  %0 = vector.extract_strided_slice %x {offsets = [0, 8], sizes = [2, 4], strides = [1, 1]}2928        : vector<8x16xf32> to vector<2x4xf32>2929  %1 = vector.insert_strided_slice %0, %x {offsets = [0, 8], strides = [1, 1]}2930        : vector<2x4xf32> into vector<8x16xf32>2931  return %1 : vector<8x16xf32>2932}2933 2934// -----2935 2936// CHECK-LABEL: func.func @insert_strided_1d_constant2937//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<[4, 1, 2]> : vector<3xi32>2938//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<[0, 1, 4]> : vector<3xi32>2939//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<[5, 6, 2]> : vector<3xi32>2940//   CHECK-DAG: %[[DCST:.*]] = arith.constant dense<[0, 5, 6]> : vector<3xi32>2941//   CHECK-DAG: %[[ECST:.*]] = arith.constant dense<[7, 8, 9]> : vector<3xi32>2942//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]], %[[ECST]]2943func.func @insert_strided_1d_constant() ->2944  (vector<3xi32>, vector<3xi32>, vector<3xi32>, vector<3xi32>, vector<3xi32>) {2945  %vcst = arith.constant dense<[0, 1, 2]> : vector<3xi32>2946  %cst_1 = arith.constant dense<4> : vector<1xi32>2947  %cst_2 = arith.constant dense<[5, 6]> : vector<2xi32>2948  %cst_3 = arith.constant dense<[7, 8, 9]> : vector<3xi32>2949  %a = vector.insert_strided_slice %cst_1, %vcst {offsets = [0], strides = [1]} : vector<1xi32> into vector<3xi32>2950  %b = vector.insert_strided_slice %cst_1, %vcst {offsets = [2], strides = [1]} : vector<1xi32> into vector<3xi32>2951  %c = vector.insert_strided_slice %cst_2, %vcst {offsets = [0], strides = [1]} : vector<2xi32> into vector<3xi32>2952  %d = vector.insert_strided_slice %cst_2, %vcst {offsets = [1], strides = [1]} : vector<2xi32> into vector<3xi32>2953  %e = vector.insert_strided_slice %cst_3, %vcst {offsets = [0], strides = [1]} : vector<3xi32> into vector<3xi32>2954  return %a, %b, %c, %d, %e : vector<3xi32>, vector<3xi32>, vector<3xi32>, vector<3xi32>, vector<3xi32>2955}2956 2957// -----2958 2959// CHECK-LABEL: func.func @insert_strided_2d_constant2960//   CHECK-DAG: %[[ACST:.*]] = arith.constant dense<{{\[\[0, 1\], \[9, 3\], \[4, 5\]\]}}> : vector<3x2xi32>2961//   CHECK-DAG: %[[BCST:.*]] = arith.constant dense<{{\[\[0, 1\], \[2, 3\], \[4, 9\]\]}}> : vector<3x2xi32>2962//   CHECK-DAG: %[[CCST:.*]] = arith.constant dense<{{\[\[18, 19\], \[2, 3\], \[4, 5\]\]}}> : vector<3x2xi32>2963//   CHECK-DAG: %[[DCST:.*]] = arith.constant dense<{{\[\[0, 1\], \[18, 19\], \[4, 5\]\]}}> : vector<3x2xi32>2964//   CHECK-DAG: %[[ECST:.*]] = arith.constant dense<{{\[\[0, 1\], \[2, 3\], \[18, 19\]\]}}> : vector<3x2xi32>2965//   CHECK-DAG: %[[FCST:.*]] = arith.constant dense<{{\[\[28, 29\], \[38, 39\], \[4, 5\]\]}}> : vector<3x2xi32>2966//   CHECK-DAG: %[[GCST:.*]] = arith.constant dense<{{\[\[0, 1\], \[28, 29\], \[38, 39\]\]}}> : vector<3x2xi32>2967//  CHECK-NEXT: return %[[ACST]], %[[BCST]], %[[CCST]], %[[DCST]], %[[ECST]], %[[FCST]], %[[GCST]]2968func.func @insert_strided_2d_constant() ->2969  (vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>) {2970  %vcst = arith.constant dense<[[0, 1], [2, 3], [4, 5]]> : vector<3x2xi32>2971  %cst_1 = arith.constant dense<9> : vector<1xi32>2972  %cst_2 = arith.constant dense<[18, 19]> : vector<2xi32>2973  %cst_3 = arith.constant dense<[[28, 29], [38, 39]]> : vector<2x2xi32>2974  %a = vector.insert_strided_slice %cst_1, %vcst {offsets = [1, 0], strides = [1]} : vector<1xi32> into vector<3x2xi32>2975  %b = vector.insert_strided_slice %cst_1, %vcst {offsets = [2, 1], strides = [1]} : vector<1xi32> into vector<3x2xi32>2976  %c = vector.insert_strided_slice %cst_2, %vcst {offsets = [0, 0], strides = [1]} : vector<2xi32> into vector<3x2xi32>2977  %d = vector.insert_strided_slice %cst_2, %vcst {offsets = [1, 0], strides = [1]} : vector<2xi32> into vector<3x2xi32>2978  %e = vector.insert_strided_slice %cst_2, %vcst {offsets = [2, 0], strides = [1]} : vector<2xi32> into vector<3x2xi32>2979  %f = vector.insert_strided_slice %cst_3, %vcst {offsets = [0, 0], strides = [1, 1]} : vector<2x2xi32> into vector<3x2xi32>2980  %g = vector.insert_strided_slice %cst_3, %vcst {offsets = [1, 0], strides = [1, 1]} : vector<2x2xi32> into vector<3x2xi32>2981  return %a, %b, %c, %d, %e, %f, %g :2982    vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>, vector<3x2xi32>2983}2984 2985// -----2986 2987// CHECK-LABEL: func @shuffle_splatlike2988//  CHECK-SAME:   (%[[ARG:.*]]: i32)2989//  CHECK-NEXT:   %[[SPLAT:.*]] = vector.broadcast %[[ARG]] : i32 to vector<4xi32>2990//  CHECK-NEXT:   return %[[SPLAT]] : vector<4xi32>2991func.func @shuffle_splatlike(%x : i32) -> vector<4xi32> {2992  %v0 = vector.broadcast %x : i32 to vector<4xi32>2993  %v1 = vector.broadcast %x : i32 to vector<2xi32>2994  %shuffle = vector.shuffle %v0, %v1 [2, 3, 4, 5] : vector<4xi32>, vector<2xi32>2995  return %shuffle : vector<4xi32>2996}2997 2998 2999// -----3000 3001// CHECK-LABEL: func @insert_splatlike3002//  CHECK-SAME:   (%[[ARG:.*]]: i32)3003//  CHECK-NEXT:   %[[SPLAT:.*]] = vector.broadcast %[[ARG]] : i32 to vector<2x4x3xi32>3004//  CHECK-NEXT:   return %[[SPLAT]] : vector<2x4x3xi32>3005func.func @insert_splatlike(%x : i32) -> vector<2x4x3xi32> {3006  %v0 = vector.broadcast %x : i32 to vector<4x3xi32>3007  %v1 = vector.broadcast %x : i32 to vector<2x4x3xi32>3008  %insert = vector.insert %v0, %v1[0] : vector<4x3xi32> into vector<2x4x3xi32>3009  return %insert : vector<2x4x3xi32>3010}3011 3012// -----3013 3014// CHECK-LABEL: func.func @transfer_read_from_rank_reducing_extract_slice3015//       CHECK:   tensor.extract_slice3016//       CHECK:   vector.transfer_read3017func.func @transfer_read_from_rank_reducing_extract_slice(%src: tensor<1x8x8x8xf32>, %i1: index, %i2: index, %i3: index, %i4: index) -> vector<4xf32> {3018  %c0 = arith.constant 0 : index3019  %f0 = arith.constant 0.000000e+00 : f323020  %0 = tensor.extract_slice %src[0, %i1, %i2, %i3] [1, 4, 1, 4] [1, 1, 1, 1] : tensor<1x8x8x8xf32> to tensor<1x4x4xf32>3021  %1 = vector.transfer_read %0[%c0, %i4, %c0], %f0 {in_bounds = [true]} : tensor<1x4x4xf32>, vector<4xf32>3022  return %1 : vector<4xf32>3023}3024 3025// -----3026 3027// CHECK-LABEL: func.func @extract_from_broadcast3028func.func @extract_from_broadcast(%src: vector<1x1x1xf32>) -> vector<1xf32> {3029  %0 = vector.broadcast %src : vector<1x1x1xf32> to vector<1x1x32x1xf32>3030 3031  //  CHECK-NEXT:   %0 = vector.extract {{.*}}[0, 0] : vector<1xf32> from vector<1x1x1xf32>3032  //  CHECK-NEXT:   return %0 : vector<1xf32>3033  %1 = vector.extract %0[0, 0, 31] : vector<1xf32> from vector<1x1x32x1xf32>3034  return %1: vector<1xf32>3035}3036 3037// CHECK-LABEL: func.func @extract_from_stretch_broadcast3038func.func @extract_from_stretch_broadcast(%src: vector<3x1x2xf32>) -> f32 {3039  //  CHECK-NEXT:  %0 = vector.extract {{.*}}[0, 0, 0] : f32 from vector<3x1x2xf32>3040  //  CHECK-NEXT:  return %0 : f323041  %0 = vector.broadcast %src : vector<3x1x2xf32> to vector<3x4x2xf32>3042  %1 = vector.extract %0[0, 2, 0] : f32 from vector<3x4x2xf32>3043  return %1: f323044}3045 3046// -----3047// CHECK-LABEL: func.func @extract_strided_slice_of_constant_mask3048func.func @extract_strided_slice_of_constant_mask() -> vector<5x7xi1>{3049  //  CHECK-NEXT:   %[[RES:.*]] = vector.constant_mask [5, 4] : vector<5x7xi1>3050  //  CHECK-NEXT:   return %[[RES]] : vector<5x7xi1>3051  %c4 = arith.constant 4 : index3052  %c10 = arith.constant 10 : index3053  %mask = vector.create_mask %c10, %c4 : vector<12x7xi1>3054  %res = vector.extract_strided_slice %mask {offsets = [3], sizes = [5], strides = [1]} : vector<12x7xi1> to vector<5x7xi1>3055  return %res : vector<5x7xi1>3056}3057 3058// -----3059 3060// CHECK-LABEL: func.func @fold_0d_vector_reduction3061func.func @fold_0d_vector_reduction(%arg0: vector<f32>) -> f32 {3062  // CHECK-NEXT: %[[RES:.*]] = vector.extract %arg{{.*}}[] : f32 from vector<f32>3063  // CHECK-NEXT: return %[[RES]] : f323064  %0 = vector.reduction <add>, %arg0 : vector<f32> into f323065  return %0 : f323066}3067 3068// -----3069 3070// CHECK-LABEL: func @empty_vector_mask3071func.func @empty_vector_mask(%mask : vector<8xi1>) {3072//   CHECK-NOT:   vector.mask3073  vector.mask %mask { } : vector<8xi1>3074  return3075}3076 3077// -----3078 3079// CHECK-LABEL: func @empty_vector_mask_with_return3080//  CHECK-SAME:     %[[IN:.*]]: vector<8xf32>3081func.func @empty_vector_mask_with_return(%a : vector<8xf32>, %mask : vector<8xi1>) -> vector<8xf32> {3082//   CHECK-NOT:   vector.mask3083//       CHECK:   return %[[IN]] : vector<8xf32>3084  %0 = vector.mask %mask { vector.yield %a : vector<8xf32> } : vector<8xi1> -> vector<8xf32>3085  return %0 : vector<8xf32>3086}3087 3088// -----3089 3090// CHECK-LABEL: func @empty_vector_mask_with_passthru3091//  CHECK-SAME:     %[[IN:.*]]: vector<8xf32>, %[[MASK:.*]]: vector<8xi1>, %[[PASSTHRU:.*]]: vector<8xf32>3092func.func @empty_vector_mask_with_passthru(%a : vector<8xf32>, %mask : vector<8xi1>,3093                                           %passthru : vector<8xf32>) -> vector<8xf32> {3094//   CHECK-NOT:   vector.mask3095//       CHECK:   %[[SEL:.*]] = arith.select %[[MASK]], %[[IN]], %[[PASSTHRU]] : vector<8xi1>, vector<8xf32>3096//       CHECK:   return %[[SEL]] : vector<8xf32>3097  %0 = vector.mask %mask, %passthru { vector.yield %a : vector<8xf32> } : vector<8xi1> -> vector<8xf32>3098  return %0 : vector<8xf32>3099}3100 3101// -----3102 3103// CHECK-LABEL: func @all_true_vector_mask3104//  CHECK-SAME:     %[[IN:.*]]: tensor<3x4xf32>3105func.func @all_true_vector_mask(%ta : tensor<3x4xf32>) -> vector<3x4xf32> {3106//   CHECK-NOT:   vector.mask3107//       CHECK:   %[[LD:.*]] = vector.transfer_read %[[IN]]3108//       CHECK:   return %[[LD]] : vector<3x4xf32>3109  %c0 = arith.constant 0 : index3110  %cf0 = arith.constant 0.0 : f323111  %all_true = vector.constant_mask [3, 4] : vector<3x4xi1>3112  %0 = vector.mask %all_true { vector.transfer_read %ta[%c0, %c0], %cf0 : tensor<3x4xf32>, vector<3x4xf32> } : vector<3x4xi1> -> vector<3x4xf32>3113  return %0 : vector<3x4xf32>3114}3115 3116// -----3117 3118// CHECK-LABEL: func @all_true_vector_mask_no_result(3119func.func @all_true_vector_mask_no_result(%a : vector<3x4xf32>, %m : memref<3x4xf32>) {3120//   CHECK-NOT:   vector.mask3121//       CHECK:   vector.transfer_write3122  %c0 = arith.constant 0 : index3123  %all_true = vector.constant_mask [3, 4] : vector<3x4xi1>3124  vector.mask %all_true { vector.transfer_write %a, %m[%c0, %c0] : vector<3x4xf32>, memref<3x4xf32> } : vector<3x4xi1>3125  return3126}3127 3128// -----3129 3130// CHECK-LABEL:   func.func @fold_shape_cast_with_mask(3131// CHECK-SAME:     %[[VAL_0:.*]]: tensor<1x?xf32>) -> vector<1x4xi1> {3132func.func @fold_shape_cast_with_mask(%arg0: tensor<1x?xf32>) -> vector<1x4xi1> {3133// CHECK-NOT: vector.shape_cast3134// CHECK:     %[[VAL_1:.*]] = arith.constant 1 : index3135// CHECK:     %[[VAL_2:.*]] = tensor.dim %[[VAL_0]], %[[VAL_1]] : tensor<1x?xf32>3136// CHECK:     %[[VAL_3:.*]] = vector.create_mask %[[VAL_1]], %[[VAL_2]] : vector<1x4xi1>3137// CHECK:     return %[[VAL_3]] : vector<1x4xi1>3138  %c1 = arith.constant 1 : index3139  %dim = tensor.dim %arg0, %c1 : tensor<1x?xf32>3140  %1 = vector.create_mask %c1, %dim, %c1, %c1 : vector<1x4x1x1xi1>3141  %2 = vector.shape_cast %1 : vector<1x4x1x1xi1> to vector<1x4xi1>3142  return %2 : vector<1x4xi1>3143}3144 3145// -----3146 3147// CHECK-LABEL:   func.func @fold_shape_cast_with_mask_scalable(3148// CHECK-SAME:    %[[VAL_0:.*]]: tensor<1x?xf32>) -> vector<1x[4]xi1> {3149func.func @fold_shape_cast_with_mask_scalable(%arg0: tensor<1x?xf32>) -> vector<1x[4]xi1> {3150// CHECK-NOT: vector.shape_cast3151// CHECK:           %[[VAL_1:.*]] = arith.constant 1 : index3152// CHECK:           %[[VAL_2:.*]] = tensor.dim %[[VAL_0]], %[[VAL_1]] : tensor<1x?xf32>3153// CHECK:           %[[VAL_3:.*]] = vector.create_mask %[[VAL_1]], %[[VAL_2]] : vector<1x[4]xi1>3154// CHECK:           return %[[VAL_3]] : vector<1x[4]xi1>3155  %c1 = arith.constant 1 : index3156  %dim = tensor.dim %arg0, %c1 : tensor<1x?xf32>3157  %1 = vector.create_mask %c1, %dim, %c1, %c1 : vector<1x[4]x1x1xi1>3158  %2 = vector.shape_cast %1 : vector<1x[4]x1x1xi1> to vector<1x[4]xi1>3159  return %2 : vector<1x[4]xi1>3160}3161 3162// -----3163 3164// Check that scalable "1" (i.e. [1]) is not folded3165// CHECK-LABEL:   func.func @fold_shape_cast_with_mask_scalable_one(3166// CHECK-SAME:    %[[VAL_0:.*]]: tensor<1x?xf32>) -> vector<1x[1]xi1> {3167func.func @fold_shape_cast_with_mask_scalable_one(%arg0: tensor<1x?xf32>) -> vector<1x[1]xi1>{3168// CHECK:           %[[VAL_1:.*]] = arith.constant 1 : index3169// CHECK:           %[[VAL_2:.*]] = tensor.dim %[[VAL_0]], %[[VAL_1]] : tensor<1x?xf32>3170// CHECK:           %[[VAL_3:.*]] = vector.create_mask %[[VAL_1]], %[[VAL_2]] : vector<1x[1]xi1>3171// CHECK:           return %[[VAL_3]] : vector<1x[1]xi1>3172  %c1 = arith.constant 1 : index3173  %dim = tensor.dim %arg0, %c1 : tensor<1x?xf32>3174  %1 = vector.create_mask %c1, %dim, %c1 : vector<1x[1]x1xi1>3175  %2 = vector.shape_cast %1 : vector<1x[1]x1xi1> to vector<1x[1]xi1>3176  return %2 : vector<1x[1]xi1>3177}3178 3179// -----3180 3181// CHECK-LABEL:   func.func @fold_shape_cast_with_constant_mask() -> vector<4xi1> {3182func.func @fold_shape_cast_with_constant_mask() -> vector<4xi1>{3183// CHECK-NOT: vector.shape_cast3184// CHECK:           %[[VAL_0:.*]] = vector.constant_mask [1] : vector<4xi1>3185// CHECK:           return %[[VAL_0]] : vector<4xi1>3186  %1 = vector.constant_mask [1, 1, 1] : vector<4x1x1xi1>3187  %2 = vector.shape_cast %1 : vector<4x1x1xi1> to vector<4xi1>3188  return %2 : vector<4xi1>3189}3190 3191// -----3192 3193// TODO: This IR could be canonicalized but the canonicalization pattern is not3194// smart enough. For now, just make sure that we do not crash.3195 3196// CHECK-LABEL: func.func @load_store_forwarding_rank_mismatch(3197//       CHECK:   vector.transfer_write3198//       CHECK:   vector.transfer_read3199func.func @load_store_forwarding_rank_mismatch(%v0: vector<4x1x1xf32>, %arg0: tensor<4x4x4xf32>) -> (vector<1x100x4x5xf32>) {3200  %c0 = arith.constant 0 : index3201  %cf0 = arith.constant 0.0 : f323202  // d0 is explicitly written.3203  %w0 = vector.transfer_write %v0, %arg0[%c0, %c0, %c0]3204      {in_bounds = [true, true, true],3205      permutation_map = affine_map<(d0, d1, d2) -> (d2, d1, d0)>} :3206      vector<4x1x1xf32>, tensor<4x4x4xf32>3207  // d0 is implicitly read (rank-reduction of unit dim).3208  %r = vector.transfer_read %w0[%c0, %c0, %c0], %cf03209      {in_bounds = [true, true, true, true],3210      permutation_map = affine_map<(d0, d1, d2) -> (d1, 0, d2, 0)>} :3211      tensor<4x4x4xf32>, vector<1x100x4x5xf32>3212  return %r : vector<1x100x4x5xf32>3213}3214 3215// -----3216 3217// CHECK-LABEL: func.func @rank_0_shuffle_to_interleave(3218//  CHECK-SAME:     %[[LHS:.*]]: vector<f64>, %[[RHS:.*]]: vector<f64>)3219func.func @rank_0_shuffle_to_interleave(%arg0: vector<f64>, %arg1: vector<f64>) -> vector<2xf64> {3220  // CHECK: %[[ZIP:.*]] = vector.interleave %[[LHS]], %[[RHS]] : vector<f64> -> vector<2xf64>3221  // CHECK: return %[[ZIP]]3222  %0 = vector.shuffle %arg0, %arg1 [0, 1] : vector<f64>, vector<f64>3223  return %0 : vector<2xf64>3224}3225 3226// -----3227 3228// CHECK-LABEL: func.func @rank_1_shuffle_to_interleave(3229//  CHECK-SAME:     %[[LHS:.*]]: vector<6xi32>, %[[RHS:.*]]: vector<6xi32>)3230func.func @rank_1_shuffle_to_interleave(%arg0: vector<6xi32>, %arg1: vector<6xi32>) -> vector<12xi32> {3231  // CHECK: %[[ZIP:.*]] = vector.interleave %[[LHS]], %[[RHS]] : vector<6xi32> -> vector<12xi32>3232  // CHECK: return %[[ZIP]]3233  %0 = vector.shuffle %arg0, %arg1 [0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11] : vector<6xi32>, vector<6xi32>3234  return %0 : vector<12xi32>3235}3236 3237// -----3238 3239// CHECK-LABEL: func @extract_from_splatlike_broadcast(3240//  CHECK-SAME:     %[[A:.*]]: f32, %[[B:.*]]: vector<f32>, %[[C:.*]]: vector<2xf32>)3241func.func @extract_from_splatlike_broadcast(%a: f32, %b: vector<f32>, %c: vector<2xf32>) -> (f32, f32, f32, f32, vector<6x7xf32>, vector<3xf32>) {3242  // Broadcast scalar to 0D and extract scalar.3243  %0 = vector.broadcast %a : f32 to vector<f32>3244  %1 = vector.extract %0[] : f32 from vector<f32>3245 3246  // Broadcast 0D to 3D and extract scalar.3247  // CHECK: %[[EXTRACT1:.*]] = vector.extract %[[B]][] : f32 from vector<f32>3248  %4 = vector.broadcast %b : vector<f32> to vector<1x2x4xf32>3249  %5 = vector.extract %4[0, 0, 1] : f32 from vector<1x2x4xf32>3250 3251  // Broadcast scalar to 2D and extract scalar.3252  %6 = vector.broadcast %a : f32 to vector<2x3xf32>3253  %7 = vector.extract %6[0, 1] : f32 from vector<2x3xf32>3254 3255  // Broadcast scalar to 3D and extract scalar.3256  %8 = vector.broadcast %a : f32 to vector<5x6x7xf32>3257  %9 = vector.extract %8[2, 1, 5] : f32 from vector<5x6x7xf32>3258 3259  // Extract 2D from 3D that was broadcasted from a scalar.3260  // CHECK: %[[EXTRACT2:.*]] = vector.broadcast %[[A]] : f32 to vector<6x7xf32>3261  %10 = vector.extract %8[2] : vector<6x7xf32> from vector<5x6x7xf32>3262 3263  // Extract 1D from 2D that was splat'ed from a scalar.3264  // CHECK: %[[EXTRACT3:.*]] = vector.broadcast %[[A]] : f32 to vector<3xf32>3265  %11 = vector.extract %6[1] : vector<3xf32> from vector<2x3xf32>3266 3267  // CHECK:   return %[[A]], %[[EXTRACT1]], %[[A]], %[[A]], %[[EXTRACT2]], %[[EXTRACT3]]3268  return %1, %5, %7, %9, %10, %11 : f32, f32, f32, f32, vector<6x7xf32>, vector<3xf32>3269}3270 3271// -----3272 3273// CHECK-LABEL: func @to_elements_from_elements_no_op(3274// CHECK-SAME:     %[[A:.*]]: f32, %[[B:.*]]: f323275func.func @to_elements_from_elements_no_op(%a: f32, %b: f32) -> (f32, f32) {3276  // CHECK-NOT: vector.from_elements3277  // CHECK-NOT: vector.to_elements3278  %0 = vector.from_elements %b, %a : vector<2xf32>3279  %1:2 = vector.to_elements %0 : vector<2xf32>3280  // CHECK: return %[[B]], %[[A]]3281  return %1#0, %1#1 : f32, f323282}3283 3284// -----3285 3286// CHECK-LABEL: func @from_elements_to_elements_no_op(3287// CHECK-SAME:     %[[A:.*]]: vector<4x2xf32>3288func.func @from_elements_to_elements_no_op(%a: vector<4x2xf32>) -> vector<4x2xf32> {3289  // CHECK-NOT: vector.from_elements3290  // CHECK-NOT: vector.to_elements3291  %0:8 = vector.to_elements %a : vector<4x2xf32>3292  %1 = vector.from_elements %0#0, %0#1, %0#2, %0#3, %0#4, %0#5, %0#6, %0#7 : vector<4x2xf32>3293  // CHECK: return %[[A]]3294  return %1 : vector<4x2xf32>3295}3296 3297// -----3298 3299// CHECK-LABEL: func @from_elements_to_elements_dup_elems(3300// CHECK-SAME:     %[[A:.*]]: vector<4xf32>3301func.func @from_elements_to_elements_dup_elems(%a: vector<4xf32>) -> vector<4x2xf32> {3302  // CHECK: %[[TO_EL:.*]]:4 = vector.to_elements %[[A]]3303  // CHECK: %[[FROM_EL:.*]] = vector.from_elements %[[TO_EL]]#0, %[[TO_EL]]#1, %[[TO_EL]]#23304  %0:4 = vector.to_elements %a : vector<4xf32> // 4 elements3305  %1 = vector.from_elements %0#0, %0#1, %0#2, %0#3, %0#0, %0#1, %0#2, %0#3 : vector<4x2xf32>3306  // CHECK: return %[[FROM_EL]]3307  return %1 : vector<4x2xf32>3308}3309 3310// -----3311 3312// CHECK-LABEL: func @from_elements_to_elements_shuffle(3313// CHECK-SAME:     %[[A:.*]]: vector<4x2xf32>3314func.func @from_elements_to_elements_shuffle(%a: vector<4x2xf32>) -> vector<4x2xf32> {3315  // CHECK: %[[TO_EL:.*]]:8 = vector.to_elements %[[A]]3316  // CHECK: %[[FROM_EL:.*]] = vector.from_elements %[[TO_EL]]#7, %[[TO_EL]]#0, %[[TO_EL]]#63317  %0:8 = vector.to_elements %a : vector<4x2xf32>3318  %1 = vector.from_elements %0#7, %0#0, %0#6, %0#1, %0#5, %0#2, %0#4, %0#3 : vector<4x2xf32>3319  // CHECK: return %[[FROM_EL]]3320  return %1 : vector<4x2xf32>3321}3322 3323// -----3324 3325// CHECK-LABEL: func @to_elements_of_scalar_broadcast_folds3326// CHECK-SAME: (%[[S:.*]]: f32) -> (f32, f32, f32, f32)3327func.func @to_elements_of_scalar_broadcast_folds(%s: f32) -> (f32, f32, f32, f32) {3328  %v = vector.broadcast %s : f32 to vector<4xf32>3329  %e:4 = vector.to_elements %v : vector<4xf32>3330  // CHECK-NOT: vector.broadcast3331  // CHECK-NOT: vector.to_elements3332  // CHECK: return %[[S]], %[[S]], %[[S]], %[[S]]3333  return %e#0, %e#1, %e#2, %e#3 : f32, f32, f32, f323334}3335 3336// -----3337 3338// CHECK-LABEL: func @to_elements_of_vector_broadcast3339// CHECK-SAME: (%[[VEC:.*]]: vector<2xf32>) -> (f32, f32, f32, f32, f32, f32)3340func.func @to_elements_of_vector_broadcast(%vec: vector<2xf32>) -> (f32, f32, f32, f32, f32, f32) {3341  %v = vector.broadcast %vec : vector<2xf32> to vector<3x2xf32>3342  %e:6 = vector.to_elements %v : vector<3x2xf32>3343  // CHECK-NOT: vector.broadcast3344  // CHECK: %[[SRC_ELEMS:.*]]:2 = vector.to_elements %[[VEC]]3345  // CHECK: return %[[SRC_ELEMS]]#0, %[[SRC_ELEMS]]#1, %[[SRC_ELEMS]]#0, %[[SRC_ELEMS]]#1, %[[SRC_ELEMS]]#0, %[[SRC_ELEMS]]#13346  return %e#0, %e#1, %e#2, %e#3, %e#4, %e#5 : f32, f32, f32, f32, f32, f323347}3348 3349// -----3350 3351// CHECK-LABEL: func @to_elements_of_vector_broadcast_inner_dim3352// CHECK-SAME: (%[[V:.*]]: vector<2x1x2xf32>) -> (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)3353func.func @to_elements_of_vector_broadcast_inner_dim(%v: vector<2x1x2xf32>) -> (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) {3354  %b = vector.broadcast %v : vector<2x1x2xf32> to vector<2x3x2xf32>3355  %e:12 = vector.to_elements %b : vector<2x3x2xf32>3356  // CHECK-NOT: vector.broadcast3357  // CHECK: %[[SRC:.*]]:4 = vector.to_elements %[[V]] : vector<2x1x2xf32>3358  // CHECK: return %[[SRC]]#0, %[[SRC]]#1, %[[SRC]]#0, %[[SRC]]#1, %[[SRC]]#0, %[[SRC]]#1, %[[SRC]]#2, %[[SRC]]#3, %[[SRC]]#2, %[[SRC]]#3, %[[SRC]]#2, %[[SRC]]#33359  return %e#0, %e#1, %e#2, %e#3, %e#4, %e#5, %e#6, %e#7, %e#8, %e#9, %e#10, %e#11 :3360    f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f323361}3362 3363// -----3364 3365// +---------------------------------------------------------------------------3366// Tests for foldFromElementsToConstant3367// +---------------------------------------------------------------------------3368 3369// CHECK-LABEL: func @from_elements_to_constant(3370func.func @from_elements_to_constant() -> vector<2x2xi32> {3371  %c0_i32 = arith.constant 0 : i323372  %c1_i32 = arith.constant 1 : i323373  %c2_i32 = arith.constant 2 : i323374  %c3_i32 = arith.constant 3 : i323375  // CHECK: %[[RES:.*]] = arith.constant dense<{{\[\[0, 1\], \[2, 3\]\]}}> : vector<2x2xi32>3376  %res = vector.from_elements %c0_i32, %c1_i32, %c2_i32, %c3_i32 : vector<2x2xi32>3377  // CHECK: return %[[RES]]3378  return %res : vector<2x2xi32>3379}3380 3381// -----3382 3383// One of the elements is not a constant, the folder should fail.3384 3385// CHECK-LABEL: func @negative_from_elements_to_constant(3386// CHECK-SAME:     %[[A:.*]]: f323387func.func @negative_from_elements_to_constant(%arg0: f32) -> vector<2xf32> {3388  // CHECK: %[[C:.*]] = arith.constant 1.000000e+00 : f323389  %c = arith.constant 1.0 : f323390  // CHECK: %[[RES:.*]] = vector.from_elements %[[A]], %[[C]] : vector<2xf32>3391  %res = vector.from_elements %arg0, %c : vector<2xf32>3392  // CHECK: return %[[RES]]3393  return %res : vector<2xf32>3394}3395 3396// -----3397 3398// While all inputs in this example are constant, we cannot create a3399// DenselElemAttr containing llvm.mlir.addressof. Instead,3400// `foldFromElementsToConstant` bails out. Note that in this case, a different3401// folder is applied (`rewriteFromElementsAsBroadcast`).3402llvm.mlir.global constant @my_symbol() : i323403 3404// CHECK-LABEL: func @negative_from_elements_to_constant3405//       CHECK:   %[[A:.*]] = llvm.mlir.addressof @my_symbol3406//       CHECK:   %[[B:.*]] = vector.broadcast %[[A]] : !llvm.ptr to vector<1x!llvm.ptr>3407//       CHECK:   return %[[B]]3408func.func @negative_from_elements_to_constant() -> vector<1x!llvm.ptr> {3409  %a = llvm.mlir.addressof @my_symbol : !llvm.ptr3410  %b = vector.from_elements %a : vector<1x!llvm.ptr>3411  return %b : vector<1x!llvm.ptr>3412}3413 3414// -----3415 3416// `foldFromElementsToConstant` does not support `ub.poison`, so it bails out.3417// Instead, other folders apply here (e.g. `rewriteFromElementsAsBroadcast`).3418 3419// CHECK-LABEL: @negative_from_elements_poison3420//       CHECK:   %[[VAL:.*]] = ub.poison : vector<2xf32>3421//       CHECK:   return %[[VAL]] : vector<2xf32>3422func.func @negative_from_elements_poison_f32() -> vector<2xf32> {3423  %0 = ub.poison : f323424  %1 = vector.from_elements %0, %0 : vector<2xf32>3425  return %1 : vector<2xf32>3426}3427 3428// -----3429 3430// `foldFromElementsToConstant` does not support `ub.poison`, so it bails out.3431// Instead, other folders apply here (e.g. `rewriteFromElementsAsBroadcast`).3432 3433// CHECK-LABEL: @negative_from_elements_poison_i323434//       CHECK:   %[[VAL:.*]] = ub.poison : vector<2xi32>3435//       CHECK:   return %[[VAL]] : vector<2xi32>3436func.func @negative_from_elements_poison_i32() -> vector<2xi32> {3437  %0 = ub.poison : i323438  %1 = vector.from_elements %0, %0 : vector<2xi32>3439  return %1 : vector<2xi32>3440}3441 3442// -----3443 3444// `foldFromElementsToConstant` does not support `ub.poison`, so it bails out.3445// Instead, other folders apply here (e.g. `rewriteFromElementsAsBroadcast`).3446 3447// CHECK-LABEL: @negative_from_elements_poison_constant_mix3448//       CHECK:   %[[POISON:.*]] = ub.poison : f323449//       CHECK:   %[[CONST:.*]] = arith.constant 1.000000e+00 : f323450//       CHECK:   %[[RES:.*]] = vector.from_elements %[[POISON]], %[[CONST]] : vector<2xf32>3451//       CHECK:   return %[[RES]] : vector<2xf32>3452func.func @negative_from_elements_poison_constant_mix() -> vector<2xf32> {3453  %0 = ub.poison : f323454  %c = arith.constant 1.0 : f323455  %1 = vector.from_elements %0, %c : vector<2xf32>3456  return %1 : vector<2xf32>3457}3458 3459// -----3460 3461// CHECK-LABEL: func @from_elements_float8_to_i8_conversion(3462// CHECK-NEXT:    %[[CST:.*]] = arith.constant dense<[0, 56, -72, 69, 127, -1]> : vector<6xi8>3463// CHECK-NEXT:    return %[[CST]] : vector<6xi8>3464func.func @from_elements_float8_to_i8_conversion() -> vector<6xi8> {3465  %cst0 = llvm.mlir.constant(0.0 : f8E4M3FN) : i83466  %cst1 = llvm.mlir.constant(1.0 : f8E4M3FN) : i83467  %cst_neg1 = llvm.mlir.constant(-1.0 : f8E4M3FN) : i83468  %cst_pi = llvm.mlir.constant(3.14 : f8E4M3FN) : i83469  %cst_inf = llvm.mlir.constant(0x7F : f8E4M3FN) : i83470  %cst_neg_inf = llvm.mlir.constant(0xFF : f8E4M3FN) : i83471  %v = vector.from_elements %cst0, %cst1, %cst_neg1, %cst_pi, %cst_inf, %cst_neg_inf : vector<6xi8>3472  return %v : vector<6xi8>3473}3474 3475// CHECK-LABEL: func @from_elements_float16_to_i16_conversion(3476// CHECK-NEXT:    %[[CST:.*]] = arith.constant dense<[0, 15360, -17408, 16968, 31743, -1025]> : vector<6xi16>3477// CHECK-NEXT:    return %[[CST]] : vector<6xi16>3478func.func @from_elements_float16_to_i16_conversion() -> vector<6xi16> {3479  %cst0 = llvm.mlir.constant(0.0 : f16) : i163480  %cst1 = llvm.mlir.constant(1.0 : f16) : i163481  %cst_neg1 = llvm.mlir.constant(-1.0 : f16) : i163482  %cst_pi = llvm.mlir.constant(3.14 : f16) : i163483  %cst_max = llvm.mlir.constant(65504.0	: f16) : i163484  %cst_min = llvm.mlir.constant(-65504.0 : f16) : i163485  %v = vector.from_elements %cst0, %cst1, %cst_neg1, %cst_pi, %cst_max, %cst_min : vector<6xi16>3486  return %v : vector<6xi16>3487}3488 3489// CHECK-LABEL: func @from_elements_f64_to_i64_conversion(3490// CHECK-NEXT:    %[[CST:.*]] = arith.constant dense<[0, 4607182418800017408, -4616189618054758400, 4614253070214989087, 9218868437227405311, -4503599627370497]> : vector<6xi64>3491// CHECK-NEXT:    return %[[CST]] : vector<6xi64>3492func.func @from_elements_f64_to_i64_conversion() -> vector<6xi64> {3493  %cst0 = llvm.mlir.constant(0.0 : f64) : i643494  %cst1 = llvm.mlir.constant(1.0 : f64) : i643495  %cst_neg1 = llvm.mlir.constant(-1.0 : f64) : i643496  %cst_pi = llvm.mlir.constant(3.14 : f64) : i643497  %cst_max = llvm.mlir.constant(1.7976931348623157e+308 : f64) : i643498  %cst_min = llvm.mlir.constant(-1.7976931348623157e+308 : f64) : i643499  %v = vector.from_elements %cst0, %cst1, %cst_neg1, %cst_pi, %cst_max, %cst_min : vector<6xi64>3500  return %v : vector<6xi64>3501}3502 3503// -----3504 3505// CHECK-LABEL: func @from_elements_i1_to_i8_conversion(3506// CHECK-NEXT:    %[[CST:.*]] = arith.constant dense<0> : vector<1xi8>3507// CHECK-NEXT:    return %[[CST]] : vector<1xi8>3508func.func @from_elements_i1_to_i8_conversion() -> vector<1xi8> {3509  %cst = llvm.mlir.constant(0: i1) : i83510  %v = vector.from_elements %cst : vector<1xi8>3511  return %v : vector<1xi8>3512}3513 3514// -----3515 3516// CHECK-LABEL: func @from_elements_index_to_i64_conversion(3517// CHECK-NEXT:    %[[CST:.*]] = arith.constant dense<[0, 1, 42]> : vector<3xi64>3518// CHECK-NEXT:    return %[[CST]] : vector<3xi64>3519func.func @from_elements_index_to_i64_conversion() -> vector<3xi64> {3520  %cst0 = llvm.mlir.constant(0 : index) : i643521  %cst1 = llvm.mlir.constant(1 : index) : i643522  %cst42 = llvm.mlir.constant(42 : index) : i643523  %v = vector.from_elements %cst0, %cst1, %cst42 : vector<3xi64>3524  return %v : vector<3xi64>3525}3526 3527// +---------------------------------------------------------------------------3528// End of  Tests for foldFromElementsToConstant3529// +---------------------------------------------------------------------------3530 3531// -----3532 3533// +---------------------------------------------------------------------------3534// Tests for FoldTransposeFromElements3535// +---------------------------------------------------------------------------3536 3537// CHECK-LABEL: transpose_from_elements_1d3538// CHECK-SAME:  %[[EL_0:.*]]: i32, %[[EL_1:.*]]: i32 3539func.func @transpose_from_elements_1d(%el_0: i32, %el_1: i32) -> vector<2xi32> {3540  %v = vector.from_elements %el_0, %el_1 : vector<2xi32>3541  %t = vector.transpose %v, [0] : vector<2xi32> to vector<2xi32>3542  return %t : vector<2xi32>3543  // CHECK: %[[R:.*]] = vector.from_elements %[[EL_0]], %[[EL_1]] : vector<2xi32>3544  // CHECK-NOT: vector.transpose3545  // CHECK: return %[[R]]3546}3547 3548// CHECK-LABEL: transpose_from_elements_2d3549// CHECK-SAME:  %[[EL_0_0:.*]]: i32, %[[EL_0_1:.*]]: i32, %[[EL_0_2:.*]]: i32, %[[EL_1_0:.*]]: i32, %[[EL_1_1:.*]]: i32, %[[EL_1_2:.*]]: i32 3550func.func @transpose_from_elements_2d(3551  %el_0_0: i32, %el_0_1: i32, %el_0_2: i32,3552  %el_1_0: i32, %el_1_1: i32, %el_1_2: i323553) -> vector<3x2xi32> {3554  %v = vector.from_elements %el_0_0, %el_0_1, %el_0_2, %el_1_0, %el_1_1, %el_1_2 : vector<2x3xi32>3555  %t = vector.transpose %v, [1, 0] : vector<2x3xi32> to vector<3x2xi32>3556  return %t : vector<3x2xi32>3557  // CHECK: %[[R:.*]] = vector.from_elements %[[EL_0_0:.*]], %[[EL_1_0:.*]], %[[EL_0_1:.*]], %[[EL_1_1:.*]], %[[EL_0_2:.*]], %[[EL_1_2:.*]] : vector<3x2xi32>3558  // CHECK-NOT: vector.transpose3559  // CHECK: return %[[R]]3560}3561 3562// CHECK-LABEL: transpose_from_elements_3d3563// CHECK-SAME:  %[[EL_0_0_0:.*]]: i32, %[[EL_0_0_1:.*]]: i32, %[[EL_0_1_0:.*]]: i32, %[[EL_0_1_1:.*]]: i32, %[[EL_0_2_0:.*]]: i32, %[[EL_0_2_1:.*]]: i32, %[[EL_1_0_0:.*]]: i32, %[[EL_1_0_1:.*]]: i32, %[[EL_1_1_0:.*]]: i32, %[[EL_1_1_1:.*]]: i32, %[[EL_1_2_0:.*]]: i32, %[[EL_1_2_1:.*]]: i32 3564func.func @transpose_from_elements_3d(3565  %el_0_0_0: i32, %el_0_0_1: i32, %el_0_1_0: i32, %el_0_1_1: i32, %el_0_2_0: i32, %el_0_2_1: i32,3566  %el_1_0_0: i32, %el_1_0_1: i32, %el_1_1_0: i32, %el_1_1_1: i32, %el_1_2_0: i32, %el_1_2_1: i323567) -> vector<2x2x3xi32> {3568  %v = vector.from_elements3569    %el_0_0_0, %el_0_0_1,3570    %el_0_1_0, %el_0_1_1,3571    %el_0_2_0, %el_0_2_1,3572    %el_1_0_0, %el_1_0_1,3573    %el_1_1_0, %el_1_1_1,3574    %el_1_2_0, %el_1_2_13575    : vector<2x3x2xi32>3576  %t = vector.transpose %v, [0, 2, 1] : vector<2x3x2xi32> to vector<2x2x3xi32>3577  return %t : vector<2x2x3xi32>3578  // CHECK: %[[R:.*]] = vector.from_elements %[[EL_0_0_0:.*]], %[[EL_0_1_0:.*]], %[[EL_0_2_0:.*]], %[[EL_0_0_1:.*]], %[[EL_0_1_1:.*]], %[[EL_0_2_1:.*]], %[[EL_1_0_0:.*]], %[[EL_1_1_0:.*]], %[[EL_1_2_0:.*]], %[[EL_1_0_1:.*]], %[[EL_1_1_1:.*]], %[[EL_1_2_1:.*]] : vector<2x2x3xi32>3579  // CHECK-NOT: vector.transpose3580  // CHECK: return %[[R]]3581}3582 3583// +---------------------------------------------------------------------------3584// End of  Tests for FoldTransposeFromElements3585// +---------------------------------------------------------------------------3586 3587// -----3588 3589// Not a DenseElementsAttr, don't fold.3590 3591// CHECK-LABEL: func @negative_insert_llvm_undef(3592//       CHECK:   llvm.mlir.undef3593//       CHECK:   vector.insert3594func.func @negative_insert_llvm_undef(%arg0: i8) -> vector<4xi8> {3595  %0 = llvm.mlir.undef : vector<4xi8>3596  %1 = vector.insert %arg0, %0 [0] : i8 into vector<4xi8>3597  return %1 : vector<4xi8>3598}3599 3600// -----3601 3602// Insert a poison value shouldn't be folded as the resulting vector is not3603// fully poison.3604 3605// CHECK-LABEL: @insert_scalar_poison3606func.func @insert_scalar_poison(%a: vector<4x8xf32>)3607    -> vector<4x8xf32> {3608  //  CHECK-NEXT: %[[UB:.*]] = ub.poison : f323609  //  CHECK-NEXT: %[[RES:.*]] = vector.insert %[[UB]]3610  //  CHECK-NEXT: return %[[RES]] : vector<4x8xf32>3611  %0 = ub.poison : f323612  %1 = vector.insert %0, %a[2, 3] : f32 into vector<4x8xf32>3613  return %1 : vector<4x8xf32>3614}3615 3616// -----3617 3618// Insert a poison value shouldn't be folded as the resulting vector is not3619// fully poison.3620 3621// CHECK-LABEL: @insert_vector_poison3622func.func @insert_vector_poison(%a: vector<4x8xf32>)3623    -> vector<4x8xf32> {3624  //  CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<8xf32>3625  //  CHECK-NEXT: %[[RES:.*]] = vector.insert %[[UB]]3626  //  CHECK-NEXT: return %[[RES]] : vector<4x8xf32>3627  %0 = ub.poison : vector<8xf32>3628  %1 = vector.insert %0, %a[2] : vector<8xf32> into vector<4x8xf32>3629  return %1 : vector<4x8xf32>3630}3631 3632// -----3633 3634// CHECK-LABEL: @insert_scalar_poison_idx3635func.func @insert_scalar_poison_idx(%a: vector<4x5xf32>, %b: f32)3636    -> vector<4x5xf32> {3637  // CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<4x5xf32>3638  //  CHECK-NOT: vector.insert3639  // CHECK-NEXT: return %[[UB]] : vector<4x5xf32>3640  %0 = vector.insert %b, %a[-1, 0] : f32 into vector<4x5xf32>3641  return %0 : vector<4x5xf32>3642}3643 3644// -----3645 3646// CHECK-LABEL: @insert_vector_poison_idx3647func.func @insert_vector_poison_idx(%a: vector<4x5xf32>, %b: vector<5xf32>)3648    -> vector<4x5xf32> {3649  // CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<4x5xf32>3650  //  CHECK-NOT: vector.insert3651  // CHECK-NEXT: return %[[UB]] : vector<4x5xf32>3652  %0 = vector.insert %b, %a[-1] : vector<5xf32> into vector<4x5xf32>3653  return %0 : vector<4x5xf32>3654}3655 3656// -----3657 3658// Similar to the test above, but the index is not a static constant.3659 3660// CHECK-LABEL: @insert_vector_poison_idx_non_cst3661func.func @insert_vector_poison_idx_non_cst(%a: vector<4x5xf32>, %b: vector<5xf32>)3662    -> vector<4x5xf32> {3663  // CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<4x5xf32>3664  //  CHECK-NOT: vector.insert3665  // CHECK-NEXT: return %[[UB]] : vector<4x5xf32>3666  %c_neg_1 = arith.constant -1 : index3667  %0 = vector.insert %b, %a[%c_neg_1] : vector<5xf32> into vector<4x5xf32>3668  return %0 : vector<4x5xf32>3669}3670 3671// -----3672 3673// Similar to test above, but now the index is out-of-bounds.3674 3675// CHECK-LABEL: @no_fold_insert_scalar_idx_oob3676func.func @no_fold_insert_scalar_idx_oob(%a: vector<4x5xf32>, %b: vector<5xf32>)3677    -> vector<4x5xf32> {3678  //  CHECK: vector.insert3679  %c_neg_2 = arith.constant -2 : index3680  %0 = vector.insert %b, %a[%c_neg_2] : vector<5xf32> into vector<4x5xf32>3681  return %0 : vector<4x5xf32>3682}3683 3684// -----3685 3686// CHECK-LABEL: @insert_multiple_poison_idx3687func.func @insert_multiple_poison_idx(%a: vector<4x5x8xf32>, %b: vector<8xf32>)3688    -> vector<4x5x8xf32> {3689  // CHECK-NEXT: %[[UB:.*]] = ub.poison : vector<4x5x8xf32>3690  //  CHECK-NOT: vector.insert3691  // CHECK-NEXT: return %[[UB]] : vector<4x5x8xf32>3692  %0 = vector.insert %b, %a[-1, -1] : vector<8xf32> into vector<4x5x8xf32>3693  return %0 : vector<4x5x8xf32>3694}3695 3696// -----3697 3698// CHECK-LABEL: @contiguous_extract_strided_slices_to_extract_sizes_and_outer_source_dims_overlap3699// CHECK:        %[[EXTRACT:.+]] = vector.extract {{.*}}[0, 0, 0, 0, 0] : vector<4xi32> from vector<8x1x2x1x1x4xi32>3700// CHECK-NEXT:   return %[[EXTRACT]] :  vector<4xi32>3701func.func @contiguous_extract_strided_slices_to_extract_sizes_and_outer_source_dims_overlap(%arg0 : vector<8x1x2x1x1x4xi32>) -> vector<4xi32> {3702  %1 = vector.extract_strided_slice %arg0 {offsets = [0, 0, 0, 0, 0, 0], sizes = [1, 1, 1, 1, 1, 4], strides = [1, 1, 1, 1, 1, 1]} : vector<8x1x2x1x1x4xi32> to vector<1x1x1x1x1x4xi32>3703  %2 = vector.shape_cast %1 : vector<1x1x1x1x1x4xi32> to vector<4xi32>3704  return %2 : vector<4xi32>3705}3706 3707// -----3708 3709// CHECK-LABEL: @contiguous_extract_strided_slices_to_extract_sizes_and_outer_source_dims_no_overlap3710// CHECK:        %[[EXTRACT:.+]] = vector.extract {{.*}}[0, 0] : vector<4xi32> from vector<8x2x4xi32>3711// CHECK-NEXT:   return %[[EXTRACT]] :  vector<4xi32>3712func.func @contiguous_extract_strided_slices_to_extract_sizes_and_outer_source_dims_no_overlap(%arg0 : vector<8x2x4xi32>) -> vector<4xi32> {3713  %1 = vector.extract_strided_slice %arg0 {offsets = [0, 0], sizes = [1, 1], strides = [1, 1]} : vector<8x2x4xi32> to vector<1x1x4xi32>3714  %2 = vector.shape_cast %1 : vector<1x1x4xi32> to vector<4xi32>3715  return %2 : vector<4xi32>3716}3717 3718// -----3719 3720// CHECK-LABEL: @contiguous_extract_strided_slices_to_extract_shorter_size_list3721// CHECK:        %[[EXTRACT:.+]] = vector.extract {{.*}}[0, 0, 0, 0] : vector<1x4xi32> from vector<8x1x2x1x1x4xi32>3722// CHECK-NEXT:   return %[[EXTRACT]] :  vector<1x4xi32>3723func.func @contiguous_extract_strided_slices_to_extract_shorter_size_list(%arg0 : vector<8x1x2x1x1x4xi32>) -> vector<1x4xi32> {3724  %1 = vector.extract_strided_slice %arg0 {offsets = [0, 0, 0, 0, 0], sizes = [1, 1, 1, 1, 1], strides = [1, 1, 1, 1, 1]} : vector<8x1x2x1x1x4xi32> to vector<1x1x1x1x1x4xi32>3725  %2 = vector.shape_cast %1 : vector<1x1x1x1x1x4xi32> to vector<1x4xi32>3726  return %2 : vector<1x4xi32>3727}3728 3729// -----3730 3731// CHECK-LABEL: @contiguous_extract_strided_slices_to_extract_failure_non_unit_outer_size3732// CHECK-NEXT:   vector.extract_strided_slice3733func.func @contiguous_extract_strided_slices_to_extract_failure_non_unit_outer_size(%arg0 : vector<8x1x2x1x1x4xi32>) -> vector<8x1x1x1x1x4xi32> {3734  %1 = vector.extract_strided_slice %arg0 {offsets = [0, 0, 0, 0, 0, 0], sizes = [8, 1, 1, 1, 1, 4], strides = [1, 1, 1, 1, 1, 1]} : vector<8x1x2x1x1x4xi32> to vector<8x1x1x1x1x4xi32>3735  return %1 : vector<8x1x1x1x1x4xi32>3736}3737 3738// -----3739 3740// CHECK-LABEL: @contiguous_extract_strided_slices_to_extract_failure_non_full_size3741// CHECK-NEXT:   vector.extract_strided_slice3742func.func @contiguous_extract_strided_slices_to_extract_failure_non_full_size(%arg0 : vector<8x1x2x1x1x4xi32>) -> vector<1x1x1x1x1x2xi32> {3743  %1 = vector.extract_strided_slice %arg0 {offsets = [0, 0, 0, 0, 0, 0], sizes = [1, 1, 1, 1, 1, 2], strides = [1, 1, 1, 1, 1, 1]} : vector<8x1x2x1x1x4xi32> to vector<1x1x1x1x1x2xi32>3744  return %1 : vector<1x1x1x1x1x2xi32>3745}3746 3747// -----3748 3749// CHECK-LABEL: @contiguous_extract_strided_slices_to_extract_failure_non_full_inner_size3750// CHECK-NEXT:    vector.extract_strided_slice3751func.func @contiguous_extract_strided_slices_to_extract_failure_non_full_inner_size(%arg0 : vector<8x1x2x1x1x4xi32>) -> vector<1x1x2x1x1x1xi32> {3752  %1 = vector.extract_strided_slice %arg0 {offsets = [0, 0, 0, 0, 0, 0], sizes = [1, 1, 2, 1, 1, 1], strides = [1, 1, 1, 1, 1, 1]} : vector<8x1x2x1x1x4xi32> to vector<1x1x2x1x1x1xi32>3753  return %1 : vector<1x1x2x1x1x1xi32>3754}3755 3756// -----3757 3758// CHECK-LABEL: @contiguous_gather3759//  CHECK-SAME:   (%[[BASE:.*]]: memref<?xf32>, %[[MASK:.*]]: vector<16xi1>, %[[PASSTHRU:.*]]: vector<16xf32>)3760//       CHECK:   %[[C0:.*]] = arith.constant 0 : index3761//       CHECK:   %[[R:.*]] = vector.maskedload %[[BASE]][%[[C0]]], %[[MASK]], %[[PASSTHRU]] : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32>3762//       CHECK:   return %[[R]]3763func.func @contiguous_gather(%base: memref<?xf32>,3764                             %mask: vector<16xi1>, %passthru: vector<16xf32>) -> vector<16xf32> {3765  %c0 = arith.constant 0 : index3766  %indices = arith.constant dense<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]> : vector<16xi32>3767  %1 = vector.gather %base[%c0][%indices], %mask, %passthru :3768    memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32>3769  return %1 : vector<16xf32>3770}3771 3772// -----3773 3774// CHECK-LABEL: @contiguous_gather_non_zero_start(3775//  TODO: Non-zero start is not supported yet.3776//       CHECK:   %[[R:.*]] = vector.gather3777//       CHECK:   return %[[R]]3778func.func @contiguous_gather_non_zero_start(%base: memref<?xf32>,3779                                            %mask: vector<16xi1>,3780                                            %passthru: vector<16xf32>) -> vector<16xf32> {3781  %c0 = arith.constant 0 : index3782  %indices = arith.constant dense<[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]> : vector<16xi32>3783  %1 = vector.gather %base[%c0][%indices], %mask, %passthru :3784    memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32>3785  return %1 : vector<16xf32>3786}3787 3788// -----3789 3790// CHECK-LABEL: @contiguous_gather_2d(3791// TODO: Only 1D vectors are supported.3792//       CHECK:   %[[R:.*]] = vector.gather3793//       CHECK:   return %[[R]]3794func.func @contiguous_gather_2d(%base: memref<?x?xf32>,3795                                %mask: vector<4x4xi1>, %passthru: vector<4x4xf32>) -> vector<4x4xf32> {3796  %c0 = arith.constant 0 : index3797  %indices = arith.constant dense<[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]> : vector<4x4xi32>3798  %1 = vector.gather %base[%c0, %c0][%indices], %mask, %passthru :3799    memref<?x?xf32>, vector<4x4xi32>, vector<4x4xi1>, vector<4x4xf32> into vector<4x4xf32>3800  return %1 : vector<4x4xf32>3801}3802 3803// -----3804 3805// CHECK-LABEL: @contiguous_gather_const_mask3806//  CHECK-SAME:   (%[[BASE:.*]]: memref<?xf32>, %[[PASSTHRU:.*]]: vector<16xf32>)3807//       CHECK:   %[[C0:.*]] = arith.constant 0 : index3808//       CHECK:   %[[R:.*]] = vector.load %[[BASE]][%[[C0]]] : memref<?xf32>, vector<16xf32>3809//       CHECK:   return %[[R]]3810func.func @contiguous_gather_const_mask(%base: memref<?xf32>,3811                                        %passthru: vector<16xf32>) -> vector<16xf32> {3812  %c0 = arith.constant 0 : index3813  %indices = arith.constant dense<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]> : vector<16xi32>3814  %mask = arith.constant dense<true> : vector<16xi1>3815  %1 = vector.gather %base[%c0][%indices], %mask, %passthru :3816    memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32>3817  return %1 : vector<16xf32>3818}3819 3820// -----3821 3822// CHECK-LABEL: @contiguous_gather_step3823//  CHECK-SAME:   (%[[BASE:.*]]: memref<?xf32>, %[[MASK:.*]]: vector<16xi1>, %[[PASSTHRU:.*]]: vector<16xf32>)3824//       CHECK:   %[[C0:.*]] = arith.constant 0 : index3825//       CHECK:   %[[R:.*]] = vector.maskedload %[[BASE]][%[[C0]]], %[[MASK]], %[[PASSTHRU]] : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32>3826//       CHECK:   return %[[R]]3827func.func @contiguous_gather_step(%base: memref<?xf32>,3828                                  %mask: vector<16xi1>, %passthru: vector<16xf32>) -> vector<16xf32> {3829  %c0 = arith.constant 0 : index3830  %indices = vector.step : vector<16xindex>3831  %1 = vector.gather %base[%c0][%indices], %mask, %passthru :3832    memref<?xf32>, vector<16xindex>, vector<16xi1>, vector<16xf32> into vector<16xf32>3833  return %1 : vector<16xf32>3834}3835 3836// -----3837 3838// CHECK-LABEL: @no_fold_contiguous_gather_tensor3839func.func @no_fold_contiguous_gather_tensor(%base: tensor<8xf32>, %mask: vector<4xi1>, %pass_thru: vector<4xf32>) -> vector<4xf32> {3840  %c0 = arith.constant 0 : index3841  %indices = arith.constant dense<[0, 1, 2, 3]> : vector<4xindex>3842  // CHECK: vector.gather3843  // CHECK-NOT: vector.maskedload3844  %0 = vector.gather %base[%c0][%indices], %mask, %pass_thru :3845    tensor<8xf32>, vector<4xindex>, vector<4xi1>, vector<4xf32> into vector<4xf32>3846  return %0 : vector<4xf32>3847}3848 3849// -----3850 3851// CHECK-LABEL: @gather_broadcast(3852// TODO: Broadcast is not supported yet3853//       CHECK:   %[[R:.*]] = vector.gather3854//       CHECK:   return %[[R]]3855func.func @gather_broadcast(%base: memref<?xf32>,3856                             %mask: vector<16xi1>, %passthru: vector<16xf32>) -> vector<16xf32> {3857  %c0 = arith.constant 0 : index3858  %indices = arith.constant dense<0> : vector<16xi32>3859  %1 = vector.gather %base[%c0][%indices], %mask, %passthru :3860    memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32>3861  return %1 : vector<16xf32>3862}3863 3864// -----3865 3866// CHECK-LABEL: @contiguous_scatter3867//  CHECK-SAME:   (%[[BASE:.*]]: memref<?xf32>, %[[MASK:.*]]: vector<16xi1>, %[[VALUE:.*]]: vector<16xf32>)3868//       CHECK:   %[[C0:.*]] = arith.constant 0 : index3869//       CHECK:   vector.maskedstore %[[BASE]][%[[C0]]], %[[MASK]], %[[VALUE]] : memref<?xf32>, vector<16xi1>, vector<16xf32>3870func.func @contiguous_scatter(%base: memref<?xf32>,3871                              %mask: vector<16xi1>, %value: vector<16xf32>) {3872  %c0 = arith.constant 0 : index3873  %indices = arith.constant dense<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]> : vector<16xi32>3874  vector.scatter %base[%c0][%indices], %mask, %value :3875    memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32>3876  return3877}3878 3879// -----3880 3881// CHECK-LABEL: @contiguous_scatter_const_mask3882//  CHECK-SAME:   (%[[BASE:.*]]: memref<?xf32>, %[[VALUE:.*]]: vector<16xf32>)3883//       CHECK:   %[[C0:.*]] = arith.constant 0 : index3884//       CHECK:   vector.store %[[VALUE]], %[[BASE]][%[[C0]]] : memref<?xf32>, vector<16xf32>3885func.func @contiguous_scatter_const_mask(%base: memref<?xf32>,3886                                         %value: vector<16xf32>) {3887  %c0 = arith.constant 0 : index3888  %indices = arith.constant dense<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]> : vector<16xi32>3889  %mask = vector.constant_mask [16] : vector<16xi1>3890  vector.scatter %base[%c0][%indices], %mask, %value :3891    memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32>3892  return3893}3894 3895// -----3896 3897// CHECK-LABEL: @contiguous_scatter_step3898//  CHECK-SAME:   (%[[BASE:.*]]: memref<?xf32>, %[[MASK:.*]]: vector<16xi1>, %[[VALUE:.*]]: vector<16xf32>)3899//       CHECK:   %[[C0:.*]] = arith.constant 0 : index3900//       CHECK:   vector.maskedstore %[[BASE]][%[[C0]]], %[[MASK]], %[[VALUE]] : memref<?xf32>, vector<16xi1>, vector<16xf32>3901func.func @contiguous_scatter_step(%base: memref<?xf32>,3902                                   %mask: vector<16xi1>, %value: vector<16xf32>) {3903  %c0 = arith.constant 0 : index3904  %indices = vector.step : vector<16xindex>3905  vector.scatter %base[%c0][%indices], %mask, %value :3906    memref<?xf32>, vector<16xindex>, vector<16xi1>, vector<16xf32>3907  return3908}3909 3910// -----3911 3912// CHECK-LABEL: @fold_extract_constant_indices3913//   CHECK-SAME:   %[[ARG:.*]]: vector<32x1xi32>) -> i32 {3914//        CHECK:   %[[RES:.*]] = vector.extract %[[ARG]][0, 0] : i32 from vector<32x1xi32>3915//        CHECK:   return %[[RES]] : i323916func.func @fold_extract_constant_indices(%arg : vector<32x1xi32>) -> i32 {3917  %0 = arith.constant 0 : index3918  %1 = vector.extract %arg[%0, %0] : i32 from vector<32x1xi32>3919  return %1 : i323920}3921 3922// -----3923 3924// CHECK-LABEL: @fold_insert_constant_indices3925//  CHECK-SAME:   %[[ARG:.*]]: vector<4x1xi32>) -> vector<4x1xi32> {3926//       CHECK:   %[[VAL:.*]] = arith.constant 1 : i323927//       CHECK:   %[[RES:.*]] = vector.insert %[[VAL]], %[[ARG]] [0, 0] : i32 into vector<4x1xi32>3928//       CHECK:   return %[[RES]] : vector<4x1xi32>3929func.func @fold_insert_constant_indices(%arg : vector<4x1xi32>) -> vector<4x1xi32> {3930  %0 = arith.constant 0 : index3931  %1 = arith.constant 1 : i323932  %res = vector.insert %1, %arg[%0, %0] : i32 into vector<4x1xi32>3933  return %res : vector<4x1xi32>3934}3935 3936// -----3937 3938// CHECK-LABEL: @fold_insert_use_chain(3939//  CHECK-SAME:   %[[ARG:.*]]: vector<4x4xf32>,3940//  CHECK-SAME:   %[[VAL:.*]]: f32,3941//  CHECK-SAME:   %[[POS:.*]]: index) -> vector<4x4xf32> {3942//  CHECK-NEXT:   %[[RES:.*]] = vector.insert %[[VAL]], %[[ARG]] {{\[}}%[[POS]], 0] : f32 into vector<4x4xf32>3943//  CHECK-NEXT:   return %[[RES]] : vector<4x4xf32>3944func.func @fold_insert_use_chain(%arg : vector<4x4xf32>, %val : f32, %pos: index) -> vector<4x4xf32> {3945  %v_0 = vector.insert %val, %arg[%pos, 0] : f32 into vector<4x4xf32>3946  %v_1 = vector.insert %val, %v_0[%pos, 0] : f32 into vector<4x4xf32>3947  %v_2 = vector.insert %val, %v_1[%pos, 0] : f32 into vector<4x4xf32>3948  return %v_2 : vector<4x4xf32>3949}3950 3951// -----3952 3953// CHECK-LABEL: @no_fold_insert_use_chain_mismatch_static_position(3954//  CHECK-SAME:   %[[ARG:.*]]: vector<4xf32>,3955//  CHECK-SAME:   %[[VAL:.*]]: f32) -> vector<4xf32> {3956//       CHECK:   %[[V_0:.*]] = vector.insert %[[VAL]], %[[ARG]] [0] : f32 into vector<4xf32>3957//       CHECK:   %[[V_1:.*]] = vector.insert %[[VAL]], %[[V_0]] [1] : f32 into vector<4xf32>3958//       CHECK:   return %[[V_1]] : vector<4xf32>3959func.func @no_fold_insert_use_chain_mismatch_static_position(%arg : vector<4xf32>, %val : f32) -> vector<4xf32> {3960  %v_0 = vector.insert %val, %arg[0] : f32 into vector<4xf32>3961  %v_1 = vector.insert %val, %v_0[1] : f32 into vector<4xf32>3962  return %v_1 : vector<4xf32>3963}3964