brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.7 KiB · f7f2d2e Raw
614 lines · plain
1// RUN: mlir-opt -promote-buffers-to-stack -split-input-file %s | FileCheck %s --check-prefix=CHECK --check-prefix DEFINDEX2// RUN: mlir-opt -promote-buffers-to-stack="max-alloc-size-in-bytes=64" -split-input-file %s | FileCheck %s --check-prefix=CHECK --check-prefix LOWLIMIT3// RUN: mlir-opt -promote-buffers-to-stack="max-rank-of-allocated-memref=2" -split-input-file %s | FileCheck %s --check-prefix=CHECK --check-prefix RANK4 5// This file checks the behavior of PromoteBuffersToStack pass for converting6// AllocOps into AllocaOps, if possible.7 8// Test Case:9//    bb010//   /   \11//  bb1  bb2 <- Initial position of AllocOp12//   \   /13//    bb314// PromoteBuffersToStack expected behavior: It should convert %0 into an15// AllocaOp.16 17// CHECK-LABEL: func @condBranch18func.func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {19  cf.cond_br %arg0, ^bb1, ^bb220^bb1:21  cf.br ^bb3(%arg1 : memref<2xf32>)22^bb2:23  %0 = memref.alloc() : memref<2xf32>24  test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)25  cf.br ^bb3(%0 : memref<2xf32>)26^bb3(%1: memref<2xf32>):27  test.copy(%1, %arg2) : (memref<2xf32>, memref<2xf32>)28  return29}30 31// CHECK-NEXT: cf.cond_br {{.*}}32//      CHECK: ^bb233// CHECK-NEXT: %[[ALLOCA:.*]] = memref.alloca()34//      CHECK: test.copy35// CHECK-NEXT: return36 37// -----38 39// Test Case:40//    bb041//   /   \42//  bb1  bb2 <- Initial position of AllocOp43//   \   /44//    bb345// PromoteBuffersToStack expected behavior:46// Since the alloc has dynamic type, it is not converted into an alloca.47 48// CHECK-LABEL: func @condBranchDynamicType49func.func @condBranchDynamicType(50  %arg0: i1,51  %arg1: memref<?xf32>,52  %arg2: memref<?xf32>,53  %arg3: index) {54  cf.cond_br %arg0, ^bb1, ^bb2(%arg3: index)55^bb1:56  cf.br ^bb3(%arg1 : memref<?xf32>)57^bb2(%0: index):58  %1 = memref.alloc(%0) : memref<?xf32>59  test.buffer_based in(%arg1: memref<?xf32>) out(%1: memref<?xf32>)60  cf.br ^bb3(%1 : memref<?xf32>)61^bb3(%2: memref<?xf32>):62  test.copy(%2, %arg2) : (memref<?xf32>, memref<?xf32>)63  return64}65 66// CHECK-NEXT: cf.cond_br67//      CHECK: ^bb268//      CHECK: ^bb2(%[[IDX:.*]]:{{.*}})69// CHECK-NEXT: %[[ALLOC0:.*]] = memref.alloc(%[[IDX]])70// CHECK-NEXT: test.buffer_based71//      CHECK: cf.br ^bb372// CHECK-NEXT: ^bb3(%[[ALLOC0:.*]]:{{.*}})73//      CHECK: test.copy(%[[ALLOC0]],74// CHECK-NEXT: return75 76// -----77 78// CHECK-LABEL: func @dynamicRanked79func.func @dynamicRanked(%memref: memref<*xf32>) {80  %0 = memref.rank %memref : memref<*xf32>81  %1 = memref.alloc(%0) : memref<?xindex>82  return83}84 85// CHECK-NEXT: %[[RANK:.*]] = memref.rank %{{.*}} : memref<*xf32>86// CHECK-NEXT: %[[ALLOCA:.*]] = memref.alloca(%[[RANK]])87 88// -----89 90// CHECK-LABEL: func @dynamicRanked2D91func.func @dynamicRanked2D(%memref: memref<*xf32>) {92  %0 = memref.rank %memref : memref<*xf32>93  %1 = memref.alloc(%0, %0) : memref<?x?xindex>94  return95}96 97// CHECK-NEXT: %[[RANK:.*]] = memref.rank %{{.*}} : memref<*xf32>98//  RANK-NEXT: %[[ALLOC:.*]] = memref.alloca(%[[RANK]], %[[RANK]])99// DEFINDEX-NEXT: %[[ALLOC:.*]] = memref.alloc(%[[RANK]], %[[RANK]])100 101// -----102 103// CHECK-LABEL: func @dynamicNoRank104func.func @dynamicNoRank(%arg0: index) {105  %0 = memref.alloc(%arg0) : memref<?xindex>106  return107}108 109// CHECK-NEXT: %[[ALLOC:.*]] = memref.alloc110 111// -----112 113// Test Case: Existing AllocOp with no users.114// PromoteBuffersToStack expected behavior: It should convert it to an115// AllocaOp.116 117// CHECK-LABEL: func @emptyUsesValue118func.func @emptyUsesValue(%arg0: memref<4xf32>) {119  %0 = memref.alloc() : memref<4xf32>120  return121}122// CHECK-NEXT: %[[ALLOCA:.*]] = memref.alloca()123// CHECK-NEXT: return124 125// -----126 127// Test Case:128//    bb0129//   /   \130//  |    bb1 <- Initial position of AllocOp131//   \   /132//    bb2133// PromoteBuffersToStack expected behavior: It should convert it into an134// AllocaOp.135 136// CHECK-LABEL: func @criticalEdge137func.func @criticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {138  cf.cond_br %arg0, ^bb1, ^bb2(%arg1 : memref<2xf32>)139^bb1:140  %0 = memref.alloc() : memref<2xf32>141  test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)142  cf.br ^bb2(%0 : memref<2xf32>)143^bb2(%1: memref<2xf32>):144  test.copy(%1, %arg2) : (memref<2xf32>, memref<2xf32>)145  return146}147 148// CHECK-NEXT: cf.cond_br {{.*}}149//      CHECK: ^bb1150// CHECK-NEXT: %[[ALLOCA:.*]] = memref.alloca()151//      CHECK: test.copy152// CHECK-NEXT: return153 154// -----155 156// Test Case:157//    bb0 <- Initial position of AllocOp158//   /   \159//  |    bb1160//   \   /161//    bb2162// PromoteBuffersToStack expected behavior: It converts the alloc in an alloca.163 164// CHECK-LABEL: func @invCriticalEdge165func.func @invCriticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {166  %0 = memref.alloc() : memref<2xf32>167  test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)168  cf.cond_br %arg0, ^bb1, ^bb2(%arg1 : memref<2xf32>)169^bb1:170  cf.br ^bb2(%0 : memref<2xf32>)171^bb2(%1: memref<2xf32>):172  test.copy(%1, %arg2) : (memref<2xf32>, memref<2xf32>)173  return174}175 176// CHECK-NEXT: %[[ALLOCA:.*]] = memref.alloca()177//      CHECK: cf.cond_br178//      CHECK: test.copy179// CHECK-NEXT: return180 181// -----182 183// Test Case:184//    bb0 <- Initial position of the first AllocOp185//   /   \186//  bb1  bb2187//   \   /188//    bb3 <- Initial position of the second AllocOp189// PromoteBuffersToStack expected behavior: It converts the allocs into allocas.190 191// CHECK-LABEL: func @ifElse192func.func @ifElse(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {193  %0 = memref.alloc() : memref<2xf32>194  test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)195  cf.cond_br %arg0,196    ^bb1(%arg1, %0 : memref<2xf32>, memref<2xf32>),197    ^bb2(%0, %arg1 : memref<2xf32>, memref<2xf32>)198^bb1(%1: memref<2xf32>, %2: memref<2xf32>):199  cf.br ^bb3(%1, %2 : memref<2xf32>, memref<2xf32>)200^bb2(%3: memref<2xf32>, %4: memref<2xf32>):201  cf.br ^bb3(%3, %4 : memref<2xf32>, memref<2xf32>)202^bb3(%5: memref<2xf32>, %6: memref<2xf32>):203  %7 = memref.alloc() : memref<2xf32>204  test.buffer_based in(%5: memref<2xf32>) out(%7: memref<2xf32>)205  test.copy(%7, %arg2) : (memref<2xf32>, memref<2xf32>)206  return207}208 209// CHECK-NEXT: %[[ALLOCA0:.*]] = memref.alloca()210// CHECK-NEXT: test.buffer_based211//      CHECK: %[[ALLOCA1:.*]] = memref.alloca()212//      CHECK: test.buffer_based213//      CHECK: test.copy(%[[ALLOCA1]]214// CHECK-NEXT: return215 216// -----217 218// Test Case: No users for buffer in if-else CFG219//    bb0 <- Initial position of AllocOp220//   /   \221//  bb1  bb2222//   \   /223//    bb3224// PromoteBuffersToStack expected behavior: It converts the alloc into alloca.225 226// CHECK-LABEL: func @ifElseNoUsers227func.func @ifElseNoUsers(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {228  %0 = memref.alloc() : memref<2xf32>229  test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)230  cf.cond_br %arg0,231    ^bb1(%arg1, %0 : memref<2xf32>, memref<2xf32>),232    ^bb2(%0, %arg1 : memref<2xf32>, memref<2xf32>)233^bb1(%1: memref<2xf32>, %2: memref<2xf32>):234  cf.br ^bb3(%1, %2 : memref<2xf32>, memref<2xf32>)235^bb2(%3: memref<2xf32>, %4: memref<2xf32>):236  cf.br ^bb3(%3, %4 : memref<2xf32>, memref<2xf32>)237^bb3(%5: memref<2xf32>, %6: memref<2xf32>):238  test.copy(%arg1, %arg2) : (memref<2xf32>, memref<2xf32>)239  return240}241 242// CHECK-NEXT: %[[ALLOCA:.*]] = memref.alloca()243//      CHECK: return244 245// -----246 247// Test Case:248//      bb0 <- Initial position of the first AllocOp249//     /    \250//   bb1    bb2251//    |     /  \252//    |   bb3  bb4253//    \     \  /254//     \     /255//       bb5 <- Initial position of the second AllocOp256// PromoteBuffersToStack expected behavior: The two allocs should be converted257// into allocas.258 259// CHECK-LABEL: func @ifElseNested260func.func @ifElseNested(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {261  %0 = memref.alloc() : memref<2xf32>262  test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)263  cf.cond_br %arg0,264    ^bb1(%arg1, %0 : memref<2xf32>, memref<2xf32>),265    ^bb2(%0, %arg1 : memref<2xf32>, memref<2xf32>)266^bb1(%1: memref<2xf32>, %2: memref<2xf32>):267  cf.br ^bb5(%1, %2 : memref<2xf32>, memref<2xf32>)268^bb2(%3: memref<2xf32>, %4: memref<2xf32>):269  cf.cond_br %arg0, ^bb3(%3 : memref<2xf32>), ^bb4(%4 : memref<2xf32>)270^bb3(%5: memref<2xf32>):271  cf.br ^bb5(%5, %3 : memref<2xf32>, memref<2xf32>)272^bb4(%6: memref<2xf32>):273  cf.br ^bb5(%3, %6 : memref<2xf32>, memref<2xf32>)274^bb5(%7: memref<2xf32>, %8: memref<2xf32>):275  %9 = memref.alloc() : memref<2xf32>276  test.buffer_based in(%7: memref<2xf32>) out(%9: memref<2xf32>)277  test.copy(%9, %arg2) : (memref<2xf32>, memref<2xf32>)278  return279}280 281// CHECK-NEXT: %[[ALLOCA0:.*]] = memref.alloca()282// CHECK-NEXT: test.buffer_based283//      CHECK: %[[ALLOCA1:.*]] = memref.alloca()284//      CHECK: test.buffer_based285//      CHECK: test.copy(%[[ALLOCA1]]286// CHECK-NEXT: return287 288// -----289 290// Test Case: Dead operations in a single block.291// PromoteBuffersToStack expected behavior: It converts the two AllocOps into292// allocas.293 294// CHECK-LABEL: func @redundantOperations295func.func @redundantOperations(%arg0: memref<2xf32>) {296  %0 = memref.alloc() : memref<2xf32>297  test.buffer_based in(%arg0: memref<2xf32>) out(%0: memref<2xf32>)298  %1 = memref.alloc() : memref<2xf32>299  test.buffer_based in(%0: memref<2xf32>) out(%1: memref<2xf32>)300  return301}302 303//      CHECK: (%[[ARG0:.*]]: {{.*}})304// CHECK-NEXT: %[[ALLOCA0:.*]] = memref.alloca()305// CHECK-NEXT: test.buffer_based in(%[[ARG0]]{{.*}} out(%[[ALLOCA0]]306//      CHECK: %[[ALLOCA1:.*]] = memref.alloca()307// CHECK-NEXT: test.buffer_based in(%[[ALLOCA0]]{{.*}} out(%[[ALLOCA1]]308//      CHECK: return309 310// -----311 312// Test Case:313//                                     bb0314//                                    /   \315// Initial pos of the 1st AllocOp -> bb1  bb2 <- Initial pos of the 2nd AllocOp316//                                    \   /317//                                     bb3318// PromoteBuffersToStack expected behavior: Both AllocOps are converted into319// allocas.320 321// CHECK-LABEL: func @moving_alloc_and_inserting_missing_dealloc322func.func @moving_alloc_and_inserting_missing_dealloc(323  %cond: i1,324    %arg0: memref<2xf32>,325    %arg1: memref<2xf32>) {326  cf.cond_br %cond, ^bb1, ^bb2327^bb1:328  %0 = memref.alloc() : memref<2xf32>329  test.buffer_based in(%arg0: memref<2xf32>) out(%0: memref<2xf32>)330  cf.br ^exit(%0 : memref<2xf32>)331^bb2:332  %1 = memref.alloc() : memref<2xf32>333  test.buffer_based in(%arg0: memref<2xf32>) out(%1: memref<2xf32>)334  cf.br ^exit(%1 : memref<2xf32>)335^exit(%arg2: memref<2xf32>):336  test.copy(%arg2, %arg1) : (memref<2xf32>, memref<2xf32>)337  return338}339 340// CHECK-NEXT: cf.cond_br {{.*}}341//      CHECK: ^bb1342// CHECK-NEXT: %{{.*}} = memref.alloca()343//      CHECK: ^bb2344// CHECK-NEXT: %{{.*}} = memref.alloca()345//      CHECK: test.copy346// CHECK-NEXT: return347 348// -----349 350// Test Case: Nested regions - This test defines a BufferBasedOp inside the351// region of a RegionBufferBasedOp.352// PromoteBuffersToStack expected behavior: The AllocOps are converted into353// allocas.354 355// CHECK-LABEL: func @nested_regions_and_cond_branch356func.func @nested_regions_and_cond_branch(357  %arg0: i1,358  %arg1: memref<2xf32>,359  %arg2: memref<2xf32>) {360  cf.cond_br %arg0, ^bb1, ^bb2361^bb1:362  cf.br ^bb3(%arg1 : memref<2xf32>)363^bb2:364  %0 = memref.alloc() : memref<2xf32>365  test.region_buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>) {366  ^bb0(%gen1_arg0: f32, %gen1_arg1: f32):367    %1 = memref.alloc() : memref<2xf32>368    test.buffer_based in(%arg1: memref<2xf32>) out(%1: memref<2xf32>)369    %tmp1 = math.exp %gen1_arg0 : f32370    test.region_yield %tmp1 : f32371  }372  cf.br ^bb3(%0 : memref<2xf32>)373^bb3(%1: memref<2xf32>):374  test.copy(%1, %arg2) : (memref<2xf32>, memref<2xf32>)375  return376}377 378// CHECK-NEXT:   cf.cond_br {{.*}}379//      CHECK:   ^bb2380// CHECK-NEXT:   %[[ALLOCA0:.*]] = memref.alloca()381//      CHECK:   ^bb0382// CHECK-NEXT:   %[[ALLOCA1:.*]] = memref.alloc()383 384// -----385 386// Test Case: buffer deallocation escaping387// PromoteBuffersToStack expected behavior: The first alloc is returned, so388// there is no conversion allowed. The second alloc is converted, since it389// only remains in the scope of the function.390 391// CHECK-LABEL: func @memref_in_function_results392func.func @memref_in_function_results(393  %arg0: memref<5xf32>,394  %arg1: memref<10xf32>,395  %arg2: memref<5xf32>) -> (memref<10xf32>, memref<15xf32>) {396  %x = memref.alloc() : memref<15xf32>397  %y = memref.alloc() : memref<5xf32>398  test.buffer_based in(%arg0: memref<5xf32>) out(%y: memref<5xf32>)399  test.copy(%y, %arg2) : (memref<5xf32>, memref<5xf32>)400  return %arg1, %x : memref<10xf32>, memref<15xf32>401}402//      CHECK: (%[[ARG0:.*]]: memref<5xf32>, %[[ARG1:.*]]: memref<10xf32>,403// CHECK-SAME: %[[RESULT:.*]]: memref<5xf32>)404//      CHECK: %[[ALLOC:.*]] = memref.alloc()405//      CHECK: %[[ALLOCA:.*]] = memref.alloca()406//      CHECK: test.copy407//      CHECK: return %[[ARG1]], %[[ALLOC]]408 409// -----410 411// Test Case: nested region control flow412// The allocation in the nested if branch cannot be converted to an alloca413// due to its dynamic memory allocation behavior.414 415// CHECK-LABEL: func @nested_region_control_flow416func.func @nested_region_control_flow(417  %arg0 : index,418  %arg1 : index) -> memref<?x?xf32> {419  %0 = arith.cmpi eq, %arg0, %arg1 : index420  %1 = memref.alloc(%arg0, %arg0) : memref<?x?xf32>421  %2 = scf.if %0 -> (memref<?x?xf32>) {422    scf.yield %1 : memref<?x?xf32>423  } else {424    %3 = memref.alloc(%arg0, %arg1) : memref<?x?xf32>425    scf.yield %1 : memref<?x?xf32>426  }427  return %2 : memref<?x?xf32>428}429 430//      CHECK: %[[ALLOC0:.*]] = memref.alloc(%arg0, %arg0)431// CHECK-NEXT: %[[ALLOC1:.*]] = scf.if432//      CHECK: scf.yield %[[ALLOC0]]433//      CHECK: %[[ALLOC2:.*]] = memref.alloc(%arg0, %arg1)434// CHECK-NEXT: scf.yield %[[ALLOC0]]435//      CHECK: return %[[ALLOC1]]436 437// -----438 439// Test Case: nested region control flow within a region interface.440// The alloc %0 does not need to be converted in this case since the441// allocation finally escapes the method.442 443// CHECK-LABEL: func @inner_region_control_flow444func.func @inner_region_control_flow(%arg0 : index) -> memref<2x2xf32> {445  %0 = memref.alloc() : memref<2x2xf32>446  %1 = test.region_if %0 : memref<2x2xf32> -> (memref<2x2xf32>) then {447    ^bb0(%arg1 : memref<2x2xf32>):448      test.region_if_yield %arg1 : memref<2x2xf32>449  } else {450    ^bb0(%arg1 : memref<2x2xf32>):451      test.region_if_yield %arg1 : memref<2x2xf32>452  } join {453    ^bb0(%arg1 : memref<2x2xf32>):454      test.region_if_yield %arg1 : memref<2x2xf32>455  }456  return %1 : memref<2x2xf32>457}458 459//      CHECK: %[[ALLOC0:.*]] = memref.alloc()460// CHECK-NEXT: %[[ALLOC1:.*]] = test.region_if461// CHECK-NEXT: ^bb0(%[[ALLOC2:.*]]:{{.*}}):462// CHECK-NEXT: test.region_if_yield %[[ALLOC2]]463//      CHECK: ^bb0(%[[ALLOC3:.*]]:{{.*}}):464// CHECK-NEXT: test.region_if_yield %[[ALLOC3]]465//      CHECK: ^bb0(%[[ALLOC4:.*]]:{{.*}}):466// CHECK-NEXT: test.region_if_yield %[[ALLOC4]]467//      CHECK: return %[[ALLOC1]]468 469// -----470 471// Test Case: structured control-flow loop using a nested alloc.472// Alloc %0 will be converted to an alloca. %3 is not transformed.473 474// CHECK-LABEL: func @loop_alloc475func.func @loop_alloc(476  %lb: index,477  %ub: index,478  %step: index,479  %buf: memref<2xf32>,480  %res: memref<2xf32>) {481  %0 = memref.alloc() : memref<2xf32>482  %1 = scf.for %i = %lb to %ub step %step483    iter_args(%iterBuf = %buf) -> memref<2xf32> {484    %2 = arith.cmpi eq, %i, %ub : index485    %3 = memref.alloc() : memref<2xf32>486    scf.yield %3 : memref<2xf32>487  }488  test.copy(%1, %res) : (memref<2xf32>, memref<2xf32>)489  return490}491 492// CHECK-NEXT: %[[ALLOCA:.*]] = memref.alloca()493// CHECK-NEXT: scf.for494//      CHECK: %[[ALLOC:.*]] = memref.alloc()495 496// -----497 498// Test Case: structured control-flow loop with a nested if operation.499// The loop yields buffers that have been defined outside of the loop and the500// backedges only use the iteration arguments (or one of its aliases).501// Therefore, we do not have to (and are not allowed to) free any buffers502// that are passed via the backedges. The alloc is converted to an AllocaOp.503 504// CHECK-LABEL: func @loop_nested_if_no_alloc505func.func @loop_nested_if_no_alloc(506  %lb: index,507  %ub: index,508  %step: index,509  %buf: memref<2xf32>,510  %res: memref<2xf32>) {511  %0 = memref.alloc() : memref<2xf32>512  %1 = scf.for %i = %lb to %ub step %step513    iter_args(%iterBuf = %buf) -> memref<2xf32> {514    %2 = arith.cmpi eq, %i, %ub : index515    %3 = scf.if %2 -> (memref<2xf32>) {516      scf.yield %0 : memref<2xf32>517    } else {518      scf.yield %iterBuf : memref<2xf32>519    }520    scf.yield %3 : memref<2xf32>521  }522  test.copy(%1, %res) : (memref<2xf32>, memref<2xf32>)523  return524}525 526//      CHECK: %[[ALLOCA0:.*]] = memref.alloca()527// CHECK-NEXT: %[[ALLOCA1:.*]] = scf.for {{.*}} iter_args(%[[IALLOCA:.*]] =528//      CHECK: %[[ALLOCA2:.*]] = scf.if529//      CHECK: scf.yield %[[ALLOCA0]]530//      CHECK: scf.yield %[[IALLOCA]]531//      CHECK: scf.yield %[[ALLOCA2]]532//      CHECK: test.copy(%[[ALLOCA1]], %arg4)533 534// -----535 536// Test Case: structured control-flow loop with a nested if operation using537// a deeply nested buffer allocation.538// The allocs are not converted in this case.539 540// CHECK-LABEL: func @loop_nested_if_alloc541func.func @loop_nested_if_alloc(542  %lb: index,543  %ub: index,544  %step: index,545  %buf: memref<2xf32>) -> memref<2xf32> {546  %0 = memref.alloc() : memref<2xf32>547  %1 = scf.for %i = %lb to %ub step %step548    iter_args(%iterBuf = %buf) -> memref<2xf32> {549    %2 = arith.cmpi eq, %i, %ub : index550    %3 = scf.if %2 -> (memref<2xf32>) {551      %4 = memref.alloc() : memref<2xf32>552      scf.yield %4 : memref<2xf32>553    } else {554      scf.yield %0 : memref<2xf32>555    }556    scf.yield %3 : memref<2xf32>557  }558  return %1 : memref<2xf32>559}560 561//      CHECK: %[[ALLOC0:.*]] = memref.alloc()562// CHECK-NEXT: %[[ALLOC1:.*]] = scf.for {{.*}}563//      CHECK: %[[ALLOC2:.*]] = scf.if564//      CHECK: %[[ALLOC3:.*]] = memref.alloc()565// CHECK-NEXT: scf.yield %[[ALLOC3]]566//      CHECK: scf.yield %[[ALLOC0]]567//      CHECK: scf.yield %[[ALLOC2]]568//      CHECK: return %[[ALLOC1]]569 570// -----571 572// Test Case: The allocated buffer is too large and, hence, it is not573// converted. In the actual implementation the largest size is 1KB.574 575// CHECK-LABEL: func @large_buffer_allocation576func.func @large_buffer_allocation(%arg0: memref<2048xf32>) {577  %0 = memref.alloc() : memref<2048xf32>578  test.copy(%0, %arg0) : (memref<2048xf32>, memref<2048xf32>)579  return580}581 582// CHECK-NEXT: %[[ALLOC:.*]] = memref.alloc()583// CHECK-NEXT: test.copy584 585// -----586 587// Test Case: AllocOp with element type index.588// PromoteBuffersToStack expected behavior: It should convert it to an589// AllocaOp.590 591// CHECK-LABEL: func @indexElementType592func.func @indexElementType() {593  %0 = memref.alloc() : memref<4xindex>594  return595}596// DEFINDEX-NEXT: memref.alloca()597// LOWLIMIT-NEXT: memref.alloca()598// RANK-NEXT: memref.alloca()599// CHECK-NEXT: return600 601// -----602 603// CHECK-LABEL: func @bigIndexElementType604module attributes { dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<index, 256>>} {605  func.func @bigIndexElementType() {606    %0 = memref.alloc() {alignment = 64 : i64, custom_attr} : memref<4xindex>607    return608  }609}610// DEFINDEX-NEXT: memref.alloca() {alignment = 64 : i64, custom_attr}611// LOWLIMIT-NEXT: memref.alloc() {alignment = 64 : i64, custom_attr}612// RANK-NEXT: memref.alloca() {alignment = 64 : i64, custom_attr}613// CHECK-NEXT: return614