brintos

brintos / llvm-project-archived public Read only

0
0
Text · 55.8 KiB · e02717a Raw
1357 lines · plain
1// RUN: mlir-opt %s -canonicalize="test-convergence" --split-input-file -allow-unregistered-dialect | FileCheck %s2 3 4// CHECK-LABEL: collapse_shape_identity_fold5// CHECK-NEXT: return6func.func @collapse_shape_identity_fold(%arg0 : memref<5xi8>) -> memref<5xi8> {7  %0 = memref.collapse_shape %arg0 [[0]] : memref<5xi8> into memref<5xi8>8  return %0 : memref<5xi8>9}10 11// -----12 13// CHECK-LABEL: expand_shape_identity_fold14// CHECK-NEXT: return15func.func @expand_shape_identity_fold(%arg0 : memref<5x4xi8>) -> memref<5x4xi8> {16  %0 = memref.expand_shape %arg0 [[0], [1]] output_shape [5, 4] : memref<5x4xi8> into memref<5x4xi8>17  return %0 : memref<5x4xi8>18}19 20// -----21 22// CHECK-LABEL: collapse_expand_rank0_cancel23// CHECK-NEXT: return24func.func @collapse_expand_rank0_cancel(%arg0 : memref<1x1xi8>) -> memref<1x1xi8> {25  %0 = memref.collapse_shape %arg0 [] : memref<1x1xi8> into memref<i8>26  %1 = memref.expand_shape %0 [] output_shape [1, 1] : memref<i8> into memref<1x1xi8>27  return %1 : memref<1x1xi8>28}29 30// -----31 32// CHECK-LABEL: func @subview_of_size_memcast33//  CHECK-SAME:   %[[ARG0:.[a-z0-9A-Z_]+]]: memref<4x6x16x32xi8>34//       CHECK:   %[[S:.+]] = memref.subview %[[ARG0]][0, 1, 0, 0] [1, 1, 16, 32] [1, 1, 1, 1] : memref<4x6x16x32xi8> to memref<16x32xi8, strided{{.*}}>35//       CHECK:   return %[[S]] : memref<16x32xi8, strided{{.*}}>36func.func @subview_of_size_memcast(%arg : memref<4x6x16x32xi8>) ->37  memref<16x32xi8, strided<[32, 1], offset: 512>>{38  %0 = memref.cast %arg : memref<4x6x16x32xi8> to memref<?x?x16x32xi8>39  %1 = memref.subview %0[0, 1, 0, 0] [1, 1, 16, 32] [1, 1, 1, 1] :40    memref<?x?x16x32xi8> to41    memref<16x32xi8, strided<[32, 1], offset: 512>>42  return %1 : memref<16x32xi8, strided<[32, 1], offset: 512>>43}44 45// -----46 47//       CHECK: func @subview_of_strides_memcast48//  CHECK-SAME:   %[[ARG0:.[a-z0-9A-Z_]+]]: memref<1x1x?xf32, strided{{.*}}>49//       CHECK:   %[[S:.+]] = memref.subview %[[ARG0]][0, 0, 0] [1, 1, 4]50//  CHECK-SAME:                    to memref<1x4xf32, strided<[7, 1], offset: ?>>51//       CHECK:   %[[M:.+]] = memref.cast %[[S]]52//  CHECK-SAME:                    to memref<1x4xf32, strided<[?, ?], offset: ?>>53//       CHECK:   return %[[M]]54func.func @subview_of_strides_memcast(%arg : memref<1x1x?xf32, strided<[35, 7, 1], offset: ?>>) -> memref<1x4xf32, strided<[?, ?], offset: ?>> {55  %0 = memref.cast %arg : memref<1x1x?xf32, strided<[35, 7, 1], offset: ?>> to memref<1x1x?xf32, strided<[?, ?, ?], offset: ?>>56  %1 = memref.subview %0[0, 0, 0] [1, 1, 4] [1, 1, 1] : memref<1x1x?xf32, strided<[?, ?, ?], offset: ?>> to memref<1x4xf32, strided<[?, ?], offset: ?>>57  return %1 : memref<1x4xf32, strided<[?, ?], offset: ?>>58}59 60// -----61 62// CHECK-LABEL: func @subview_of_static_full_size63// CHECK-SAME: %[[ARG0:.+]]: memref<4x6x16x32xi8>64// CHECK-NOT: memref.subview65// CHECK: return %[[ARG0]] : memref<4x6x16x32xi8>66func.func @subview_of_static_full_size(%arg0 : memref<4x6x16x32xi8>) -> memref<4x6x16x32xi8> {67  %0 = memref.subview %arg0[0, 0, 0, 0] [4, 6, 16, 32] [1, 1, 1, 1] : memref<4x6x16x32xi8> to memref<4x6x16x32xi8>68  return %0 : memref<4x6x16x32xi8>69}70 71// -----72 73// CHECK-LABEL: func @negative_subview_of_static_full_size74//  CHECK-SAME:   %[[ARG0:.+]]: memref<16x4xf32,  strided<[4, 1], offset: ?>>75//  CHECK-SAME:   %[[IDX:.+]]: index76//       CHECK:   %[[S:.+]] = memref.subview %[[ARG0]][%[[IDX]], 0] [16, 4] [1, 1]77//  CHECK-SAME:                    to memref<16x4xf32,  strided<[4, 1], offset: ?>>78//       CHECK:    return %[[S]] : memref<16x4xf32,  strided<[4, 1], offset: ?>>79func.func @negative_subview_of_static_full_size(%arg0:  memref<16x4xf32,  strided<[4, 1], offset: ?>>, %idx: index) -> memref<16x4xf32,  strided<[4, 1], offset: ?>> {80  %0 = memref.subview %arg0[%idx, 0][16, 4][1, 1] : memref<16x4xf32,  strided<[4, 1], offset: ?>> to memref<16x4xf32,  strided<[4, 1], offset: ?>>81  return %0 : memref<16x4xf32,  strided<[4, 1], offset: ?>>82}83 84// -----85 86func.func @subview_canonicalize(%arg0 : memref<?x?x?xf32>, %arg1 : index,87    %arg2 : index) -> memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>88{89  %c0 = arith.constant 0 : index90  %c1 = arith.constant 1 : index91  %c4 = arith.constant 4 : index92  %0 = memref.subview %arg0[%c0, %arg1, %c1] [%c4, %c1, %arg2] [%c1, %c1, %c1] : memref<?x?x?xf32> to memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>93  return %0 : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>94}95// CHECK-LABEL: func @subview_canonicalize96//  CHECK-SAME:   %[[ARG0:.+]]: memref<?x?x?xf32>97//       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG0]][0, %{{[a-zA-Z0-9_]+}}, 1]98//  CHECK-SAME:      [4, 1, %{{[a-zA-Z0-9_]+}}] [1, 1, 1]99//  CHECK-SAME:      : memref<?x?x?xf32> to memref<4x1x?xf32100//       CHECK:   %[[RESULT:.+]] = memref.cast %[[SUBVIEW]]101//       CHECK:   return %[[RESULT]]102 103// -----104 105func.func @rank_reducing_subview_canonicalize(%arg0 : memref<?x?x?xf32>, %arg1 : index,106  %arg2 : index) -> memref<?x?xf32, strided<[?, ?], offset: ?>>107{108  %c0 = arith.constant 0 : index109  %c1 = arith.constant 1 : index110  %c4 = arith.constant 4 : index111  %0 = memref.subview %arg0[%c0, %arg1, %c1] [%c4, 1, %arg2] [%c1, %c1, %c1] : memref<?x?x?xf32> to memref<?x?xf32, strided<[?, ?], offset: ?>>112  return %0 : memref<?x?xf32, strided<[?, ?], offset: ?>>113}114// CHECK-LABEL: func @rank_reducing_subview_canonicalize115//  CHECK-SAME:   %[[ARG0:.+]]: memref<?x?x?xf32>116//       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG0]][0, %{{[a-zA-Z0-9_]+}}, 1]117//  CHECK-SAME:      [4, 1, %{{[a-zA-Z0-9_]+}}] [1, 1, 1]118//  CHECK-SAME:      : memref<?x?x?xf32> to memref<4x?xf32119//       CHECK:   %[[RESULT:.+]] = memref.cast %[[SUBVIEW]]120//       CHECK:   return %[[RESULT]]121 122// -----123 124func.func @multiple_reducing_dims(%arg0 : memref<1x384x384xf32>,125    %arg1 : index, %arg2 : index, %arg3 : index) -> memref<?xf32, strided<[1], offset: ?>>126{127  %c1 = arith.constant 1 : index128  %0 = memref.subview %arg0[0, %arg1, %arg2] [1, %c1, %arg3] [1, 1, 1] : memref<1x384x384xf32> to memref<?x?xf32, strided<[384, 1], offset: ?>>129  %1 = memref.subview %0[0, 0] [1, %arg3] [1, 1] : memref<?x?xf32, strided<[384, 1], offset: ?>> to memref<?xf32, strided<[1], offset: ?>>130  return %1 : memref<?xf32, strided<[1], offset: ?>>131}132//       CHECK: func @multiple_reducing_dims133//       CHECK:   %[[REDUCED1:.+]] = memref.subview %{{.+}}[0, %{{.+}}, %{{.+}}] [1, 1, %{{.+}}] [1, 1, 1]134//  CHECK-SAME:       : memref<1x384x384xf32> to memref<1x?xf32, strided<[384, 1], offset: ?>>135//       CHECK:   %[[REDUCED2:.+]] = memref.subview %[[REDUCED1]][0, 0] [1, %{{.+}}] [1, 1]136//  CHECK-SAME:       : memref<1x?xf32, strided<[384, 1], offset: ?>> to memref<?xf32, strided<[1], offset: ?>>137 138// -----139 140func.func @multiple_reducing_dims_dynamic(%arg0 : memref<?x?x?xf32>,141    %arg1 : index, %arg2 : index, %arg3 : index) -> memref<?xf32, strided<[1], offset: ?>>142{143  %c1 = arith.constant 1 : index144  %0 = memref.subview %arg0[0, %arg1, %arg2] [1, %c1, %arg3] [1, 1, 1] : memref<?x?x?xf32> to memref<?x?xf32, strided<[?, 1], offset: ?>>145  %1 = memref.subview %0[0, 0] [1, %arg3] [1, 1] : memref<?x?xf32, strided<[?, 1], offset: ?>> to memref<?xf32, strided<[1], offset: ?>>146  return %1 : memref<?xf32, strided<[1], offset: ?>>147}148//       CHECK: func @multiple_reducing_dims_dynamic149//       CHECK:   %[[REDUCED1:.+]] = memref.subview %{{.+}}[0, %{{.+}}, %{{.+}}] [1, 1, %{{.+}}] [1, 1, 1]150//  CHECK-SAME:       : memref<?x?x?xf32> to memref<1x?xf32, strided<[?, 1], offset: ?>>151//       CHECK:   %[[REDUCED2:.+]] = memref.subview %[[REDUCED1]][0, 0] [1, %{{.+}}] [1, 1]152//  CHECK-SAME:       : memref<1x?xf32, strided<[?, 1], offset: ?>> to memref<?xf32, strided<[1], offset: ?>>153 154// -----155 156func.func @multiple_reducing_dims_all_dynamic(%arg0 : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>,157    %arg1 : index, %arg2 : index, %arg3 : index) -> memref<?xf32, strided<[?], offset: ?>>158{159  %c1 = arith.constant 1 : index160  %0 = memref.subview %arg0[0, %arg1, %arg2] [1, %c1, %arg3] [1, 1, 1]161      : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>> to memref<?x?xf32, strided<[?, ?], offset: ?>>162  %1 = memref.subview %0[0, 0] [1, %arg3] [1, 1] : memref<?x?xf32, strided<[?, ?], offset: ?>> to memref<?xf32, strided<[?], offset: ?>>163  return %1 : memref<?xf32, strided<[?], offset: ?>>164}165//       CHECK: func @multiple_reducing_dims_all_dynamic166//       CHECK:   %[[REDUCED1:.+]] = memref.subview %{{.+}}[0, %{{.+}}, %{{.+}}] [1, 1, %{{.+}}] [1, 1, 1]167//  CHECK-SAME:       : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>> to memref<1x?xf32, strided<[?, ?], offset: ?>>168//       CHECK:   %[[REDUCED2:.+]] = memref.subview %[[REDUCED1]][0, 0] [1, %{{.+}}] [1, 1]169//  CHECK-SAME:       : memref<1x?xf32, strided<[?, ?], offset: ?>> to memref<?xf32, strided<[?], offset: ?>>170 171// -----172 173func.func @subview_negative_stride1(%arg0 : memref<?xf32>) -> memref<?xf32, strided<[?], offset: ?>>174{175  %c0 = arith.constant 0 : index176  %c1 = arith.constant -1 : index177  %1 = memref.dim %arg0, %c0 : memref<?xf32>178  %2 = arith.addi %1, %c1 : index179  %3 = memref.subview %arg0[%2] [%1] [%c1] : memref<?xf32> to memref<?xf32, strided<[?], offset: ?>>180  return %3 : memref<?xf32, strided<[?], offset: ?>>181}182//       CHECK: func @subview_negative_stride1183//  CHECK-SAME:   (%[[ARG0:.*]]: memref<?xf32>)184//       CHECK:   %[[C1:.*]] = arith.constant 0185//       CHECK:   %[[C2:.*]] = arith.constant -1186//       CHECK:   %[[DIM1:.*]] = memref.dim %[[ARG0]], %[[C1]] : memref<?xf32>187//       CHECK:   %[[DIM2:.*]] = arith.addi %[[DIM1]], %[[C2]] : index188//       CHECK:   %[[RES1:.*]] = memref.subview %[[ARG0]][%[[DIM2]]] [%[[DIM1]]] [-1] : memref<?xf32> to memref<?xf32, strided<[-1], offset: ?>>189//       CHECK:   %[[RES2:.*]] = memref.cast %[[RES1]] : memref<?xf32, strided<[-1], offset: ?>> to memref<?xf32, strided<[?], offset: ?>>190//       CHECK:   return %[[RES2]] : memref<?xf32, strided<[?], offset: ?>>191 192// -----193 194func.func @subview_negative_stride2(%arg0 : memref<7xf32>) -> memref<?xf32, strided<[?], offset: ?>>195{196  %c0 = arith.constant 0 : index197  %c1 = arith.constant -1 : index198  %1 = memref.dim %arg0, %c0 : memref<7xf32>199  %2 = arith.addi %1, %c1 : index200  %3 = memref.subview %arg0[%2] [%1] [%c1] : memref<7xf32> to memref<?xf32, strided<[?], offset: ?>>201  return %3 : memref<?xf32, strided<[?], offset: ?>>202}203//       CHECK: func @subview_negative_stride2204//  CHECK-SAME:   (%[[ARG0:.*]]: memref<7xf32>)205//       CHECK:   %[[RES1:.*]] = memref.subview %[[ARG0]][6] [7] [-1] : memref<7xf32> to memref<7xf32, strided<[-1], offset: 6>>206//       CHECK:   %[[RES2:.*]] = memref.cast %[[RES1]] : memref<7xf32, strided<[-1], offset: 6>> to memref<?xf32, strided<[?], offset: ?>>207//       CHECK:   return %[[RES2]] : memref<?xf32, strided<[?], offset: ?>>208 209// -----210 211// CHECK-LABEL: func @no_fold_subview_negative_size212//  CHECK:        %[[SUBVIEW:.+]] = memref.subview213//  CHECK:        return %[[SUBVIEW]]214func.func @no_fold_subview_negative_size(%input: memref<4x1024xf32>) -> memref<?x256xf32, strided<[1024, 1], offset: 2304>> {215  %cst = arith.constant -13 : index216  %0 = memref.subview %input[2, 256] [%cst, 256] [1, 1] : memref<4x1024xf32> to memref<?x256xf32, strided<[1024, 1], offset: 2304>>217  return %0 : memref<?x256xf32, strided<[1024, 1], offset: 2304>>218}219 220// -----221 222// CHECK-LABEL: func @no_fold_subview_zero_stride223//  CHECK:        %[[SUBVIEW:.+]] = memref.subview224//  CHECK:        return %[[SUBVIEW]]225func.func @no_fold_subview_zero_stride(%arg0 : memref<10xf32>) -> memref<1xf32, strided<[?], offset: 1>> {226  %c0 = arith.constant 0 : index227  %c1 = arith.constant 1 : index228  %1 = memref.subview %arg0[1] [1] [%c0] : memref<10xf32> to memref<1xf32, strided<[?], offset: 1>>229  return %1 : memref<1xf32, strided<[?], offset: 1>>230}231 232// -----233 234// CHECK-LABEL: func @no_fold_of_store235//  CHECK:   %[[cst:.+]] = memref.cast %arg236//  CHECK:   memref.store %[[cst]]237func.func @no_fold_of_store(%arg : memref<32xi8>, %holder: memref<memref<?xi8>>) {238  %0 = memref.cast %arg : memref<32xi8> to memref<?xi8>239  memref.store %0, %holder[] : memref<memref<?xi8>>240  return241}242 243// -----244 245// Test case: Folding of memref.dim(memref.alloca(%size), %idx) -> %size246// CHECK-LABEL: func @dim_of_alloca(247//  CHECK-SAME:     %[[SIZE:[0-9a-z]+]]: index248//  CHECK-NEXT:   return %[[SIZE]] : index249func.func @dim_of_alloca(%size: index) -> index {250  %0 = memref.alloca(%size) : memref<?xindex>251  %c0 = arith.constant 0 : index252  %1 = memref.dim %0, %c0 : memref<?xindex>253  return %1 : index254}255 256// -----257 258// Test case: Folding of memref.dim(memref.alloca(rank(%v)), %idx) -> rank(%v)259// CHECK-LABEL: func @dim_of_alloca_with_dynamic_size(260//  CHECK-SAME:     %[[MEM:[0-9a-z]+]]: memref<*xf32>261//  CHECK-NEXT:   %[[RANK:.*]] = memref.rank %[[MEM]] : memref<*xf32>262//  CHECK-NEXT:   return %[[RANK]] : index263func.func @dim_of_alloca_with_dynamic_size(%arg0: memref<*xf32>) -> index {264  %0 = memref.rank %arg0 : memref<*xf32>265  %1 = memref.alloca(%0) : memref<?xindex>266  %c0 = arith.constant 0 : index267  %2 = memref.dim %1, %c0 : memref<?xindex>268  return %2 : index269}270 271// -----272 273// Test case: Folding of memref.dim(memref.reshape %v %shp, %idx) -> memref.load %shp[%idx]274// CHECK-LABEL: func @dim_of_memref_reshape(275//  CHECK-SAME:     %[[MEM:[0-9a-z]+]]: memref<*xf32>,276//  CHECK-SAME:     %[[SHP:[0-9a-z]+]]: memref<?xindex>277//  CHECK-NEXT:   %[[IDX:.*]] = arith.constant 3278//  CHECK-NEXT:   %[[DIM:.*]] = memref.load %[[SHP]][%[[IDX]]]279//  CHECK-NEXT:   memref.store280//   CHECK-NOT:   memref.dim281//       CHECK:   return %[[DIM]] : index282func.func @dim_of_memref_reshape(%arg0: memref<*xf32>, %arg1: memref<?xindex>)283    -> index {284  %c3 = arith.constant 3 : index285  %0 = memref.reshape %arg0(%arg1)286      : (memref<*xf32>, memref<?xindex>) -> memref<*xf32>287  // Update the shape to test that he load ends up in the right place.288  memref.store %c3, %arg1[%c3] : memref<?xindex>289  %1 = memref.dim %0, %c3 : memref<*xf32>290  return %1 : index291}292 293// -----294 295// Test case: Folding of memref.dim(memref.reshape %v %shp, %idx) -> memref.load %shp[%idx]296// CHECK-LABEL: func @dim_of_memref_reshape_i32(297//  CHECK-SAME:     %[[MEM:[0-9a-z]+]]: memref<*xf32>,298//  CHECK-SAME:     %[[SHP:[0-9a-z]+]]: memref<?xi32>299//  CHECK-NEXT:   %[[IDX:.*]] = arith.constant 3300//  CHECK-NEXT:   %[[DIM:.*]] = memref.load %[[SHP]][%[[IDX]]]301//  CHECK-NEXT:   %[[CAST:.*]] = arith.index_cast %[[DIM]]302//   CHECK-NOT:   memref.dim303//       CHECK:   return %[[CAST]] : index304func.func @dim_of_memref_reshape_i32(%arg0: memref<*xf32>, %arg1: memref<?xi32>)305    -> index {306  %c3 = arith.constant 3 : index307  %0 = memref.reshape %arg0(%arg1)308      : (memref<*xf32>, memref<?xi32>) -> memref<*xf32>309  %1 = memref.dim %0, %c3 : memref<*xf32>310  return %1 : index311}312 313// -----314 315// Test case: memref.dim(memref.reshape %v %shp, %idx) -> memref.load %shp[%idx]316// CHECK-LABEL: func @dim_of_memref_reshape_block_arg_index(317//  CHECK-SAME:   %[[MEM:[0-9a-z]+]]: memref<*xf32>,318//  CHECK-SAME:   %[[SHP:[0-9a-z]+]]: memref<?xindex>,319//  CHECK-SAME:   %[[IDX:[0-9a-z]+]]: index320//  CHECK-NEXT:   %[[DIM:.*]] = memref.load %[[SHP]][%[[IDX]]]321//   CHECK-NOT:   memref.dim322//       CHECK:   return %[[DIM]] : index323func.func @dim_of_memref_reshape_block_arg_index(%arg0: memref<*xf32>, %arg1: memref<?xindex>, %arg2: index) -> index {324  %reshape = memref.reshape %arg0(%arg1) : (memref<*xf32>, memref<?xindex>) -> memref<*xf32>325  %dim = memref.dim %reshape, %arg2 : memref<*xf32>326  return %dim : index327}328 329// -----330 331// Test case: memref.dim(memref.reshape %v %shp, %idx) is not folded into memref.load %shp[%idx]332// CHECK-LABEL: func @dim_of_memref_reshape_for(333//       CHECK: memref.reshape334//       CHECK: memref.dim335//   CHECK-NOT: memref.load336func.func @dim_of_memref_reshape_for( %arg0: memref<*xf32>, %arg1: memref<?xindex>) -> index {337    %c0 = arith.constant 0 : index338    %c1 = arith.constant 1 : index339    %c4 = arith.constant 4 : index340 341    %0 = memref.reshape %arg0(%arg1) : (memref<*xf32>, memref<?xindex>) -> memref<*xf32>342 343    %1 = scf.for %arg2 = %c0 to %c4 step %c1 iter_args(%arg3 = %c1) -> (index) {344      %2 = memref.dim %0, %arg2 : memref<*xf32>345      %3 = arith.muli %arg3, %2 : index346      scf.yield %3 : index347    }348    return %1 : index349}350 351// -----352 353// Test case: memref.dim(memref.reshape %v %shp, %idx) is not folded into memref.load %shp[%idx]354// CHECK-LABEL: func @dim_of_memref_reshape_undominated(355//       CHECK: memref.reshape356//       CHECK: memref.dim357//   CHECK-NOT: memref.load358func.func @dim_of_memref_reshape_undominated(%arg0: memref<*xf32>, %arg1: memref<?xindex>, %arg2: index) -> index {359    %c4 = arith.constant 4 : index360    %reshape = memref.reshape %arg0(%arg1) : (memref<*xf32>, memref<?xindex>) -> memref<*xf32>361    %0 = arith.muli %arg2, %c4 : index362    %dim = memref.dim %reshape, %0 : memref<*xf32>363    return %dim : index364  }365 366// -----367 368// CHECK-LABEL: func @alloc_const_fold369func.func @alloc_const_fold() -> memref<?xf32> {370  // CHECK-NEXT: memref.alloc() : memref<4xf32>371  %c4 = arith.constant 4 : index372  %a = memref.alloc(%c4) : memref<?xf32>373 374  // CHECK-NEXT: memref.cast %{{.*}} : memref<4xf32> to memref<?xf32>375  // CHECK-NEXT: return %{{.*}} : memref<?xf32>376  return %a : memref<?xf32>377}378 379// -----380 381// CHECK-LABEL: func @alloc_alignment_const_fold382func.func @alloc_alignment_const_fold() -> memref<?xf32> {383  // CHECK-NEXT: memref.alloc() {alignment = 4096 : i64} : memref<4xf32>384  %c4 = arith.constant 4 : index385  %a = memref.alloc(%c4) {alignment = 4096 : i64} : memref<?xf32>386 387  // CHECK-NEXT: memref.cast %{{.*}} : memref<4xf32> to memref<?xf32>388  // CHECK-NEXT: return %{{.*}} : memref<?xf32>389  return %a : memref<?xf32>390}391 392// -----393 394// CHECK-LABEL: func @alloc_const_fold_with_symbols1(395//  CHECK: %[[c1:.+]] = arith.constant 1 : index396//  CHECK: %[[mem1:.+]] = memref.alloc({{.*}})[%[[c1]], %[[c1]]] : memref<?xi32, strided{{.*}}>397//  CHECK: return %[[mem1]] : memref<?xi32, strided{{.*}}>398func.func @alloc_const_fold_with_symbols1(%arg0 : index) -> memref<?xi32, strided<[?], offset: ?>> {399  %c1 = arith.constant 1 : index400  %0 = memref.alloc(%arg0)[%c1, %c1] : memref<?xi32, strided<[?], offset: ?>>401  return %0 : memref<?xi32, strided<[?], offset: ?>>402}403 404// -----405 406// CHECK-LABEL: func @alloc_const_fold_with_symbols2(407//  CHECK: %[[c1:.+]] = arith.constant 1 : index408//  CHECK: %[[mem1:.+]] = memref.alloc()[%[[c1]], %[[c1]]] : memref<1xi32, strided{{.*}}>409//  CHECK: %[[mem2:.+]] = memref.cast %[[mem1]] : memref<1xi32, strided{{.*}}> to memref<?xi32, strided{{.*}}>410//  CHECK: return %[[mem2]] : memref<?xi32, strided{{.*}}>411func.func @alloc_const_fold_with_symbols2() -> memref<?xi32, strided<[?], offset: ?>> {412  %c1 = arith.constant 1 : index413  %0 = memref.alloc(%c1)[%c1, %c1] : memref<?xi32, strided<[?], offset: ?>>414  return %0 : memref<?xi32, strided<[?], offset: ?>>415}416 417// -----418// CHECK-LABEL: func @allocator419// CHECK:   %[[alloc:.+]] = memref.alloc420// CHECK:   memref.store %[[alloc:.+]], %arg0421func.func @allocator(%arg0 : memref<memref<?xi32>>, %arg1 : index)  {422  %0 = memref.alloc(%arg1) : memref<?xi32>423  memref.store %0, %arg0[] : memref<memref<?xi32>>424  return425}426 427// -----428 429func.func @compose_collapse_of_collapse_zero_dim(%arg0 : memref<1x1x1xf32>)430    -> memref<f32> {431  %0 = memref.collapse_shape %arg0 [[0, 1, 2]]432      : memref<1x1x1xf32> into memref<1xf32>433  %1 = memref.collapse_shape %0 [] : memref<1xf32> into memref<f32>434  return %1 : memref<f32>435}436// CHECK-LABEL: func @compose_collapse_of_collapse_zero_dim437//       CHECK:   memref.collapse_shape %{{.*}} []438//  CHECK-SAME:     memref<1x1x1xf32> into memref<f32>439 440// -----441 442func.func @compose_collapse_of_collapse(%arg0 : memref<?x?x?x?x?xf32>)443    -> memref<?x?xf32> {444  %0 = memref.collapse_shape %arg0 [[0, 1], [2], [3, 4]]445      : memref<?x?x?x?x?xf32> into memref<?x?x?xf32>446  %1 = memref.collapse_shape %0 [[0, 1], [2]]447      : memref<?x?x?xf32> into memref<?x?xf32>448  return %1 : memref<?x?xf32>449}450// CHECK-LABEL: func @compose_collapse_of_collapse451//       CHECK:   memref.collapse_shape %{{.*}} {{\[}}[0, 1, 2], [3, 4]]452//   CHECK-NOT:   memref.collapse_shape453 454// -----455 456func.func @compose_collapse_of_expand_partially_dynamic(%arg0: memref<?xf16>, %arg1: index, %arg2: index) -> memref<8x?x?xf16> {457  %expanded = memref.expand_shape %arg0 [[0, 1, 2, 3, 4]] output_shape [4, 2, %arg1, %arg2, 32] : memref<?xf16> into memref<4x2x?x?x32xf16>458  %collapsed = memref.collapse_shape %expanded [[0, 1], [2], [3, 4]] : memref<4x2x?x?x32xf16> into memref<8x?x?xf16>459  return %collapsed : memref<8x?x?xf16>460}461//       CHECK: func @compose_collapse_of_expand_partially_dynamic462//  CHECK-SAME:   %[[SRC:.[a-zA-Z0-9]+]]463//  CHECK-SAME:   %[[ORIG_D2:.[a-zA-Z0-9]+]]464//  CHECK-SAME:   %[[ORIG_D3:.[a-zA-Z0-9]+]]465//   CHECK-DAG:   %[[C32:.+]] = arith.constant 32466//       CHECK:   %[[COLLAPSED_D2:.+]] = arith.muli %[[ORIG_D3]], %[[C32]]467//       CHECK:   %[[RESULT:.+]] = memref.expand_shape %[[SRC]]468//  CHECK-SAME:     [0, 1, 2]469//  CHECK-SAME:     output_shape [8, %[[ORIG_D2]], %[[COLLAPSED_D2]]]470//       CHECK:   return %[[RESULT]]471 472// -----473 474func.func @do_not_compose_collapse_of_expand_non_identity_layout(475    %arg0: memref<?x?xf32, strided<[?, 1], offset: 0>>, %sz0: index, %sz1: index)476    -> memref<?xf32, strided<[?], offset: 0>> {477  %1 = memref.expand_shape %arg0 [[0, 1], [2]] output_shape [%sz0, 4, %sz1] :478    memref<?x?xf32, strided<[?, 1], offset: 0>> into479    memref<?x4x?xf32, strided<[?, ?, 1], offset: 0>>480  %2 = memref.collapse_shape %1 [[0, 1, 2]] :481    memref<?x4x?xf32, strided<[?, ?, 1], offset: 0>> into482    memref<?xf32, strided<[?], offset: 0>>483  return %2 : memref<?xf32, strided<[?], offset: 0>>484}485// CHECK-LABEL: func @do_not_compose_collapse_of_expand_non_identity_layout486// CHECK: expand487// CHECK: collapse488 489// -----490 491func.func @compose_expand_of_expand(%arg0 : memref<?x?xf32>, %sz0: index, %sz1: index, %sz2: index, %sz3: index)492    -> memref<?x6x4x5x?xf32> {493  %0 = memref.expand_shape %arg0 [[0, 1], [2]] output_shape [%sz0, 4, %sz1]494      : memref<?x?xf32> into memref<?x4x?xf32>495  %1 = memref.expand_shape %0 [[0, 1], [2], [3, 4]] output_shape [%sz2, 6, 4, 5, %sz3] : memref<?x4x?xf32> into memref<?x6x4x5x?xf32>496  return %1 : memref<?x6x4x5x?xf32>497}498// CHECK-LABEL: func @compose_expand_of_expand499//       CHECK:   memref.expand_shape %{{.*}} {{\[}}[0, 1, 2], [3, 4]] output_shape [%{{.*}}, 6, 4, 5, %{{.*}}]500//   CHECK-NOT:   memref.expand_shape501 502// -----503 504func.func @compose_expand_of_expand_of_zero_dim(%arg0 : memref<f32>)505    -> memref<1x1x1xf32> {506  %0 = memref.expand_shape %arg0 [] output_shape [1] : memref<f32> into memref<1xf32>507  %1 = memref.expand_shape %0 [[0, 1, 2]] output_shape [1, 1, 1]508      : memref<1xf32> into memref<1x1x1xf32>509  return %1 : memref<1x1x1xf32>510}511// CHECK-LABEL: func @compose_expand_of_expand_of_zero_dim512//       CHECK:   memref.expand_shape %{{.*}} [] output_shape [1, 1, 1]513//  CHECK-SAME:     memref<f32> into memref<1x1x1xf32>514 515// -----516 517func.func @fold_collapse_of_expand(%arg0 : memref<12x4xf32>) -> memref<12x4xf32> {518  %0 = memref.expand_shape %arg0 [[0, 1], [2]] output_shape [3, 4, 4]519      : memref<12x4xf32> into memref<3x4x4xf32>520  %1 = memref.collapse_shape %0 [[0, 1], [2]]521      : memref<3x4x4xf32> into memref<12x4xf32>522  return %1 : memref<12x4xf32>523}524// CHECK-LABEL: func @fold_collapse_of_expand525//   CHECK-NOT:   linalg.{{.*}}_shape526 527// -----528 529func.func @fold_collapse_collapse_of_expand(%arg0 : memref<?x?xf32>, %sz0: index, %sz1: index)530    -> memref<?x?xf32> {531  %0 = memref.expand_shape %arg0 [[0, 1], [2]] output_shape [%sz0, 4, %sz1]532      : memref<?x?xf32> into memref<?x4x?xf32>533  %1 = memref.collapse_shape %0 [[0, 1], [2]]534      : memref<?x4x?xf32> into memref<?x?xf32>535  return %1 : memref<?x?xf32>536}537// CHECK-LABEL: @fold_collapse_collapse_of_expand538//   CHECK-NOT:   linalg.{{.*}}_shape539 540// -----541 542func.func @fold_memref_expand_cast(%arg0 : memref<?x?xf32>) -> memref<2x4x4xf32> {543  %0 = memref.cast %arg0 : memref<?x?xf32> to memref<8x4xf32>544  %1 = memref.expand_shape %0 [[0, 1], [2]] output_shape [2, 4, 4]545      : memref<8x4xf32> into memref<2x4x4xf32>546  return %1 : memref<2x4x4xf32>547}548 549// CHECK-LABEL: @fold_memref_expand_cast550// CHECK: memref.expand_shape551 552// -----553 554// CHECK-LABEL:   func @collapse_after_memref_cast_type_change(555// CHECK-SAME:      %[[INPUT:.*]]: memref<?x512x1x1xf32>) -> memref<?x?xf32> {556// CHECK:           %[[COLLAPSED:.*]] = memref.collapse_shape %[[INPUT]]557// CHECK-SAME:         {{\[\[}}0], [1, 2, 3]] : memref<?x512x1x1xf32> into memref<?x512xf32>558// CHECK:           %[[DYNAMIC:.*]] = memref.cast %[[COLLAPSED]] :559// CHECK-SAME:         memref<?x512xf32> to memref<?x?xf32>560// CHECK:           return %[[DYNAMIC]] : memref<?x?xf32>561// CHECK:         }562func.func @collapse_after_memref_cast_type_change(%arg0 : memref<?x512x1x1xf32>) -> memref<?x?xf32> {563  %dynamic = memref.cast %arg0: memref<?x512x1x1xf32> to memref<?x?x?x?xf32>564  %collapsed = memref.collapse_shape %dynamic [[0], [1, 2, 3]] : memref<?x?x?x?xf32> into memref<?x?xf32>565  return %collapsed : memref<?x?xf32>566}567 568// -----569 570// CHECK-LABEL:   func @collapse_after_memref_cast(571// CHECK-SAME:      %[[INPUT:.*]]: memref<?x512x1x?xf32>) -> memref<?x?xf32> {572// CHECK:           %[[COLLAPSED:.*]] = memref.collapse_shape %[[INPUT]]573// CHECK-SAME:        {{\[\[}}0], [1, 2, 3]] : memref<?x512x1x?xf32> into memref<?x?xf32>574// CHECK:           return %[[COLLAPSED]] : memref<?x?xf32>575func.func @collapse_after_memref_cast(%arg0 : memref<?x512x1x?xf32>) -> memref<?x?xf32> {576  %dynamic = memref.cast %arg0: memref<?x512x1x?xf32> to memref<?x?x?x?xf32>577  %collapsed = memref.collapse_shape %dynamic [[0], [1, 2, 3]] : memref<?x?x?x?xf32> into memref<?x?xf32>578  return %collapsed : memref<?x?xf32>579}580 581// -----582 583// CHECK-LABEL:   func @collapse_after_memref_cast_type_change_dynamic(584// CHECK-SAME:      %[[INPUT:.*]]: memref<1x1x1x?xi64>) -> memref<?x?xi64> {585// CHECK:           %[[COLLAPSED:.*]] = memref.collapse_shape %[[INPUT]]586// CHECK-SAME:        {{\[\[}}0, 1, 2], [3]] : memref<1x1x1x?xi64> into memref<1x?xi64>587// CHECK:           %[[DYNAMIC:.*]] = memref.cast %[[COLLAPSED]] :588// CHECK-SAME:         memref<1x?xi64> to memref<?x?xi64>589// CHECK:           return %[[DYNAMIC]] : memref<?x?xi64>590func.func @collapse_after_memref_cast_type_change_dynamic(%arg0: memref<1x1x1x?xi64>) -> memref<?x?xi64> {591  %casted = memref.cast %arg0 : memref<1x1x1x?xi64> to memref<1x1x?x?xi64>592  %collapsed = memref.collapse_shape %casted [[0, 1, 2], [3]] : memref<1x1x?x?xi64> into memref<?x?xi64>593  return %collapsed : memref<?x?xi64>594}595 596// -----597 598func.func @reduced_memref(%arg0: memref<2x5x7x1xf32>, %arg1 :index)599    -> memref<1x4x1xf32, strided<[35, 7, 1], offset: ?>> {600  %c0 = arith.constant 0 : index601  %c5 = arith.constant 5 : index602  %c4 = arith.constant 4 : index603  %c2 = arith.constant 2 : index604  %c1 = arith.constant 1 : index605  %0 = memref.subview %arg0[%arg1, %arg1, %arg1, 0] [%c1, %c4, %c1, 1] [1, 1, 1, 1]606      : memref<2x5x7x1xf32> to memref<?x?x?xf32, strided<[35, 7, 1], offset: ?>>607  %1 = memref.cast %0608      : memref<?x?x?xf32, strided<[35, 7, 1], offset: ?>> to609        memref<1x4x1xf32, strided<[35, 7, 1], offset: ?>>610  return %1 : memref<1x4x1xf32, strided<[35, 7, 1], offset: ?>>611}612 613// CHECK-LABEL: func @reduced_memref614//       CHECK:   %[[RESULT:.+]] = memref.subview615//  CHECK-SAME:       memref<2x5x7x1xf32> to memref<1x4x1xf32, strided{{.+}}>616//       CHECK:   return %[[RESULT]]617 618// -----619 620// CHECK-LABEL: func @fold_rank_memref621func.func @fold_rank_memref(%arg0 : memref<?x?xf32>) -> (index) {622  // Fold a rank into a constant623  // CHECK-NEXT: [[C2:%.+]] = arith.constant 2 : index624  %rank_0 = memref.rank %arg0 : memref<?x?xf32>625 626  // CHECK-NEXT: return [[C2]]627  return %rank_0 : index628}629 630// -----631 632func.func @fold_no_op_subview(%arg0 : memref<20x42xf32>) -> memref<20x42xf32, strided<[42, 1]>> {633  %0 = memref.subview %arg0[0, 0] [20, 42] [1, 1] : memref<20x42xf32> to memref<20x42xf32, strided<[42, 1]>>634  return %0 : memref<20x42xf32, strided<[42, 1]>>635}636// CHECK-LABEL: func @fold_no_op_subview(637//       CHECK:   %[[ARG0:.+]]: memref<20x42xf32>)638//       CHECK:   %[[CAST:.+]] = memref.cast %[[ARG0]]639//       CHECK:   return %[[CAST]]640 641// -----642 643func.func @no_fold_subview_with_non_zero_offset(%arg0 : memref<20x42xf32>) -> memref<20x41xf32, strided<[42, 1], offset: 1>> {644  %0 = memref.subview %arg0[0, 1] [20, 41] [1, 1] : memref<20x42xf32> to memref<20x41xf32, strided<[42, 1], offset: 1>>645  return %0 : memref<20x41xf32, strided<[42, 1], offset: 1>>646}647// CHECK-LABEL: func @no_fold_subview_with_non_zero_offset(648//       CHECK:   %[[SUBVIEW:.+]] = memref.subview649//       CHECK:    return %[[SUBVIEW]]650 651// -----652 653func.func @no_fold_subview_with_non_unit_stride(%arg0 : memref<20x42xf32>) -> memref<20x5xf32, strided<[42, 2]>> {654  %0 = memref.subview %arg0[0, 0] [20, 5] [1, 2] : memref<20x42xf32> to memref<20x5xf32, strided<[42, 2]>>655  return %0 : memref<20x5xf32, strided<[42, 2]>>656}657// CHECK-LABEL: func @no_fold_subview_with_non_unit_stride(658//       CHECK:   %[[SUBVIEW:.+]] = memref.subview659//       CHECK:    return %[[SUBVIEW]]660 661// -----662 663// CHECK-LABEL: func @no_fold_invalid_dynamic_slice664//       CHECK:   memref.subview %arg0[2] [%{{.*}}] [1] : memref<10xf32> to memref<?xf32, strided<[1], offset: 2>>665func.func @no_fold_invalid_dynamic_slice(%arg0: memref<10xf32>) -> memref<?xf32, strided<[1], offset: 2>> {666  %c11 = arith.constant 11 : index667  %0 = memref.subview %arg0 [2][%c11][1] : memref<10xf32> to memref<?xf32, strided<[1], offset: 2>>668  func.return %0 : memref<?xf32, strided<[1], offset: 2>>669}670 671// -----672 673func.func @no_fold_dynamic_no_op_subview(%arg0 : memref<?x?xf32>) -> memref<?x?xf32, strided<[?, 1]>> {674  %c0 = arith.constant 0 : index675  %c1 = arith.constant 1 : index676  %0 = memref.dim %arg0, %c0 : memref<?x?xf32>677  %1 = memref.dim %arg0, %c1 : memref<?x?xf32>678  %2 = memref.subview %arg0[0, 0] [%0, %1] [1, 1] : memref<?x?xf32> to memref<?x?xf32, strided<[?, 1]>>679  return %2 : memref<?x?xf32, strided<[?, 1]>>680}681// CHECK-LABEL: func @no_fold_dynamic_no_op_subview(682//       CHECK:   %[[SUBVIEW:.+]] = memref.subview683//       CHECK:    return %[[SUBVIEW]]684 685// -----686 687func.func @atomicrmw_cast_fold(%arg0 : f32, %arg1 : memref<4xf32>, %c : index) {688  %v = memref.cast %arg1 : memref<4xf32> to memref<?xf32>689  %a = memref.atomic_rmw addf %arg0, %v[%c] : (f32, memref<?xf32>) -> f32690  return691}692 693// CHECK-LABEL: func @atomicrmw_cast_fold694// CHECK-NEXT: memref.atomic_rmw addf %arg0, %arg1[%arg2] : (f32, memref<4xf32>) -> f32695 696// -----697 698func.func @copy_of_cast(%m1: memref<?xf32>, %m2: memref<*xf32>) {699  %casted1 = memref.cast %m1 : memref<?xf32> to memref<?xf32, strided<[?], offset: ?>>700  %casted2 = memref.cast %m2 : memref<*xf32> to memref<?xf32, strided<[?], offset: ?>>701  memref.copy %casted1, %casted2 : memref<?xf32, strided<[?], offset: ?>> to memref<?xf32, strided<[?], offset: ?>>702  return703}704 705// CHECK-LABEL: func @copy_of_cast(706//  CHECK-SAME:     %[[m1:.*]]: memref<?xf32>, %[[m2:.*]]: memref<*xf32>707//       CHECK:   %[[casted2:.*]] = memref.cast %[[m2]]708//       CHECK:   memref.copy %[[m1]], %[[casted2]]709 710// -----711 712func.func @self_copy(%m1: memref<?xf32>) {713  memref.copy %m1, %m1 : memref<?xf32> to memref<?xf32>714  return715}716 717// CHECK-LABEL: func @self_copy718//  CHECK-NEXT:   return719 720// -----721 722// CHECK-LABEL: func @empty_copy723//  CHECK-NEXT:   return724func.func @empty_copy(%m1: memref<0x10xf32>, %m2: memref<?x10xf32>) {725  memref.copy %m1, %m2 : memref<0x10xf32> to memref<?x10xf32>726  memref.copy %m2, %m1 : memref<?x10xf32> to memref<0x10xf32>727  return728}729 730// -----731 732func.func @scopeMerge() {733  memref.alloca_scope {734    %cnt = "test.count"() : () -> index735    %a = memref.alloca(%cnt) : memref<?xi64>736    "test.use"(%a) : (memref<?xi64>) -> ()737  }738  return739}740// CHECK:   func @scopeMerge() {741// CHECK-NOT: alloca_scope742// CHECK:     %[[cnt:.+]] = "test.count"() : () -> index743// CHECK:     %[[alloc:.+]] = memref.alloca(%[[cnt]]) : memref<?xi64>744// CHECK:     "test.use"(%[[alloc]]) : (memref<?xi64>) -> ()745// CHECK:     return746 747// -----748 749func.func @scopeMerge2() {750  "test.region"() ({751    memref.alloca_scope {752      %cnt = "test.count"() : () -> index753      %a = memref.alloca(%cnt) : memref<?xi64>754      "test.use"(%a) : (memref<?xi64>) -> ()755    }756    "test.terminator"() : () -> ()757  }) : () -> ()758  return759}760 761// CHECK:   func @scopeMerge2() {762// CHECK:     "test.region"() ({763// CHECK:       memref.alloca_scope {764// CHECK:         %[[cnt:.+]] = "test.count"() : () -> index765// CHECK:         %[[alloc:.+]] = memref.alloca(%[[cnt]]) : memref<?xi64>766// CHECK:         "test.use"(%[[alloc]]) : (memref<?xi64>) -> ()767// CHECK:       }768// CHECK:       "test.terminator"() : () -> ()769// CHECK:     }) : () -> ()770// CHECK:     return771// CHECK:   }772 773// -----774 775func.func @scopeMerge3() {776  %cnt = "test.count"() : () -> index777  "test.region"() ({778    memref.alloca_scope {779      %a = memref.alloca(%cnt) : memref<?xi64>780      "test.use"(%a) : (memref<?xi64>) -> ()781    }782    "test.terminator"() : () -> ()783  }) : () -> ()784  return785}786 787// CHECK:   func @scopeMerge3() {788// CHECK:     %[[cnt:.+]] = "test.count"() : () -> index789// CHECK:     %[[alloc:.+]] = memref.alloca(%[[cnt]]) : memref<?xi64>790// CHECK:     "test.region"() ({791// CHECK:       memref.alloca_scope {792// CHECK:         "test.use"(%[[alloc]]) : (memref<?xi64>) -> ()793// CHECK:       }794// CHECK:       "test.terminator"() : () -> ()795// CHECK:     }) : () -> ()796// CHECK:     return797// CHECK:   }798 799// -----800 801func.func @scopeMerge4() {802  %cnt = "test.count"() : () -> index803  "test.region"() ({804    memref.alloca_scope {805      %a = memref.alloca(%cnt) : memref<?xi64>806      "test.use"(%a) : (memref<?xi64>) -> ()807    }808    "test.op"() : () -> ()809    "test.terminator"() : () -> ()810  }) : () -> ()811  return812}813 814// CHECK:   func @scopeMerge4() {815// CHECK:     %[[cnt:.+]] = "test.count"() : () -> index816// CHECK:     "test.region"() ({817// CHECK:       memref.alloca_scope {818// CHECK:         %[[alloc:.+]] = memref.alloca(%[[cnt]]) : memref<?xi64>819// CHECK:         "test.use"(%[[alloc]]) : (memref<?xi64>) -> ()820// CHECK:       }821// CHECK:       "test.op"() : () -> ()822// CHECK:       "test.terminator"() : () -> ()823// CHECK:     }) : () -> ()824// CHECK:     return825// CHECK:   }826 827// -----828 829func.func @scopeMerge5() {830  "test.region"() ({831    memref.alloca_scope {832      affine.parallel (%arg) = (0) to (64) {833        %a = memref.alloca(%arg) : memref<?xi64>834        "test.use"(%a) : (memref<?xi64>) -> ()835      }836    }837    "test.op"() : () -> ()838    "test.terminator"() : () -> ()839  }) : () -> ()840  return841}842 843// CHECK:   func @scopeMerge5() {844// CHECK:     "test.region"() ({845// CHECK:       affine.parallel (%[[cnt:.+]]) = (0) to (64) {846// CHECK:         %[[alloc:.+]] = memref.alloca(%[[cnt]]) : memref<?xi64>847// CHECK:         "test.use"(%[[alloc]]) : (memref<?xi64>) -> ()848// CHECK:       }849// CHECK:       "test.op"() : () -> ()850// CHECK:       "test.terminator"() : () -> ()851// CHECK:     }) : () -> ()852// CHECK:     return853// CHECK:   }854 855// -----856 857func.func @scopeInline(%arg : memref<index>) {858  %cnt = "test.count"() : () -> index859  "test.region"() ({860    memref.alloca_scope {861      memref.store %cnt, %arg[] : memref<index>862    }863    "test.terminator"() : () -> ()864  }) : () -> ()865  return866}867 868// CHECK:   func @scopeInline869// CHECK-NOT:  memref.alloca_scope870 871// -----872 873// Ensure this case not crash.874 875// CHECK-LABEL:   func.func @scope_merge_without_terminator() {876// CHECK:           "test.region"()877// CHECK:             memref.alloca_scope878func.func @scope_merge_without_terminator() {879  "test.region"() ({880    memref.alloca_scope {881      %cnt = "test.count"() : () -> index882      %a = memref.alloca(%cnt) : memref<?xi64>883      "test.use"(%a) : (memref<?xi64>) -> ()884    }885  }) : () -> ()886  return887}888 889// -----890 891// Check that we simplify extract_strided_metadata of cast892// when the source of the cast is compatible with what893// `extract_strided_metadata`s accept.894//895// When we apply the transformation the resulting offset, sizes and strides896// should come straight from the inputs of the cast.897// Additionally the folder on extract_strided_metadata should propagate the898// static information.899//900// CHECK-LABEL: func @extract_strided_metadata_of_cast901//  CHECK-SAME: %[[ARG:.*]]: memref<3x?xi32, strided<[4, ?], offset: ?>>)902//903//   CHECK-DAG: %[[C3:.*]] = arith.constant 3 : index904//   CHECK-DAG: %[[C4:.*]] = arith.constant 4 : index905//       CHECK: %[[BASE:.*]], %[[DYN_OFFSET:.*]], %[[DYN_SIZES:.*]]:2, %[[DYN_STRIDES:.*]]:2 = memref.extract_strided_metadata %[[ARG]]906//907//       CHECK: return %[[BASE]], %[[DYN_OFFSET]], %[[C3]], %[[DYN_SIZES]]#1, %[[C4]], %[[DYN_STRIDES]]#1908func.func @extract_strided_metadata_of_cast(909  %arg : memref<3x?xi32, strided<[4, ?], offset:?>>)910  -> (memref<i32>, index,911      index, index,912      index, index) {913 914  %cast =915    memref.cast %arg :916      memref<3x?xi32, strided<[4, ?], offset: ?>> to917      memref<?x?xi32, strided<[?, ?], offset: ?>>918 919  %base, %base_offset, %sizes:2, %strides:2 =920    memref.extract_strided_metadata %cast:memref<?x?xi32, strided<[?, ?], offset: ?>>921    -> memref<i32>, index,922       index, index,923       index, index924 925  return %base, %base_offset,926    %sizes#0, %sizes#1,927    %strides#0, %strides#1 :928      memref<i32>, index,929      index, index,930      index, index931}932 933// -----934 935// Check that we simplify extract_strided_metadata of cast936// when the source of the cast is compatible with what937// `extract_strided_metadata`s accept.938//939// Same as extract_strided_metadata_of_cast but with constant sizes and strides940// in the destination type.941//942// CHECK-LABEL: func @extract_strided_metadata_of_cast_w_csts943//  CHECK-SAME: %[[ARG:.*]]: memref<?x?xi32, strided<[?, ?], offset: ?>>)944//945//   CHECK-DAG: %[[C4:.*]] = arith.constant 4 : index946//   CHECK-DAG: %[[C18:.*]] = arith.constant 18 : index947//   CHECK-DAG: %[[C25:.*]] = arith.constant 25 : index948//       CHECK: %[[BASE:.*]], %[[DYN_OFFSET:.*]], %[[DYN_SIZES:.*]]:2, %[[DYN_STRIDES:.*]]:2 = memref.extract_strided_metadata %[[ARG]]949//950//       CHECK: return %[[BASE]], %[[C25]], %[[C4]], %[[DYN_SIZES]]#1, %[[DYN_STRIDES]]#0, %[[C18]]951func.func @extract_strided_metadata_of_cast_w_csts(952  %arg : memref<?x?xi32, strided<[?, ?], offset:?>>)953  -> (memref<i32>, index,954      index, index,955      index, index) {956 957  %cast =958    memref.cast %arg :959      memref<?x?xi32, strided<[?, ?], offset: ?>> to960      memref<4x?xi32, strided<[?, 18], offset: 25>>961 962  %base, %base_offset, %sizes:2, %strides:2 =963    memref.extract_strided_metadata %cast:memref<4x?xi32, strided<[?, 18], offset: 25>>964    -> memref<i32>, index,965       index, index,966       index, index967 968  return %base, %base_offset,969    %sizes#0, %sizes#1,970    %strides#0, %strides#1 :971      memref<i32>, index,972      index, index,973      index, index974}975 976// -----977 978// Check that we don't simplify extract_strided_metadata of979// cast when the source of the cast is unranked.980// Unranked memrefs cannot feed into extract_strided_metadata operations.981// Note: Technically we could still fold the sizes and strides.982//983// CHECK-LABEL: func @extract_strided_metadata_of_cast_unranked984//  CHECK-SAME: %[[ARG:.*]]: memref<*xi32>)985//986//       CHECK: %[[CAST:.*]] = memref.cast %[[ARG]] :987//       CHECK: %[[BASE:.*]], %[[OFFSET:.*]], %[[SIZES:.*]]:2, %[[STRIDES:.*]]:2 = memref.extract_strided_metadata %[[CAST]]988//989//       CHECK: return %[[BASE]], %[[OFFSET]], %[[SIZES]]#0, %[[SIZES]]#1, %[[STRIDES]]#0, %[[STRIDES]]#1990func.func @extract_strided_metadata_of_cast_unranked(991  %arg : memref<*xi32>)992  -> (memref<i32>, index,993      index, index,994      index, index) {995 996  %cast =997    memref.cast %arg :998      memref<*xi32> to999      memref<?x?xi32, strided<[?, ?], offset: ?>>1000 1001  %base, %base_offset, %sizes:2, %strides:2 =1002    memref.extract_strided_metadata %cast:memref<?x?xi32, strided<[?, ?], offset: ?>>1003    -> memref<i32>, index,1004       index, index,1005       index, index1006 1007  return %base, %base_offset,1008    %sizes#0, %sizes#1,1009    %strides#0, %strides#1 :1010      memref<i32>, index,1011      index, index,1012      index, index1013}1014 1015// -----1016 1017// CHECK-LABEL: func @reinterpret_noop1018//  CHECK-SAME: (%[[ARG:.*]]: memref<2x3x4xf32>)1019//  CHECK-NEXT: return %[[ARG]]1020func.func @reinterpret_noop(%arg : memref<2x3x4xf32>) -> memref<2x3x4xf32> {1021  %0 = memref.reinterpret_cast %arg to offset: [0], sizes: [2, 3, 4], strides: [12, 4, 1] : memref<2x3x4xf32> to memref<2x3x4xf32>1022  return %0 : memref<2x3x4xf32>1023}1024 1025// -----1026 1027// CHECK-LABEL: func @reinterpret_constant_fold1028//  CHECK-SAME: (%[[ARG:.*]]: memref<f32>)1029//       CHECK: %[[RES:.*]] = memref.reinterpret_cast %[[ARG]] to offset: [0], sizes: [100, 100], strides: [100, 1]1030//       CHECK: %[[CAST:.*]] = memref.cast %[[RES]]1031//       CHECK: return %[[CAST]]1032func.func @reinterpret_constant_fold(%arg0: memref<f32>) -> memref<?x?xf32, strided<[?, ?], offset: ?>> {1033  %c0 = arith.constant 0 : index1034  %c1 = arith.constant 1 : index1035  %c100 = arith.constant 100 : index1036  %reinterpret_cast = memref.reinterpret_cast %arg0 to offset: [%c0], sizes: [%c100, %c100], strides: [%c100, %c1] : memref<f32> to memref<?x?xf32, strided<[?, ?], offset: ?>>1037  return %reinterpret_cast : memref<?x?xf32, strided<[?, ?], offset: ?>>1038}1039 1040// -----1041 1042// CHECK-LABEL: func @reinterpret_of_reinterpret1043//  CHECK-SAME: (%[[ARG:.*]]: memref<?xi8>, %[[SIZE1:.*]]: index, %[[SIZE2:.*]]: index)1044//       CHECK: %[[RES:.*]] = memref.reinterpret_cast %[[ARG]] to offset: [0], sizes: [%[[SIZE2]]], strides: [1]1045//       CHECK: return %[[RES]]1046func.func @reinterpret_of_reinterpret(%arg : memref<?xi8>, %size1: index, %size2: index) -> memref<?xi8> {1047  %0 = memref.reinterpret_cast %arg to offset: [0], sizes: [%size1], strides: [1] : memref<?xi8> to memref<?xi8>1048  %1 = memref.reinterpret_cast %0 to offset: [0], sizes: [%size2], strides: [1] : memref<?xi8> to memref<?xi8>1049  return %1 : memref<?xi8>1050}1051 1052// -----1053 1054// CHECK-LABEL: func @reinterpret_of_cast1055//  CHECK-SAME: (%[[ARG:.*]]: memref<?xi8>, %[[SIZE:.*]]: index)1056//       CHECK: %[[RES:.*]] = memref.reinterpret_cast %[[ARG]] to offset: [0], sizes: [%[[SIZE]]], strides: [1]1057//       CHECK: return %[[RES]]1058func.func @reinterpret_of_cast(%arg : memref<?xi8>, %size: index) -> memref<?xi8> {1059  %0 = memref.cast %arg : memref<?xi8> to memref<5xi8>1060  %1 = memref.reinterpret_cast %0 to offset: [0], sizes: [%size], strides: [1] : memref<5xi8> to memref<?xi8>1061  return %1 : memref<?xi8>1062}1063 1064// -----1065 1066// CHECK-LABEL: func @reinterpret_of_subview1067//  CHECK-SAME: (%[[ARG:.*]]: memref<?xi8>, %[[SIZE1:.*]]: index, %[[SIZE2:.*]]: index)1068//       CHECK: %[[RES:.*]] = memref.reinterpret_cast %[[ARG]] to offset: [0], sizes: [%[[SIZE2]]], strides: [1]1069//       CHECK: return %[[RES]]1070func.func @reinterpret_of_subview(%arg : memref<?xi8>, %size1: index, %size2: index) -> memref<?xi8> {1071  %0 = memref.subview %arg[0] [%size1] [1] : memref<?xi8> to memref<?xi8>1072  %1 = memref.reinterpret_cast %0 to offset: [0], sizes: [%size2], strides: [1] : memref<?xi8> to memref<?xi8>1073  return %1 : memref<?xi8>1074}1075 1076// -----1077 1078// Check that a reinterpret cast of an equivalent extract strided metadata1079// is canonicalized to a plain cast when the destination type is different1080// than the type of the original memref.1081// CHECK-LABEL: func @reinterpret_of_extract_strided_metadata_w_type_mistach1082//  CHECK-SAME: (%[[ARG:.*]]: memref<8x2xf32>)1083//       CHECK: %[[CAST:.*]] = memref.cast %[[ARG]] : memref<8x2xf32> to memref<?x?xf32,1084//       CHECK: return %[[CAST]]1085func.func @reinterpret_of_extract_strided_metadata_w_type_mistach(%arg0 : memref<8x2xf32>) -> memref<?x?xf32, strided<[?, ?], offset: ?>> {1086  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %arg0 : memref<8x2xf32> -> memref<f32>, index, index, index, index, index1087  %m2 = memref.reinterpret_cast %base to offset: [%offset], sizes: [%sizes#0, %sizes#1], strides: [%strides#0, %strides#1] : memref<f32> to memref<?x?xf32, strided<[?, ?], offset: ?>>1088  return %m2 : memref<?x?xf32, strided<[?, ?], offset: ?>>1089}1090 1091// -----1092 1093// Similar to reinterpret_of_extract_strided_metadata_w_type_mistach except that1094// we check that the match happen when the static information has been folded.1095// E.g., in this case, we know that size of dim 0 is 8 and size of dim 1 is 2.1096// So even if we don't use the values sizes#0, sizes#1, as long as they have the1097// same constant value, the match is valid.1098// CHECK-LABEL: func @reinterpret_of_extract_strided_metadata_w_constants1099//  CHECK-SAME: (%[[ARG:.*]]: memref<8x2xf32>)1100//       CHECK: %[[CAST:.*]] = memref.cast %[[ARG]] : memref<8x2xf32> to memref<?x?xf32,1101//       CHECK: return %[[CAST]]1102func.func @reinterpret_of_extract_strided_metadata_w_constants(%arg0 : memref<8x2xf32>) -> memref<?x?xf32, strided<[?, ?], offset: ?>> {1103  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %arg0 : memref<8x2xf32> -> memref<f32>, index, index, index, index, index1104  %c8 = arith.constant 8: index1105  %m2 = memref.reinterpret_cast %base to offset: [0], sizes: [%c8, 2], strides: [2, %strides#1] : memref<f32> to memref<?x?xf32, strided<[?, ?], offset: ?>>1106  return %m2 : memref<?x?xf32, strided<[?, ?], offset: ?>>1107}1108// -----1109 1110// Check that a reinterpret cast of an equivalent extract strided metadata1111// is completely removed when the original memref has the same type.1112// CHECK-LABEL: func @reinterpret_of_extract_strided_metadata_same_type1113//  CHECK-SAME: (%[[ARG:.*]]: memref<?x?xf321114//       CHECK: return %[[ARG]]1115func.func @reinterpret_of_extract_strided_metadata_same_type(%arg0 : memref<?x?xf32, strided<[?,?], offset: ?>>) -> memref<?x?xf32, strided<[?,?], offset: ?>> {1116  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %arg0 : memref<?x?xf32, strided<[?,?], offset: ?>> -> memref<f32>, index, index, index, index, index1117  %m2 = memref.reinterpret_cast %base to offset: [%offset], sizes: [%sizes#0, %sizes#1], strides: [%strides#0, %strides#1] : memref<f32> to memref<?x?xf32, strided<[?,?], offset:?>>1118  return %m2 : memref<?x?xf32, strided<[?,?], offset:?>>1119}1120 1121// -----1122 1123// Check that we don't simplify reinterpret cast of extract strided metadata1124// when the strides don't match.1125// CHECK-LABEL: func @reinterpret_of_extract_strided_metadata_w_different_stride1126//  CHECK-SAME: (%[[ARG:.*]]: memref<8x2xf32>)1127//       CHECK: %[[RES:.*]] = memref.reinterpret_cast %[[ARG]] to offset: [0], sizes: [4, 2, 2], strides: [1, 1, 1]1128//       CHECK: %[[CAST:.*]] = memref.cast %[[RES]]1129//       CHECK: return %[[CAST]]1130func.func @reinterpret_of_extract_strided_metadata_w_different_stride(%arg0 : memref<8x2xf32>) -> memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>> {1131  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %arg0 : memref<8x2xf32> -> memref<f32>, index, index, index, index, index1132  %m2 = memref.reinterpret_cast %base to offset: [%offset], sizes: [4, 2, 2], strides: [1, 1, %strides#1] : memref<f32> to memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>1133  return %m2 : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>1134}1135// -----1136 1137// Check that we don't simplify reinterpret cast of extract strided metadata1138// when the offset doesn't match.1139// CHECK-LABEL: func @reinterpret_of_extract_strided_metadata_w_different_offset1140//  CHECK-SAME: (%[[ARG:.*]]: memref<8x2xf32>)1141//       CHECK: %[[RES:.*]] = memref.reinterpret_cast %[[ARG]] to offset: [1], sizes: [8, 2], strides: [2, 1]1142//       CHECK: %[[CAST:.*]] = memref.cast %[[RES]]1143//       CHECK: return %[[CAST]]1144func.func @reinterpret_of_extract_strided_metadata_w_different_offset(%arg0 : memref<8x2xf32>) -> memref<?x?xf32, strided<[?, ?], offset: ?>> {1145  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %arg0 : memref<8x2xf32> -> memref<f32>, index, index, index, index, index1146  %m2 = memref.reinterpret_cast %base to offset: [1], sizes: [%sizes#0, %sizes#1], strides: [%strides#0, %strides#1] : memref<f32> to memref<?x?xf32, strided<[?, ?], offset: ?>>1147  return %m2 : memref<?x?xf32, strided<[?, ?], offset: ?>>1148}1149 1150// -----1151 1152func.func @canonicalize_rank_reduced_subview(%arg0 : memref<8x?xf32>,1153    %arg1 : index) -> memref<?xf32, strided<[?], offset: ?>> {1154  %c0 = arith.constant 0 : index1155  %c1 = arith.constant 1 : index1156  %0 = memref.subview %arg0[%c0, %c0] [1, %arg1] [%c1, %c1] : memref<8x?xf32> to memref<?xf32, strided<[?], offset: ?>>1157  return %0 :  memref<?xf32, strided<[?], offset: ?>>1158}1159//      CHECK: func @canonicalize_rank_reduced_subview1160// CHECK-SAME:     %[[ARG0:.+]]: memref<8x?xf32>1161// CHECK-SAME:     %[[ARG1:.+]]: index1162//      CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG0]][0, 0] [1, %[[ARG1]]] [1, 1]1163// CHECK-SAME:       memref<8x?xf32> to memref<?xf32, strided<[1]>>1164 1165// -----1166 1167// CHECK-LABEL: func @memref_realloc_dead1168// CHECK-SAME: %[[SRC:[0-9a-z]+]]: memref<2xf32>1169// CHECK-NOT: memref.realloc1170// CHECK: return %[[SRC]]1171func.func @memref_realloc_dead(%src : memref<2xf32>, %v : f32) -> memref<2xf32>{1172  %0 = memref.realloc %src : memref<2xf32> to memref<4xf32>1173  %i2 = arith.constant 2 : index1174  memref.store %v, %0[%i2] : memref<4xf32>1175  return %src : memref<2xf32>1176}1177 1178// -----1179 1180// CHECK-LABEL: func @collapse_expand_fold_to_cast(1181//  CHECK-SAME:     %[[m:.*]]: memref<?xf32, strided<[1]>, 3>1182//       CHECK:   %[[casted:.*]] = memref.cast %[[m]] : memref<?xf32, strided<[1]>, 3> to memref<?xf32, 31183//       CHECK:   return %[[casted]]1184func.func @collapse_expand_fold_to_cast(%m: memref<?xf32, strided<[1]>, 3>, %sz0: index)1185    -> (memref<?xf32, 3>)1186{1187  %0 = memref.expand_shape %m [[0, 1]] output_shape [1, %sz0]1188      : memref<?xf32, strided<[1]>, 3> into memref<1x?xf32, 3>1189  %1 = memref.collapse_shape %0 [[0, 1]]1190      : memref<1x?xf32, 3> into memref<?xf32, 3>1191  return %1 : memref<?xf32, 3>1192}1193 1194// -----1195 1196// CHECK-LABEL: func @fold_trivial_subviews(1197//  CHECK-SAME:     %[[m:.*]]: memref<?xf32, strided<[?], offset: ?>>1198//       CHECK:   %[[subview:.*]] = memref.subview %[[m]][5]1199//       CHECK:   return %[[subview]]1200func.func @fold_trivial_subviews(%m: memref<?xf32, strided<[?], offset: ?>>,1201                                 %sz: index)1202    -> memref<?xf32, strided<[?], offset: ?>>1203{1204  %0 = memref.subview %m[5] [%sz] [1]1205      : memref<?xf32, strided<[?], offset: ?>>1206        to memref<?xf32, strided<[?], offset: ?>>1207  %1 = memref.subview %0[0] [%sz] [1]1208      : memref<?xf32, strided<[?], offset: ?>>1209        to memref<?xf32, strided<[?], offset: ?>>1210  return %1 : memref<?xf32, strided<[?], offset: ?>>1211}1212 1213// -----1214 1215// CHECK-LABEL: func @load_store_nontemporal(1216func.func @load_store_nontemporal(%input : memref<32xf32, affine_map<(d0) -> (d0)>>, %output : memref<32xf32, affine_map<(d0) -> (d0)>>) {1217  %1 = arith.constant 7 : index1218  // CHECK: memref.load %{{.*}}[%{{.*}}] {nontemporal = true} : memref<32xf32>1219  %2 = memref.load %input[%1] {nontemporal = true} : memref<32xf32, affine_map<(d0) -> (d0)>>1220  // CHECK: memref.store %{{.*}}, %{{.*}}[%{{.*}}] {nontemporal = true} : memref<32xf32>1221  memref.store %2, %output[%1] {nontemporal = true} : memref<32xf32, affine_map<(d0) -> (d0)>>1222  func.return1223}1224 1225// -----1226 1227// CHECK-LABEL: func @fold_trivial_memory_space_cast(1228//  CHECK-SAME:     %[[arg:.*]]: memref<?xf32>1229//       CHECK:   return %[[arg]]1230func.func @fold_trivial_memory_space_cast(%arg : memref<?xf32>) -> memref<?xf32> {1231  %0 = memref.memory_space_cast %arg : memref<?xf32> to memref<?xf32>1232  return %0 : memref<?xf32>1233}1234 1235// -----1236 1237// CHECK-LABEL: func @fold_multiple_memory_space_cast(1238//  CHECK-SAME:     %[[arg:.*]]: memref<?xf32>1239//       CHECK:   %[[res:.*]] = memref.memory_space_cast %[[arg]] : memref<?xf32> to memref<?xf32, 2>1240//       CHECK:   return %[[res]]1241func.func @fold_multiple_memory_space_cast(%arg : memref<?xf32>) -> memref<?xf32, 2> {1242  %0 = memref.memory_space_cast %arg : memref<?xf32> to memref<?xf32, 1>1243  %1 = memref.memory_space_cast %0 : memref<?xf32, 1> to memref<?xf32, 2>1244  return %1 : memref<?xf32, 2>1245}1246 1247// -----1248 1249// CHECK-LABEL: func private @ub_negative_alloc_size1250func.func private @ub_negative_alloc_size() -> memref<?x?x?xi1> {1251  %idx1 = index.constant 11252  %c-2 = arith.constant -2 : index1253  %c15 = arith.constant 15 : index1254// CHECK:   %[[ALLOC:.*]] = memref.alloc(%c-2) : memref<15x?x1xi1>1255  %alloc = memref.alloc(%c15, %c-2, %idx1) : memref<?x?x?xi1>1256  return %alloc : memref<?x?x?xi1>1257}1258 1259// -----1260 1261// CHECK-LABEL: func @subview_rank_reduction(1262//  CHECK-SAME:     %[[arg0:.*]]: memref<1x384x384xf32>, %[[arg1:.*]]: index1263func.func @subview_rank_reduction(%arg0: memref<1x384x384xf32>, %idx: index)1264    -> memref<?x?xf32, strided<[384, 1], offset: ?>> {1265  %c1 = arith.constant 1 : index1266  // CHECK: %[[subview:.*]] = memref.subview %[[arg0]][0, %[[arg1]], %[[arg1]]] [1, 1, %[[arg1]]] [1, 1, 1] : memref<1x384x384xf32> to memref<1x?xf32, strided<[384, 1], offset: ?>>1267  // CHECK: %[[cast:.*]] = memref.cast %[[subview]] : memref<1x?xf32, strided<[384, 1], offset: ?>> to memref<?x?xf32, strided<[384, 1], offset: ?>>1268  %0 = memref.subview %arg0[0, %idx, %idx] [1, %c1, %idx] [1, 1, 1]1269      : memref<1x384x384xf32> to memref<?x?xf32, strided<[384, 1], offset: ?>>1270  // CHECK: return %[[cast]]1271  return %0 : memref<?x?xf32, strided<[384, 1], offset: ?>>1272}1273 1274// -----1275 1276// CHECK-LABEL: func @fold_double_transpose(1277//  CHECK-SAME:     %[[arg0:.*]]: memref<1x2x3x4x5xf32>1278func.func @fold_double_transpose(%arg0: memref<1x2x3x4x5xf32>) -> memref<5x3x2x4x1xf32, strided<[1, 20, 60, 5, 120]>> {1279  // CHECK: %[[ONETRANSPOSE:.+]] = memref.transpose %[[arg0]] (d0, d1, d2, d3, d4) -> (d4, d2, d1, d3, d0)1280  %0 = memref.transpose %arg0 (d0, d1, d2, d3, d4) -> (d1, d0, d4, d3, d2) : memref<1x2x3x4x5xf32> to memref<2x1x5x4x3xf32, strided<[60, 120, 1, 5, 20]>>1281  %1 = memref.transpose %0 (d1, d0, d4, d3, d2) -> (d4, d2, d1, d3, d0) : memref<2x1x5x4x3xf32, strided<[60, 120, 1, 5, 20]>> to memref<5x3x2x4x1xf32, strided<[1, 20, 60, 5, 120]>>1282  // CHECK: return %[[ONETRANSPOSE]]1283  return %1 : memref<5x3x2x4x1xf32, strided<[1, 20, 60, 5, 120]>>1284}1285 1286// -----1287 1288// CHECK-LABEL: func @fold_double_transpose2(1289//  CHECK-SAME:     %[[arg0:.*]]: memref<1x2x3x4x5xf32>1290func.func @fold_double_transpose2(%arg0: memref<1x2x3x4x5xf32>) -> memref<5x3x2x4x1xf32, strided<[1, 20, 60, 5, 120]>> {1291  // CHECK: %[[ONETRANSPOSE:.+]] = memref.transpose %[[arg0]] (d0, d1, d2, d3, d4) -> (d4, d2, d1, d3, d0)1292  %0 = memref.transpose %arg0 (d0, d1, d2, d3, d4) -> (d0, d1, d4, d3, d2) : memref<1x2x3x4x5xf32> to memref<1x2x5x4x3xf32, strided<[120, 60, 1, 5, 20]>>1293  %1 = memref.transpose %0 (d0, d1, d4, d3, d2) -> (d4, d2, d1, d3, d0) : memref<1x2x5x4x3xf32, strided<[120, 60, 1, 5, 20]>> to memref<5x3x2x4x1xf32, strided<[1, 20, 60, 5, 120]>>1294  // CHECK: return %[[ONETRANSPOSE]]1295  return %1 : memref<5x3x2x4x1xf32, strided<[1, 20, 60, 5, 120]>>1296}1297 1298// -----1299 1300// CHECK-LABEL: func @fold_identity_transpose(1301//  CHECK-SAME:     %[[arg0:.*]]: memref<1x2x3x4x5xf32>1302func.func @fold_identity_transpose(%arg0: memref<1x2x3x4x5xf32>) -> memref<1x2x3x4x5xf32> {1303  %0 = memref.transpose %arg0 (d0, d1, d2, d3, d4) -> (d1, d0, d4, d3, d2) : memref<1x2x3x4x5xf32> to memref<2x1x5x4x3xf32, strided<[60, 120, 1, 5, 20]>>1304  %1 = memref.transpose %0 (d1, d0, d4, d3, d2) -> (d0, d1, d2, d3, d4) : memref<2x1x5x4x3xf32, strided<[60, 120, 1, 5, 20]>> to memref<1x2x3x4x5xf32>1305  // CHECK: return %[[arg0]]1306  return %1 : memref<1x2x3x4x5xf32>1307}1308 1309// -----1310 1311#transpose_map = affine_map<(d0, d1)[s0] -> (d0 + d1 * s0)>1312 1313// CHECK-LABEL: func @cannot_fold_transpose_cast(1314//  CHECK-SAME:     %[[arg0:.*]]: memref<?x4xf32>1315func.func @cannot_fold_transpose_cast(%arg0: memref<?x4xf32>) -> memref<?x?xf32, #transpose_map> {1316    // CHECK: %[[CAST:.*]] = memref.cast %[[arg0]] : memref<?x4xf32> to memref<?x?xf32>1317    %cast = memref.cast %arg0 : memref<?x4xf32> to memref<?x?xf32>1318    // CHECK: %[[TRANSPOSE:.*]] = memref.transpose %[[CAST]] (d0, d1) -> (d1, d0) : memref<?x?xf32> to memref<?x?xf32, #{{.*}}>1319    %transpose = memref.transpose %cast (d0, d1) -> (d1, d0) : memref<?x?xf32> to memref<?x?xf32, #transpose_map>1320    // CHECK: return %[[TRANSPOSE]]1321    return %transpose : memref<?x?xf32, #transpose_map>1322}1323 1324// -----1325 1326// CHECK-LABEL: func @fold_assume_alignment_chain1327//  CHECK-SAME:   %[[ARG0:[a-zA-Z0-9]+]]1328func.func @fold_assume_alignment_chain(%0: memref<128xf32>) -> memref<128xf32> {1329  // CHECK: %[[ALIGN:.+]] = memref.assume_alignment %[[ARG0]], 161330  %1 = memref.assume_alignment %0, 16 : memref<128xf32>1331  // CHECK-NOT: memref.assume_alignment1332  %2 = memref.assume_alignment %1, 16 : memref<128xf32>1333  // CHECK: return %[[ALIGN]]1334  return %2 : memref<128xf32>1335}1336 1337// -----1338 1339// CHECK-LABEL: func @fold_view_same_source_result_types1340func.func @fold_view_same_source_result_types(%0: memref<128xi8>) -> memref<128xi8> {1341  %c0 = arith.constant 0: index1342  // CHECK-NOT: memref.view1343  %res = memref.view %0[%c0][] : memref<128xi8> to memref<128xi8>1344  return %res : memref<128xi8>1345}1346 1347// -----1348 1349// CHECK-LABEL: func @non_fold_view_same_source_res_types1350//  CHECK-SAME:   %[[ARG0:[a-zA-Z0-9]+]]1351func.func @non_fold_view_same_source_res_types(%0: memref<?xi8>, %arg0 : index) -> memref<?xi8> {1352  %c0 = arith.constant 0: index1353  // CHECK: memref.view1354  %res = memref.view %0[%c0][%arg0] : memref<?xi8> to memref<?xi8>1355  return %res : memref<?xi8>1356}1357