176 lines · plain
1// RUN: mlir-opt %s --pass-pipeline="builtin.module(func.func(sroa))" --split-input-file | FileCheck %s2 3// CHECK-LABEL: func.func @basic4// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32)5func.func @basic(%arg0: i32, %arg1: i32) -> i32 {6 %c0 = arith.constant 0 : index7 %c1 = arith.constant 1 : index8 // CHECK-NOT: = memref.alloca()9 // CHECK-COUNT-2: = memref.alloca() : memref<i32>10 // CHECK-NOT: = memref.alloca()11 %alloca = memref.alloca() : memref<2xi32>12 // CHECK: memref.store %[[ARG0]], %[[ALLOCA0:.*]][]13 memref.store %arg0, %alloca[%c0] : memref<2xi32>14 // CHECK: memref.store %[[ARG1]], %[[ALLOCA1:.*]][]15 memref.store %arg1, %alloca[%c1] : memref<2xi32>16 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA0]][]17 %res = memref.load %alloca[%c0] : memref<2xi32>18 // CHECK: return %[[RES]] : i3219 return %res : i3220}21 22// -----23 24// CHECK-LABEL: func.func @basic_high_dimensions25// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32, %[[ARG2:.*]]: i32)26func.func @basic_high_dimensions(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {27 %c0 = arith.constant 0 : index28 %c1 = arith.constant 1 : index29 // CHECK-NOT: = memref.alloca()30 // CHECK-COUNT-3: = memref.alloca() : memref<i32>31 // CHECK-NOT: = memref.alloca()32 %alloca = memref.alloca() : memref<2x2xi32>33 // CHECK: memref.store %[[ARG0]], %[[ALLOCA0:.*]][]34 memref.store %arg0, %alloca[%c0, %c0] : memref<2x2xi32>35 // CHECK: memref.store %[[ARG1]], %[[ALLOCA1:.*]][]36 memref.store %arg1, %alloca[%c0, %c1] : memref<2x2xi32>37 // CHECK: memref.store %[[ARG2]], %[[ALLOCA2:.*]][]38 memref.store %arg2, %alloca[%c1, %c0] : memref<2x2xi32>39 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA1]][]40 %res = memref.load %alloca[%c0, %c1] : memref<2x2xi32>41 // CHECK: return %[[RES]] : i3242 return %res : i3243}44 45// -----46 47// CHECK-LABEL: func.func @resolve_alias48// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32)49func.func @resolve_alias(%arg0: i32, %arg1: i32) -> i32 {50 %c0 = arith.constant 0 : index51 // CHECK-NOT: = memref.alloca()52 // CHECK: %[[ALLOCA:.*]] = memref.alloca() : memref<i32>53 // CHECK-NOT: = memref.alloca()54 %alloca = memref.alloca() : memref<2xi32>55 // CHECK: memref.store %[[ARG0]], %[[ALLOCA]][]56 memref.store %arg0, %alloca[%c0] : memref<2xi32>57 // CHECK: memref.store %[[ARG1]], %[[ALLOCA]][]58 memref.store %arg1, %alloca[%c0] : memref<2xi32>59 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA]][]60 %res = memref.load %alloca[%c0] : memref<2xi32>61 // CHECK: return %[[RES]] : i3262 return %res : i3263}64 65// -----66 67// CHECK-LABEL: func.func @no_direct_use68// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32)69func.func @no_direct_use(%arg0: i32, %arg1: i32) -> i32 {70 // CHECK: %[[C0:.*]] = arith.constant 0 : index71 %c0 = arith.constant 0 : index72 // CHECK: %[[C1:.*]] = arith.constant 1 : index73 %c1 = arith.constant 1 : index74 // CHECK-NOT: = memref.alloca()75 // CHECK: %[[ALLOCA:.*]] = memref.alloca() : memref<2xi32>76 // CHECK-NOT: = memref.alloca()77 %alloca = memref.alloca() : memref<2xi32>78 // CHECK: memref.store %[[ARG0]], %[[ALLOCA]][%[[C0]]]79 memref.store %arg0, %alloca[%c0] : memref<2xi32>80 // CHECK: memref.store %[[ARG1]], %[[ALLOCA]][%[[C1]]]81 memref.store %arg1, %alloca[%c1] : memref<2xi32>82 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA]][%[[C0]]]83 %res = memref.load %alloca[%c0] : memref<2xi32>84 call @use(%alloca) : (memref<2xi32>) -> ()85 // CHECK: return %[[RES]] : i3286 return %res : i3287}88 89func.func @use(%foo: memref<2xi32>) { return }90 91// -----92 93// CHECK-LABEL: func.func @no_dynamic_indexing94// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32, %[[INDEX:.*]]: index)95func.func @no_dynamic_indexing(%arg0: i32, %arg1: i32, %index: index) -> i32 {96 // CHECK: %[[C0:.*]] = arith.constant 0 : index97 %c0 = arith.constant 0 : index98 // CHECK-NOT: = memref.alloca()99 // CHECK: %[[ALLOCA:.*]] = memref.alloca() : memref<2xi32>100 // CHECK-NOT: = memref.alloca()101 %alloca = memref.alloca() : memref<2xi32>102 // CHECK: memref.store %[[ARG0]], %[[ALLOCA]][%[[C0]]]103 memref.store %arg0, %alloca[%c0] : memref<2xi32>104 // CHECK: memref.store %[[ARG1]], %[[ALLOCA]][%[[INDEX]]]105 memref.store %arg1, %alloca[%index] : memref<2xi32>106 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA]][%[[C0]]]107 %res = memref.load %alloca[%c0] : memref<2xi32>108 // CHECK: return %[[RES]] : i32109 return %res : i32110}111 112// -----113 114// CHECK-LABEL: func.func @no_dynamic_shape115// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32)116func.func @no_dynamic_shape(%arg0: i32, %arg1: i32) -> i32 {117 // CHECK: %[[C0:.*]] = arith.constant 0 : index118 %c0 = arith.constant 0 : index119 // CHECK: %[[C1:.*]] = arith.constant 1 : index120 %c1 = arith.constant 1 : index121 // CHECK-NOT: = memref.alloca()122 // CHECK: %[[ALLOCA:.*]] = memref.alloca(%[[C1]]) : memref<?x2xi32>123 // CHECK-NOT: = memref.alloca()124 %alloca = memref.alloca(%c1) : memref<?x2xi32>125 // CHECK: memref.store %[[ARG0]], %[[ALLOCA]][%[[C0]], %[[C0]]]126 memref.store %arg0, %alloca[%c0, %c0] : memref<?x2xi32>127 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA]][%[[C0]], %[[C0]]]128 %res = memref.load %alloca[%c0, %c0] : memref<?x2xi32>129 // CHECK: return %[[RES]] : i32130 return %res : i32131}132 133// -----134 135// CHECK-LABEL: func.func @no_out_of_bound_write136// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32)137func.func @no_out_of_bound_write(%arg0: i32, %arg1: i32) -> i32 {138 // CHECK: %[[C0:.*]] = arith.constant 0 : index139 %c0 = arith.constant 0 : index140 // CHECK: %[[C100:.*]] = arith.constant 100 : index141 %c100 = arith.constant 100 : index142 // CHECK-NOT: = memref.alloca()143 // CHECK: %[[ALLOCA:.*]] = memref.alloca() : memref<2xi32>144 // CHECK-NOT: = memref.alloca()145 %alloca = memref.alloca() : memref<2xi32>146 // CHECK: memref.store %[[ARG0]], %[[ALLOCA]][%[[C0]]]147 memref.store %arg0, %alloca[%c0] : memref<2xi32>148 // CHECK: memref.store %[[ARG1]], %[[ALLOCA]][%[[C100]]]149 memref.store %arg1, %alloca[%c100] : memref<2xi32>150 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA]][%[[C0]]]151 %res = memref.load %alloca[%c0] : memref<2xi32>152 // CHECK: return %[[RES]] : i32153 return %res : i32154}155 156// -----157 158// CHECK-LABEL: func.func @no_out_of_bound_load159// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32)160func.func @no_out_of_bound_load(%arg0: i32, %arg1: i32) -> i32 {161 // CHECK: %[[C0:.*]] = arith.constant 0 : index162 %c0 = arith.constant 0 : index163 // CHECK: %[[C100:.*]] = arith.constant 100 : index164 %c100 = arith.constant 100 : index165 // CHECK-NOT: = memref.alloca()166 // CHECK: %[[ALLOCA:.*]] = memref.alloca() : memref<2xi32>167 // CHECK-NOT: = memref.alloca()168 %alloca = memref.alloca() : memref<2xi32>169 // CHECK: memref.store %[[ARG0]], %[[ALLOCA]][%[[C0]]]170 memref.store %arg0, %alloca[%c0] : memref<2xi32>171 // CHECK: %[[RES:.*]] = memref.load %[[ALLOCA]][%[[C100]]]172 %res = memref.load %alloca[%c100] : memref<2xi32>173 // CHECK: return %[[RES]] : i32174 return %res : i32175}176