brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · e8bb0c0 Raw
180 lines · plain
1// RUN: mlir-opt -verify-diagnostics -ownership-based-buffer-deallocation \2// RUN:   --buffer-deallocation-simplification -split-input-file %s | FileCheck %s3// RUN: mlir-opt -verify-diagnostics -ownership-based-buffer-deallocation=private-function-dynamic-ownership=true -split-input-file %s > /dev/null4 5// RUN: mlir-opt %s -buffer-deallocation-pipeline --split-input-file > /dev/null6 7// Test Case: Dead operations in a single block.8// BufferDeallocation expected behavior: It only inserts the two missing9// DeallocOps after the last BufferBasedOp.10 11// CHECK-LABEL: func @redundantOperations12func.func @redundantOperations(%arg0: memref<2xf32>) {13  %0 = memref.alloc() : memref<2xf32>14  test.buffer_based in(%arg0: memref<2xf32>) out(%0: memref<2xf32>)15  %1 = memref.alloc() : memref<2xf32>16  test.buffer_based in(%0: memref<2xf32>) out(%1: memref<2xf32>)17  return18}19 20//      CHECK: (%[[ARG0:.*]]: {{.*}})21//      CHECK: %[[FIRST_ALLOC:.*]] = memref.alloc()22//  CHECK-NOT: bufferization.dealloc23//      CHECK: test.buffer_based in(%[[ARG0]]{{.*}}out(%[[FIRST_ALLOC]]24//  CHECK-NOT: bufferization.dealloc25//      CHECK: %[[SECOND_ALLOC:.*]] = memref.alloc()26//  CHECK-NOT: bufferization.dealloc27//      CHECK: test.buffer_based in(%[[FIRST_ALLOC]]{{.*}}out(%[[SECOND_ALLOC]]28//      CHECK: bufferization.dealloc (%[[FIRST_ALLOC]] :{{.*}}) if (%true{{[0-9_]*}})29//      CHECK: bufferization.dealloc (%[[SECOND_ALLOC]] :{{.*}}) if (%true{{[0-9_]*}})30// CHECK-NEXT: return31 32// TODO: The dealloc could be split in two to avoid runtime aliasing checks33// since we can be sure at compile time that they will never alias.34 35// -----36 37// CHECK-LABEL: func @allocaIsNotDeallocated38func.func @allocaIsNotDeallocated(%arg0: memref<2xf32>) {39  %0 = memref.alloc() : memref<2xf32>40  test.buffer_based in(%arg0: memref<2xf32>) out(%0: memref<2xf32>)41  %1 = memref.alloca() : memref<2xf32>42  test.buffer_based in(%0: memref<2xf32>) out(%1: memref<2xf32>)43  return44}45 46//      CHECK: (%[[ARG0:.*]]: {{.*}})47//      CHECK: %[[FIRST_ALLOC:.*]] = memref.alloc()48// CHECK-NEXT: test.buffer_based in(%[[ARG0]]{{.*}}out(%[[FIRST_ALLOC]]49// CHECK-NEXT: %[[SECOND_ALLOC:.*]] = memref.alloca()50// CHECK-NEXT: test.buffer_based in(%[[FIRST_ALLOC]]{{.*}}out(%[[SECOND_ALLOC]]51//      CHECK: bufferization.dealloc (%[[FIRST_ALLOC]] :{{.*}}) if (%true{{[0-9_]*}})52// CHECK-NEXT: return53 54// -----55 56// Test Case: Inserting missing DeallocOp in a single block.57 58// CHECK-LABEL: func @inserting_missing_dealloc_simple59func.func @inserting_missing_dealloc_simple(60  %arg0 : memref<2xf32>,61  %arg1: memref<2xf32>) {62  %0 = memref.alloc() : memref<2xf32>63  test.buffer_based in(%arg0: memref<2xf32>) out(%0: memref<2xf32>)64  test.copy(%0, %arg1) : (memref<2xf32>, memref<2xf32>)65  return66}67 68//      CHECK: %[[ALLOC0:.*]] = memref.alloc()69//      CHECK: test.copy70//      CHECK: bufferization.dealloc (%[[ALLOC0]] :{{.*}}) if (%true{{[0-9_]*}})71 72// -----73 74// Test Case: The ownership indicator is set to false for alloca75 76// CHECK-LABEL: func @alloca_ownership_indicator_is_false77func.func @alloca_ownership_indicator_is_false() {78  %0 = memref.alloca() : memref<2xf32>79  cf.br ^bb1(%0: memref<2xf32>)80^bb1(%arg0 : memref<2xf32>):81  return82}83 84//      CHECK:  %[[ALLOC0:.*]] = memref.alloca()85// CHECK-NEXT:   cf.br ^bb1(%[[ALLOC0]], %false :86// CHECK-NEXT: ^bb1([[A0:%.+]]: memref<2xf32>, [[COND0:%.+]]: i1):87//      CHECK:   [[BASE:%[a-zA-Z0-9_]+]]{{.*}} = memref.extract_strided_metadata [[A0]]88//      CHECK:   bufferization.dealloc ([[BASE]] : {{.*}}) if ([[COND0]])89// CHECK-NEXT:   return90 91// -----92 93func.func @dealloc_existing_clones(%arg0: memref<?x?xf64>, %arg1: memref<?x?xf64>) -> memref<?x?xf64> {94  %0 = bufferization.clone %arg0 : memref<?x?xf64> to memref<?x?xf64>95  %1 = bufferization.clone %arg1 : memref<?x?xf64> to memref<?x?xf64>96  return %0 : memref<?x?xf64>97}98 99// CHECK-LABEL: func @dealloc_existing_clones100//       CHECK: (%[[ARG0:.*]]: memref<?x?xf64>, %[[ARG1:.*]]: memref<?x?xf64>)101//       CHECK: %[[RES0:.*]] = bufferization.clone %[[ARG0]]102//       CHECK: %[[RES1:.*]] = bufferization.clone %[[ARG1]]103//  CHECK-NEXT: bufferization.dealloc (%[[RES1]] :{{.*}}) if (%true{{[0-9_]*}})104//   CHECK-NOT: retain105//  CHECK-NEXT: return %[[RES0]]106 107// TODO: The retain operand could be dropped to avoid runtime aliasing checks108// since We can guarantee at compile-time that it will never alias with the109// dealloc operand110 111// -----112 113memref.global "private" constant @__constant_4xf32 : memref<4xf32> = dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]>114 115func.func @op_without_aliasing_and_allocation() -> memref<4xf32> {116  %0 = memref.get_global @__constant_4xf32 : memref<4xf32>117  return %0 : memref<4xf32>118}119 120// CHECK-LABEL: func @op_without_aliasing_and_allocation121//       CHECK:   [[GLOBAL:%.+]] = memref.get_global @__constant_4xf32122//       CHECK:   [[RES:%.+]] = scf.if %false123//       CHECK:     scf.yield [[GLOBAL]] :124//       CHECK:     [[CLONE:%.+]] = bufferization.clone [[GLOBAL]]125//       CHECK:     scf.yield [[CLONE]] :126//       CHECK:   return [[RES]] :127 128// -----129 130// Allocations with "bufferization.manual_deallocation" are assigned an131// ownership of "false".132 133func.func @manual_deallocation(%c: i1, %f: f32, %idx: index) -> f32 {134  %0 = memref.alloc() {bufferization.manual_deallocation} : memref<5xf32>135  linalg.fill ins(%f : f32) outs(%0 : memref<5xf32>)136  %1 = memref.alloc() : memref<5xf32>137  linalg.fill ins(%f : f32) outs(%1 : memref<5xf32>)138  %2 = arith.select %c, %0, %1 : memref<5xf32>139  %3 = memref.load %2[%idx] : memref<5xf32>140 141  // Only buffers that are under "manual deallocation" are allowed to be142  // deallocated with memref.dealloc. For consistency reasons, the143  // manual_deallocation attribute must also be specified. A runtime insertion144  // is inserted to ensure that we do not have ownership. (This is not a145  // bulletproof check, but covers some cases of invalid IR.)146  memref.dealloc %0 {bufferization.manual_deallocation} : memref<5xf32>147 148  return %3 : f32149}150 151// CHECK-LABEL: func @manual_deallocation(152//       CHECK:   %[[true:.*]] = arith.constant true153//       CHECK:   %[[manual_alloc:.*]] = memref.alloc() {bufferization.manual_deallocation} : memref<5xf32>154//       CHECK:   %[[managed_alloc:.*]] = memref.alloc() : memref<5xf32>155//       CHECK:   %[[selected:.*]] = arith.select156//       CHECK:   cf.assert %[[true]], "expected that the block does not have ownership"157//       CHECK:   memref.dealloc %[[manual_alloc]]158//       CHECK:   bufferization.dealloc (%[[managed_alloc]] : memref<5xf32>) if (%[[true]])159 160// -----161 162// CHECK-LABEL: func.func private @properly_creates_deallocations_in_execute_region(163// CHECK:           %[[true:.*]] = arith.constant true164// CHECK:           scf.execute_region no_inline {165// CHECK:             %[[alloc:.*]] = memref.alloc() {alignment = 64 : i64} : memref<1x63x378x16xui8>166// CHECK:             bufferization.dealloc (%[[alloc]] : memref<1x63x378x16xui8>) if (%[[true]])167 168func.func private @properly_creates_deallocations_in_execute_region(%arg1: memref<1x16x252x380xui8> ) -> (memref<1x250x378x16xui8> )  {169  %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x250x378x16xui8>170  scf.execute_region no_inline {171    %subview = memref.subview %arg1[0, 0, 0, 0] [1, 16, 65, 380] [1, 1, 1, 1] : memref<1x16x252x380xui8> to memref<1x16x65x380xui8, strided<[1532160, 95760, 380, 1]>>172    %alloc_3 = memref.alloc() {alignment = 64 : i64} : memref<1x63x378x16xui8>    173    test.buffer_based in(%subview: memref<1x16x65x380xui8, strided<[1532160, 95760, 380, 1]>>) out(%alloc_3: memref<1x63x378x16xui8>)174    %subview_7 = memref.subview %alloc[0, 0, 0, 0] [1, 63, 378, 16] [1, 1, 1, 1] : memref<1x250x378x16xui8> to memref<1x63x378x16xui8, strided<[1512000, 6048, 16, 1]>>175    test.copy(%alloc_3, %subview_7) : (memref<1x63x378x16xui8>, memref<1x63x378x16xui8, strided<[1512000, 6048, 16, 1]>>)176    scf.yield177  }178  return %alloc : memref<1x250x378x16xui8>179}180