brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · 454c17a Raw
189 lines · plain
1// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only" \2// RUN:     -allow-unregistered-dialect -split-input-file | FileCheck %s3 4// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only dump-alias-sets" \5// RUN:     -allow-unregistered-dialect -split-input-file | \6// RUN: FileCheck %s --check-prefix=CHECK-ALIAS-SETS7 8// CHECK-LABEL: func @unknown_op_aliasing(9// CHECK-ALIAS-SETS-LABEL: func @unknown_op_aliasing(10func.func @unknown_op_aliasing(%f: f32, %f2: f32, %pos: index) -> f32 {11  // CHECK-ALIAS-SETS: %[[empty:.*]] = tensor.empty12 13  %0 = tensor.empty() : tensor<10xf32>14  // CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "true"]}15  // CHECK-ALIAS-SETS: %[[fill1:.*]] = linalg.fill16  %1 = linalg.fill ins(%f : f32) outs(%0 : tensor<10xf32>) -> tensor<10xf32>17 18  // Something must bufferize out-of-place because the op may return an alias19  // of %1.20  // CHECK: "dummy.dummy_op"(%{{.*}}) {__inplace_operands_attr__ = ["false"]}21  %alias = "dummy.dummy_op"(%1) : (tensor<10xf32>) -> (tensor<10xf32>)22 23  // CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "true"]}24  // CHECK-ALIAS-SETS: %[[fill2:.*]] = linalg.fill25  // CHECK-ALIAS-SETS-SAME: __opresult_alias_set_attr__ = [{{\[}}"%[[fill2]]", "%[[fill1]]", "%[[empty]]"]]26  %2 = linalg.fill ins(%f2 : f32) outs(%1 : tensor<10xf32>) -> tensor<10xf32>27  %3 = tensor.extract %alias[%pos] : tensor<10xf32>28  return %3 : f3229}30 31// -----32 33// CHECK-LABEL: func @unknown_op_bbarg_aliasing(34// CHECK-ALIAS-SETS-LABEL: func @unknown_op_bbarg_aliasing(35func.func @unknown_op_bbarg_aliasing() {36  %0 = tensor.empty() : tensor<7xf32>37 38  // %arg0 is not aliasing with %0 because it bufferizes out-of-place.39  // CHECK-ALIAS-SETS: "dummy.dummy_op"40  // CHECK-ALIAS-SETS-NEXT: ^{{.*}}(%[[arg:.*]]: tensor<7xf32>):41  // CHECK-ALIAS-SETS-NEXT: }) {__bbarg_alias_set_attr__ = [{{\[}}[{{\[}}"%[[arg]]"]]]], __inplace_operands_attr__ = ["false"]} : (tensor<7xf32>) -> ()42  "dummy.dummy_op"(%0) ({43  ^bb0(%arg1: tensor<7xf32>):44  }) : (tensor<7xf32>) -> ()45  return46}47 48// -----49 50// CHECK-LABEL: func @unknown_op_writing(51func.func @unknown_op_writing(%f: f32, %f2: f32, %pos: index) -> f32 {52  %0 = tensor.empty() : tensor<10xf32>53  // CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "true"]}54  %1 = linalg.fill ins(%f : f32) outs(%0 : tensor<10xf32>) -> tensor<10xf32>55 56  // The op may bufferize to a memory write, so it must bufferize out-of-place.57  // CHECK: "dummy.dummy_op"(%{{.*}}) {__inplace_operands_attr__ = ["false"]}58  "dummy.dummy_op"(%1) : (tensor<10xf32>) -> ()59 60  %3 = tensor.extract %1[%pos] : tensor<10xf32>61  return %3 : f3262}63 64// -----65 66// CHECK-LABEL: func @read_of_undef_is_not_a_conflict(67func.func @read_of_undef_is_not_a_conflict(%f: f32, %idx: index) -> f32 {68  %0 = tensor.empty() : tensor<10xf32>69  // This can be in-place because the read below does reads undefined data.70  // CHECK: tensor.insert {{.*}} {__inplace_operands_attr__ = ["none", "true", "none"]}71  %1 = tensor.insert %f into %0[%idx] : tensor<10xf32>72  %2 = tensor.extract %0[%idx] : tensor<10xf32>73  return %2 : f3274}75 76// -----77 78// CHECK-LABEL: func @read_of_alloc_tensor_is_not_a_conflict(79func.func @read_of_alloc_tensor_is_not_a_conflict(%f: f32, %idx: index) -> f32 {80  %0 = bufferization.alloc_tensor() : tensor<10xf32>81  // This can be in-place because the read below does reads undefined data.82  // CHECK: tensor.insert {{.*}} {__inplace_operands_attr__ = ["none", "true", "none"]}83  %1 = tensor.insert %f into %0[%idx] : tensor<10xf32>84  %2 = tensor.extract %0[%idx] : tensor<10xf32>85  return %2 : f3286}87 88// -----89 90// CHECK-LABEL: func @to_buffer_not_read_only(91func.func @to_buffer_not_read_only(%idx : index, %f: f32) -> f32 {92  %t = tensor.generate {93  ^bb0(%i : index):94    tensor.yield %f : f3295  } : tensor<5xf32>96  // Some op may write into the result of to_buffer later.97  // CHECK: bufferization.to_buffer98  // CHECK-SAME: {__inplace_operands_attr__ = ["false"]}99  %m = bufferization.to_buffer %t : tensor<5xf32> to memref<5xf32>100  %2 = tensor.extract %t[%idx] : tensor<5xf32>101  return %2 : f32102}103 104// -----105 106// CHECK-LABEL: func @to_buffer_read_only(107func.func @to_buffer_read_only(%idx : index, %f: f32) -> f32 {108  %t = tensor.generate {109  ^bb0(%i : index):110    tensor.yield %f : f32111  } : tensor<5xf32>112  // Some op may write into the result of to_buffer later.113  // CHECK: bufferization.to_buffer114  // CHECK-SAME: {__inplace_operands_attr__ = ["true"]}115  %m = bufferization.to_buffer %t {read_only} : tensor<5xf32> to memref<5xf32>116  %2 = tensor.extract %t[%idx] : tensor<5xf32>117  return %2 : f32118}119 120// -----121 122// CHECK-LABEL: func @bbarg_of_unknown_op(123func.func @bbarg_of_unknown_op(%f: f32) {124  %0 = tensor.empty() : tensor<10xf32>125  // CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "true"]}126  %1 = linalg.fill ins(%f : f32) outs(%0 : tensor<10xf32>) -> tensor<10xf32>127 128  // The op is not bufferizable because %1 is assumed to alias with %arg1.129  // BlockArguments are considered "not writable" by default. So %1 is also130  // considered "not writable".131 132  // CHECK: "dummy.dummy_op"133  // CHECK: {__inplace_operands_attr__ = ["false"]} : (tensor<10xf32>) -> ()134  "dummy.dummy_op"(%1) ({135  ^bb0(%arg1: tensor<10xf32>):136  }) : (tensor<10xf32>) -> ()137  return138}139 140// -----141 142// CHECK-LABEL: func @bbarg_of_unknown_op_2(143func.func @bbarg_of_unknown_op_2(%f: f32) {144  %0 = tensor.empty() : tensor<10xf32>145  // CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "true"]}146  %1 = linalg.fill ins(%f : f32) outs(%0 : tensor<10xf32>) -> tensor<10xf32>147 148  // The op is not bufferizable because %1 is assumed to alias with %arg1.149  // BlockArguments are considered "not writable" by default. So %1 is also150  // considered "not writable".151 152  // CHECK: "dummy.dummy_op"153  "dummy.dummy_op"(%1) ({154  ^bb0(%arg1: tensor<10xf32>):155    // CHECK: "dummy.another_op"(%{{.*}}) {__inplace_operands_attr__ = ["false"]}156    "dummy.another_op"(%arg1) : (tensor<10xf32>) -> ()157  }) : (tensor<10xf32>) -> ()158  // CHECK: {__inplace_operands_attr__ = ["false"]} : (tensor<10xf32>) -> ()159  return160}161 162// -----163 164// CHECK: func @materialize_in_destination_aliasing(165func.func @materialize_in_destination_aliasing(%t: tensor<?xf32>, %p1: index, %p2: index, %sz: index) -> tensor<5xf32> {166  %buffer = tensor.empty(%sz) : tensor<?xf32>167  // CHECK: tensor.extract_slice168  // CHECK-SAME: {__inplace_operands_attr__ = ["true", "none"]}169  %src = tensor.extract_slice %t[%p1][5][1] : tensor<?xf32> to tensor<5xf32>170  // CHECK: tensor.extract_slice171  // CHECK-SAME: {__inplace_operands_attr__ = ["false", "none"]}172  %dest = tensor.extract_slice %t[%p2][5][1] : tensor<?xf32> to tensor<5xf32>173  // CHECK: bufferization.materialize_in_destination174  // CHECK-SAME: {__inplace_operands_attr__ = ["true", "true"]}175  %r = bufferization.materialize_in_destination %src in %dest : (tensor<5xf32>, tensor<5xf32>) -> tensor<5xf32>176  return %r : tensor<5xf32>177}178 179// -----180 181// CHECK: func @materialize_in_destination(182func.func @materialize_in_destination(%t: tensor<?xf32>, %sz: index) -> tensor<?xf32> {183  %buffer = tensor.empty(%sz) : tensor<?xf32>184  // CHECK: bufferization.materialize_in_destination185  // CHECK-SAME: {__inplace_operands_attr__ = ["true", "true"]}186  %r = bufferization.materialize_in_destination %buffer in %buffer : (tensor<?xf32>, tensor<?xf32>) -> tensor<?xf32>187  return %r : tensor<?xf32>188}189