1// RUN: mlir-opt --expand-realloc %s --split-input-file --verify-diagnostics | FileCheck %s 2// RUN: mlir-opt --expand-realloc=emit-deallocs=false %s --split-input-file --verify-diagnostics | FileCheck %s --check-prefix=NODEALLOC 3 4func.func @reallow_lowering_example(%init_size: index, %new_size: index) -> memref<?xf32> { 5 %alloc = memref.alloc(%init_size) : memref<?xf32> 6 %realloc = memref.realloc %alloc (%new_size) {alignment = 8}: memref<?xf32> to memref<?xf32> 7 return %realloc : memref<?xf32> 8} 9 10// CHECK-LABEL: func @reallow_lowering_example 11// CHECK-SAME: ([[INIT_SIZE:%.+]]: index, [[NEW_SIZE:%.+]]: index) 12// CHECK-NEXT: [[OLD_ALLOC:%.+]] = memref.alloc([[INIT_SIZE]]) : memref<?xf32> 13// CHECK-NEXT: [[C0:%.+]] = arith.constant 0 14// CHECK-NEXT: [[CURR_SIZE:%.+]] = memref.dim [[OLD_ALLOC]], [[C0]] 15// CHECK-NEXT: [[COND:%.+]] = arith.cmpi ult, [[CURR_SIZE]], [[NEW_SIZE]] 16// CHECK-NEXT: [[REALLOC:%.+]] = scf.if [[COND]] 17// CHECK-NEXT: [[NEW_ALLOC:%.+]] = memref.alloc([[NEW_SIZE]]) {alignment = 8 : i64} : memref<?xf32> 18// CHECK-NEXT: [[SUBVIEW:%.+]] = memref.subview [[NEW_ALLOC]][0] [[[CURR_SIZE]]] [1] 19// CHECK-NEXT: memref.copy [[OLD_ALLOC]], [[SUBVIEW]] 20// CHECK-NEXT: memref.dealloc [[OLD_ALLOC]] 21// CHECK-NEXT: scf.yield [[NEW_ALLOC]] 22// CHECK: [[CAST:%.+]] = memref.reinterpret_cast [[OLD_ALLOC]] to offset: [0], sizes: [[[NEW_SIZE]]], strides: [1] : memref<?xf32> to memref<?xf32> 23// CHECK-NEXT: scf.yield [[CAST]] 24// CHECK: return [[REALLOC]] 25 26// NODEALLOC-LABEL: func @reallow_lowering_example 27// NODEALLOC-NOT: dealloc 28 29// ----- 30 31func.func @reallow_lowering_example() -> memref<4xf32> { 32 %alloc = memref.alloc() : memref<2xf32> 33 %realloc = memref.realloc %alloc {alignment = 8}: memref<2xf32> to memref<4xf32> 34 return %realloc : memref<4xf32> 35} 36 37// CHECK-LABEL: func @reallow_lowering_example 38// CHECK-NEXT: [[OLD_ALLOC:%.+]] = memref.alloc() : memref<2xf32> 39// CHECK-NEXT: [[CURR_SIZE:%.+]] = arith.constant 2 40// CHECK-NEXT: [[NEW_SIZE:%.+]] = arith.constant 4 41// CHECK-NEXT: [[COND:%.+]] = arith.cmpi ult, [[CURR_SIZE]], [[NEW_SIZE]] 42// CHECK-NEXT: [[REALLOC:%.+]] = scf.if [[COND]] 43// CHECK-NEXT: [[NEW_ALLOC:%.+]] = memref.alloc() {alignment = 8 : i64} : memref<4xf32> 44// CHECK-NEXT: [[SUBVIEW:%.+]] = memref.subview [[NEW_ALLOC]][0] [2] [1] 45// CHECK-NEXT: memref.copy [[OLD_ALLOC]], [[SUBVIEW]] 46// CHECK-NEXT: memref.dealloc [[OLD_ALLOC]] 47// CHECK-NEXT: scf.yield [[NEW_ALLOC]] 48// CHECK: [[CAST:%.+]] = memref.reinterpret_cast [[OLD_ALLOC]] to offset: [0], sizes: [4], strides: [1] : memref<2xf32> to memref<4xf32> 49// CHECK-NEXT: scf.yield [[CAST]] 50// CHECK: return [[REALLOC]] 51 52// NODEALLOC-LABEL: func @reallow_lowering_example 53// NODEALLOC-NOT: dealloc 54 55// ----- 56 57func.func @reallow_lowering_example(%init_size: index) -> memref<4xf32> { 58 %alloc = memref.alloc(%init_size) : memref<?xf32> 59 %realloc = memref.realloc %alloc : memref<?xf32> to memref<4xf32> 60 return %realloc : memref<4xf32> 61} 62 63// CHECK-LABEL: func @reallow_lowering_example 64// CHECK-SAME: ([[INIT_SIZE:%.+]]: index) 65// CHECK-NEXT: [[OLD_ALLOC:%.+]] = memref.alloc([[INIT_SIZE]]) : memref<?xf32> 66// CHECK-NEXT: [[C0:%.+]] = arith.constant 0 67// CHECK-NEXT: [[CURR_SIZE:%.+]] = memref.dim [[OLD_ALLOC]], [[C0]] 68// CHECK-NEXT: [[NEW_SIZE:%.+]] = arith.constant 4 69// CHECK-NEXT: [[COND:%.+]] = arith.cmpi ult, [[CURR_SIZE]], [[NEW_SIZE]] 70// CHECK-NEXT: [[REALLOC:%.+]] = scf.if [[COND]] 71// CHECK-NEXT: [[NEW_ALLOC:%.+]] = memref.alloc() : memref<4xf32> 72// CHECK-NEXT: [[SUBVIEW:%.+]] = memref.subview [[NEW_ALLOC]][0] [[[CURR_SIZE]]] [1] 73// CHECK-NEXT: memref.copy [[OLD_ALLOC]], [[SUBVIEW]] 74// CHECK-NEXT: memref.dealloc [[OLD_ALLOC]] 75// CHECK-NEXT: scf.yield [[NEW_ALLOC]] 76// CHECK: [[CAST:%.+]] = memref.reinterpret_cast [[OLD_ALLOC]] to offset: [0], sizes: [4], strides: [1] : memref<?xf32> to memref<4xf32> 77// CHECK-NEXT: scf.yield [[CAST]] 78// CHECK: return [[REALLOC]] 79 80// NODEALLOC-LABEL: func @reallow_lowering_example 81// NODEALLOC-NOT: dealloc 82 83// ----- 84 85func.func @reallow_lowering_example(%new_size: index) -> memref<?xf32> { 86 %alloc = memref.alloc() : memref<2xf32> 87 %realloc = memref.realloc %alloc(%new_size) : memref<2xf32> to memref<?xf32> 88 return %realloc : memref<?xf32> 89} 90 91// CHECK-LABEL: func @reallow_lowering_example 92// CHECK-SAME: ([[NEW_SIZE:%.+]]: index) 93// CHECK-NEXT: [[OLD_ALLOC:%.+]] = memref.alloc() : memref<2xf32> 94// CHECK-NEXT: [[CURR_SIZE:%.+]] = arith.constant 2 95// CHECK-NEXT: [[COND:%.+]] = arith.cmpi ult, [[CURR_SIZE]], [[NEW_SIZE]] 96// CHECK-NEXT: [[REALLOC:%.+]] = scf.if [[COND]] 97// CHECK-NEXT: [[NEW_ALLOC:%.+]] = memref.alloc([[NEW_SIZE]]) : memref<?xf32> 98// CHECK-NEXT: [[SUBVIEW:%.+]] = memref.subview [[NEW_ALLOC]][0] [2] [1] 99// CHECK-NEXT: memref.copy [[OLD_ALLOC]], [[SUBVIEW]] 100// CHECK-NEXT: memref.dealloc [[OLD_ALLOC]] 101// CHECK-NEXT: scf.yield [[NEW_ALLOC]] 102// CHECK: [[CAST:%.+]] = memref.reinterpret_cast [[OLD_ALLOC]] to offset: [0], sizes: [[[NEW_SIZE]]], strides: [1] : memref<2xf32> to memref<?xf32> 103// CHECK-NEXT: scf.yield [[CAST]] 104// CHECK: return [[REALLOC]] 105 106// NODEALLOC-LABEL: func @reallow_lowering_example 107// NODEALLOC-NOT: dealloc 108