1// RUN: mlir-opt -verify-diagnostics -ownership-based-buffer-deallocation -split-input-file %s
2
3
4// Test Case: explicit control-flow loop with a dynamically allocated buffer.
5// The BufferDeallocation transformation should fail on this explicit
6// control-flow loop since they are not supported.
7
8// expected-error@+1 {{Only structured control-flow loops are supported}}
9func.func @loop_dynalloc(
10  %arg0 : i32,
11  %arg1 : i32,
12  %arg2: memref<?xf32>,
13  %arg3: memref<?xf32>) {
14  %const0 = arith.constant 0 : i32
15  cf.br ^loopHeader(%const0, %arg2 : i32, memref<?xf32>)
16
17^loopHeader(%i : i32, %buff : memref<?xf32>):
18  %lessThan = arith.cmpi slt, %i, %arg1 : i32
19  cf.cond_br %lessThan,
20    ^loopBody(%i, %buff : i32, memref<?xf32>),
21    ^exit(%buff : memref<?xf32>)
22
23^loopBody(%val : i32, %buff2: memref<?xf32>):
24  %const1 = arith.constant 1 : i32
25  %inc = arith.addi %val, %const1 : i32
26  %size = arith.index_cast %inc : i32 to index
27  %alloc1 = memref.alloc(%size) : memref<?xf32>
28  cf.br ^loopHeader(%inc, %alloc1 : i32, memref<?xf32>)
29
30^exit(%buff3 : memref<?xf32>):
31  test.copy(%buff3, %arg3) : (memref<?xf32>, memref<?xf32>)
32  return
33}
34
35// -----
36
37// Test Case: explicit control-flow loop with a dynamically allocated buffer.
38// The BufferDeallocation transformation should fail on this explicit
39// control-flow loop since they are not supported.
40
41// expected-error@+1 {{Only structured control-flow loops are supported}}
42func.func @do_loop_alloc(
43  %arg0 : i32,
44  %arg1 : i32,
45  %arg2: memref<2xf32>,
46  %arg3: memref<2xf32>) {
47  %const0 = arith.constant 0 : i32
48  cf.br ^loopBody(%const0, %arg2 : i32, memref<2xf32>)
49
50^loopBody(%val : i32, %buff2: memref<2xf32>):
51  %const1 = arith.constant 1 : i32
52  %inc = arith.addi %val, %const1 : i32
53  %alloc1 = memref.alloc() : memref<2xf32>
54  cf.br ^loopHeader(%inc, %alloc1 : i32, memref<2xf32>)
55
56^loopHeader(%i : i32, %buff : memref<2xf32>):
57  %lessThan = arith.cmpi slt, %i, %arg1 : i32
58  cf.cond_br %lessThan,
59    ^loopBody(%i, %buff : i32, memref<2xf32>),
60    ^exit(%buff : memref<2xf32>)
61
62^exit(%buff3 : memref<2xf32>):
63  test.copy(%buff3, %arg3) : (memref<2xf32>, memref<2xf32>)
64  return
65}
66
67// -----
68
69func.func @free_effect() {
70  %alloc = memref.alloc() : memref<2xi32>
71  // expected-error @below {{memory free side-effect on MemRef value not supported!}}
72  %new_alloc = memref.realloc %alloc : memref<2xi32> to memref<4xi32>
73  return
74}
75
76// -----
77
78func.func @free_effect() {
79  %alloc = memref.alloc() : memref<2xi32>
80  // expected-error @below {{memory free side-effect on MemRef value not supported!}}
81  memref.dealloc %alloc : memref<2xi32>
82  return
83}
84
85// -----
86
87func.func @free_effect() {
88  %true = arith.constant true
89  %alloc = memref.alloc() : memref<2xi32>
90  // expected-error @below {{No deallocation operations must be present when running this pass!}}
91  bufferization.dealloc (%alloc : memref<2xi32>) if (%true)
92  return
93}
94