1// RUN: mlir-opt %s -split-input-file -verify-diagnostics 2 3func.func @alloc_tensor_missing_dims(%arg0: index) 4{ 5 // expected-error @+1 {{expected 2 dynamic sizes}} 6 %0 = bufferization.alloc_tensor(%arg0) : tensor<4x?x?x5xf32> 7 return 8} 9 10// ----- 11 12// expected-note @+1 {{prior use here}} 13func.func @alloc_tensor_type_mismatch(%t: tensor<?xf32>) { 14 // expected-error @+1{{expects different type than prior uses: 'tensor<5xf32>' vs 'tensor<?xf32>'}} 15 %0 = bufferization.alloc_tensor() copy(%t) : tensor<5xf32> 16 return 17} 18 19// ----- 20 21func.func @alloc_tensor_copy_and_dims(%t: tensor<?xf32>, %sz: index) { 22 // expected-error @+1{{dynamic sizes not needed when copying a tensor}} 23 %0 = bufferization.alloc_tensor(%sz) copy(%t) : tensor<?xf32> 24 return 25} 26 27// ----- 28 29// expected-error @+1{{invalid value for 'bufferization.access'}} 30func.func private @invalid_buffer_access_type(tensor<*xf32> {bufferization.access = "foo"}) 31 32// ----- 33 34// expected-error @+1{{'bufferization.writable' is invalid on external functions}} 35func.func private @invalid_writable_attribute(tensor<*xf32> {bufferization.writable = false}) 36 37// ----- 38 39func.func @invalid_writable_on_op() { 40 // expected-error @+1{{attribute '"bufferization.writable"' not supported as an op attribute by the bufferization dialect}} 41 arith.constant {bufferization.writable = true} 0 : index 42} 43 44// ----- 45 46func.func @invalid_materialize_in_destination(%arg0: tensor<4xf32>, %arg1: tensor<5xf32>) { 47 // expected-error @below{{source/destination shapes are incompatible}} 48 bufferization.materialize_in_destination %arg0 in %arg1 : (tensor<4xf32>, tensor<5xf32>) -> tensor<5xf32> 49} 50 51// ----- 52 53func.func @invalid_materialize_in_destination(%arg0: tensor<5x5xf32>, %arg1: tensor<5xf32>) { 54 // expected-error @below{{rank mismatch between source and destination shape}} 55 bufferization.materialize_in_destination %arg0 in %arg1 : (tensor<5x5xf32>, tensor<5xf32>) -> tensor<5xf32> 56} 57 58// ----- 59 60func.func @invalid_materialize_in_destination_dest_type(%arg0: tensor<5xf32>, %arg1: vector<5xf32>) { 61 // expected-error @below{{'dest' must be a tensor or a memref}} 62 bufferization.materialize_in_destination %arg0 in %arg1 : (tensor<5xf32>, vector<5xf32>) -> () 63} 64 65// ----- 66 67func.func @invalid_materialize_in_destination_result(%arg0: tensor<?xf32>, %arg1: memref<?xf32>) { 68 // expected-error @below{{memref 'dest' implies zero results}} 69 bufferization.materialize_in_destination %arg0 in restrict %arg1 : (tensor<?xf32>, memref<?xf32>) -> (tensor<?xf32>) 70} 71 72// ----- 73 74func.func @invalid_materialize_in_destination_result_missing(%arg0: tensor<?xf32>, %arg1: tensor<?xf32>) { 75 // expected-error @below{{tensor 'dest' implies exactly one tensor result}} 76 bufferization.materialize_in_destination %arg0 in %arg1 : (tensor<?xf32>, tensor<?xf32>) -> () 77} 78 79// ----- 80 81func.func @invalid_materialize_in_destination_restrict(%arg0: tensor<?xf32>, %arg1: tensor<?xf32>) { 82 // expected-error @below{{'restrict' is valid only for memref destinations}} 83 bufferization.materialize_in_destination %arg0 in restrict %arg1 : (tensor<?xf32>, tensor<?xf32>) -> (tensor<?xf32>) 84} 85 86// ----- 87 88func.func @invalid_materialize_in_destination_restrict(%arg0: tensor<?xf32>, %arg1: tensor<?xf32>) { 89 // expected-error @below{{'writable' must be specified if and only if the destination is of memref type}} 90 bufferization.materialize_in_destination %arg0 in writable %arg1 : (tensor<?xf32>, tensor<?xf32>) -> (tensor<?xf32>) 91} 92 93// ----- 94 95func.func @invalid_materialize_in_destination_result_shape(%arg0: tensor<?xf32>, %arg1: tensor<?xf32>) { 96 // expected-error @below{{result and 'dest' types must match}} 97 bufferization.materialize_in_destination %arg0 in %arg1 : (tensor<?xf32>, tensor<?xf32>) -> (tensor<6xf32>) 98} 99 100// ----- 101 102func.func @invalid_dealloc_memref_condition_mismatch(%arg0: memref<2xf32>, %arg1: memref<4xi32>, %arg2: i1) { 103 // expected-error @below{{must have the same number of conditions as memrefs to deallocate}} 104 bufferization.dealloc (%arg0, %arg1 : memref<2xf32>, memref<4xi32>) if (%arg2) 105 return 106} 107 108// ----- 109 110func.func @invalid_dealloc_wrong_number_of_results(%arg0: memref<2xf32>, %arg1: memref<4xi32>, %arg2: i1) -> i1 { 111 // expected-error @below{{operation defines 1 results but was provided 2 to bind}} 112 %0:2 = bufferization.dealloc (%arg0, %arg1 : memref<2xf32>, memref<4xi32>) if (%arg2, %arg2) retain (%arg1 : memref<4xi32>) 113 return %0#0 : i1 114} 115 116// ----- 117 118func.func @invalid_dealloc_wrong_number_of_results(%arg0: memref<2xf32>, %arg1: memref<4xi32>, %arg2: i1) -> i1 { 119 // expected-error @below{{must have the same number of updated conditions (results) as retained operands}} 120 %0:3 = "bufferization.dealloc"(%arg0, %arg1, %arg2, %arg2, %arg1) <{operandSegmentSizes = array<i32: 2, 2, 1>}> : (memref<2xf32>, memref<4xi32>, i1, i1, memref<4xi32>) -> (i1, i1, i1) 121 return %0#0 : i1 122} 123 124// ----- 125 126func.func @invalid_manual_deallocation() { 127 // expected-error @below{{op attribute 'bufferization.manual_deallocation' can be used only on ops that have an allocation and/or free side effect}} 128 arith.constant {bufferization.manual_deallocation} 0 : index 129} 130