222 lines · plain
1// RUN: mlir-opt -one-shot-bufferize="test-analysis-only dump-alias-sets bufferize-function-boundaries" -split-input-file %s | FileCheck %s2 3// CHECK-LABEL: func @single_branch(4// CHECK-SAME: {__bbarg_alias_set_attr__ = [{{\[}}[{{\[}}"%[[arg1:.*]]", "%[[t:.*]]"]], [{{\[}}"%[[arg1]]", "%[[t]]"]]]]}5func.func @single_branch(%t: tensor<5xf32>) -> tensor<5xf32> {6// CHECK: cf.br7// CHECK-SAME: {__inplace_operands_attr__ = ["true"]}8 cf.br ^bb1(%t : tensor<5xf32>)9// CHECK: ^{{.*}}(%[[arg1]]: tensor<5xf32>)10^bb1(%arg1 : tensor<5xf32>):11 func.return %arg1 : tensor<5xf32>12}13 14// -----15 16// CHECK-LABEL: func @diamond_branch(17// CHECK-SAME: %{{.*}}: i1, %[[t0:.*]]: tensor<5xf32> {{.*}}, %[[t1:.*]]: tensor<5xf32> {{.*}}) -> tensor<5xf32>18// CHECK-SAME: {__bbarg_alias_set_attr__ = [{{\[}}[{{\[}}"%[[arg1:.*]]", "%[[arg3:.*]]", "%[[arg2:.*]]", "%[[t0]]", "%[[t1]]"], [19func.func @diamond_branch(%c: i1, %t0: tensor<5xf32>, %t1: tensor<5xf32>) -> tensor<5xf32> {20// CHECK: cf.cond_br21// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true", "true"]}22 cf.cond_br %c, ^bb1(%t0 : tensor<5xf32>), ^bb2(%t1 : tensor<5xf32>)23// CHECK: ^{{.*}}(%[[arg1]]: tensor<5xf32>):24^bb3(%arg1 : tensor<5xf32>):25 func.return %arg1 : tensor<5xf32>26// CHECK: ^{{.*}}(%[[arg2]]: tensor<5xf32>):27^bb1(%arg2 : tensor<5xf32>):28// CHECK: cf.br29// CHECK-SAME: {__inplace_operands_attr__ = ["true"]}30 cf.br ^bb3(%arg2 : tensor<5xf32>)31// CHECK: ^{{.*}}(%[[arg3]]: tensor<5xf32>):32^bb2(%arg3 : tensor<5xf32>):33// CHECK: cf.br34// CHECK-SAME: {__inplace_operands_attr__ = ["true"]}35 cf.br ^bb3(%arg3 : tensor<5xf32>)36}37 38// -----39 40// CHECK-LABEL: func @looping_branches(41// CHECK-SAME: {__bbarg_alias_set_attr__ = [{{\[}}[], [{{\[}}"%[[arg2:.*]]", "%[[arg1:.*]]", "%[[inserted:.*]]", "%[[empty:.*]]"]], [42func.func @looping_branches() -> tensor<5xf32> {43// CHECK: %[[empty]] = tensor.empty()44 %0 = tensor.empty() : tensor<5xf32>45// CHECK: cf.br46// CHECK-SAME: {__inplace_operands_attr__ = ["true"]}47 cf.br ^bb1(%0: tensor<5xf32>)48// CHECK: ^{{.*}}(%[[arg1]]: tensor<5xf32>):49^bb1(%arg1: tensor<5xf32>):50 %pos = "test.foo"() : () -> (index)51 %val = "test.bar"() : () -> (f32)52// CHECK: %[[inserted]] = tensor.insert53// CHECK-SAME: __inplace_operands_attr__ = ["none", "true", "none"]54 %inserted = tensor.insert %val into %arg1[%pos] : tensor<5xf32>55 %cond = "test.qux"() : () -> (i1)56// CHECK: cf.cond_br57// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true", "true"]}58 cf.cond_br %cond, ^bb1(%inserted: tensor<5xf32>), ^bb2(%inserted: tensor<5xf32>)59^bb2(%arg2: tensor<5xf32>):60 func.return %arg2 : tensor<5xf32>61}62 63// -----64 65// CHECK-LABEL: func @looping_branches_with_conflict(66func.func @looping_branches_with_conflict(%f: f32) -> tensor<5xf32> {67 %0 = tensor.empty() : tensor<5xf32>68 %filled = linalg.fill ins(%f : f32) outs(%0 : tensor<5xf32>) -> tensor<5xf32>69// CHECK: cf.br70// CHECK-SAME: {__inplace_operands_attr__ = ["false"]}71 cf.br ^bb1(%filled: tensor<5xf32>)72^bb2(%arg2: tensor<5xf32>):73 %pos2 = "test.foo"() : () -> (index)74 // One OpOperand cannot bufferize in-place because an "old" value is read.75 %element = tensor.extract %filled[%pos2] : tensor<5xf32>76 func.return %arg2 : tensor<5xf32>77^bb1(%arg1: tensor<5xf32>):78 %pos = "test.foo"() : () -> (index)79 %val = "test.bar"() : () -> (f32)80// CHECK: tensor.insert81// CHECK-SAME: __inplace_operands_attr__ = ["none", "true", "none"]82 %inserted = tensor.insert %val into %arg1[%pos] : tensor<5xf32>83 %cond = "test.qux"() : () -> (i1)84// CHECK: cf.cond_br85// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true", "true"]}86 cf.cond_br %cond, ^bb1(%inserted: tensor<5xf32>), ^bb2(%inserted: tensor<5xf32>)87}88 89// -----90 91// CHECK-LABEL: func @looping_branches_outside_def(92func.func @looping_branches_outside_def(%f: f32) {93// CHECK: %[[alloc:.*]] = bufferization.alloc_tensor()94 %0 = bufferization.alloc_tensor() : tensor<5xf32>95// CHECK: %[[fill:.*]] = linalg.fill96// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true"], __opresult_alias_set_attr__ = [{{\[}}"%[[fill]]", "%[[alloc]]"]]}97 %filled = linalg.fill ins(%f : f32) outs(%0 : tensor<5xf32>) -> tensor<5xf32>98 cf.br ^bb199^bb1:100 %pos = "test.foo"() : () -> (index)101 %val = "test.bar"() : () -> (f32)102// CHECK: tensor.insert103// CHECK-SAME: __inplace_operands_attr__ = ["none", "false", "none"]104 %inserted = tensor.insert %val into %filled[%pos] : tensor<5xf32>105 %pos2 = "test.foo"() : () -> (index)106 %read = tensor.extract %inserted[%pos2] : tensor<5xf32>107 %cond = "test.qux"(%read) : (f32) -> (i1)108 cf.cond_br %cond, ^bb1, ^bb2109^bb2:110 func.return111}112 113// -----114 115// CHECK-LABEL: func @looping_branches_outside_def2(116func.func @looping_branches_outside_def2(%f: f32) {117// CHECK: %[[alloc:.*]] = bufferization.alloc_tensor()118 %0 = bufferization.alloc_tensor() : tensor<5xf32>119// CHECK: %[[fill:.*]] = linalg.fill120// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true"], __opresult_alias_set_attr__ = [{{\[}}"%[[arg0:.*]]", "%[[fill]]", "%[[alloc]]"]]}121 %filled = linalg.fill ins(%f : f32) outs(%0 : tensor<5xf32>) -> tensor<5xf32>122// CHECK: cf.br {{.*}}(%[[fill]] : tensor<5xf32>)123// CHECK-SAME: __inplace_operands_attr__ = ["true"]124 cf.br ^bb1(%filled: tensor<5xf32>)125// CHECK: ^{{.*}}(%[[arg0]]: tensor<5xf32>):126^bb1(%arg0: tensor<5xf32>):127 %pos = "test.foo"() : () -> (index)128 %val = "test.bar"() : () -> (f32)129// CHECK: tensor.insert130// CHECK-SAME: __inplace_operands_attr__ = ["none", "false", "none"]131 %inserted = tensor.insert %val into %arg0[%pos] : tensor<5xf32>132 %pos2 = "test.foo"() : () -> (index)133 %read = tensor.extract %inserted[%pos2] : tensor<5xf32>134 %cond = "test.qux"(%read) : (f32) -> (i1)135// CHECK: cf.cond_br136// CHECK-SAME: __inplace_operands_attr__ = ["none", "true"]137 cf.cond_br %cond, ^bb1(%arg0: tensor<5xf32>), ^bb2138^bb2:139 func.return140}141 142// -----143 144// CHECK-LABEL: func @looping_branches_outside_def3(145func.func @looping_branches_outside_def3(%f: f32) {146// CHECK: %[[alloc:.*]] = bufferization.alloc_tensor()147 %0 = bufferization.alloc_tensor() : tensor<5xf32>148// CHECK: %[[fill:.*]] = linalg.fill149// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true"], __opresult_alias_set_attr__ = [{{\[}}"%[[arg0:.*]]", "%[[fill]]", "%[[alloc]]"]]}150 %filled = linalg.fill ins(%f : f32) outs(%0 : tensor<5xf32>) -> tensor<5xf32>151// CHECK: cf.br {{.*}}(%[[fill]] : tensor<5xf32>)152// CHECK-SAME: __inplace_operands_attr__ = ["true"]153 cf.br ^bb1(%filled: tensor<5xf32>)154// CHECK: ^{{.*}}(%[[arg0]]: tensor<5xf32>):155^bb1(%arg0: tensor<5xf32>):156 %pos = "test.foo"() : () -> (index)157 %val = "test.bar"() : () -> (f32)158// CHECK: tensor.insert159// CHECK-SAME: __inplace_operands_attr__ = ["none", "false", "none"]160 %inserted = tensor.insert %val into %arg0[%pos] : tensor<5xf32>161 %pos2 = "test.foo"() : () -> (index)162 %read = tensor.extract %inserted[%pos2] : tensor<5xf32>163 %cond = "test.qux"(%read) : (f32) -> (i1)164// CHECK: cf.cond_br165// CHECK-SAME: __inplace_operands_attr__ = ["none", "true"]166 cf.cond_br %cond, ^bb1(%filled: tensor<5xf32>), ^bb2167^bb2:168 func.return169}170 171// -----172 173// CHECK-LABEL: func @looping_branches_sequence_outside_def(174func.func @looping_branches_sequence_outside_def(%f: f32) {175// CHECK: %[[alloc:.*]] = bufferization.alloc_tensor()176 %0 = bufferization.alloc_tensor() : tensor<5xf32>177// CHECK: %[[fill:.*]] = linalg.fill178// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true"], __opresult_alias_set_attr__ = [{{\[}}"%[[fill]]", "%[[alloc]]"]]}179 %filled = linalg.fill ins(%f : f32) outs(%0 : tensor<5xf32>) -> tensor<5xf32>180 cf.br ^bb1181^bb1:182 %pos = "test.foo"() : () -> (index)183 %val = "test.bar"() : () -> (f32)184// CHECK: tensor.insert185// CHECK-SAME: __inplace_operands_attr__ = ["none", "false", "none"]186 %inserted = tensor.insert %val into %filled[%pos] : tensor<5xf32>187 cf.br ^bb2188^bb2:189 %pos2 = "test.foo"() : () -> (index)190 %read = tensor.extract %inserted[%pos2] : tensor<5xf32>191 %cond = "test.qux"(%read) : (f32) -> (i1)192 cf.cond_br %cond, ^bb1, ^bb3193^bb3:194 func.return195}196 197// -----198 199// CHECK-LABEL: func @looping_branches_sequence_inside_def(200func.func @looping_branches_sequence_inside_def(%f: f32) {201 cf.br ^bb1202^bb1:203// CHECK: %[[alloc:.*]] = bufferization.alloc_tensor()204 %0 = bufferization.alloc_tensor() : tensor<5xf32>205// CHECK: %[[fill:.*]] = linalg.fill206// CHECK-SAME: {__inplace_operands_attr__ = ["none", "true"], __opresult_alias_set_attr__ = [{{\[}}"%[[inserted:.*]]", "%[[fill]]", "%[[alloc]]"]]}207 %filled = linalg.fill ins(%f : f32) outs(%0 : tensor<5xf32>) -> tensor<5xf32>208 %pos = "test.foo"() : () -> (index)209 %val = "test.bar"() : () -> (f32)210// CHECK: %[[inserted]] = tensor.insert211// CHECK-SAME: __inplace_operands_attr__ = ["none", "true", "none"]212 %inserted = tensor.insert %val into %filled[%pos] : tensor<5xf32>213 cf.br ^bb2214^bb2:215 %pos2 = "test.foo"() : () -> (index)216 %read = tensor.extract %inserted[%pos2] : tensor<5xf32>217 %cond = "test.qux"(%read) : (f32) -> (i1)218 cf.cond_br %cond, ^bb1, ^bb3219^bb3:220 func.return221}222