416 lines · plain
1// RUN: mlir-opt %s --split-input-file --duplicate-function-elimination | \2// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-2,CHECK-33 4func.func @identity(%arg0: tensor<f32>) -> tensor<f32> {5 return %arg0 : tensor<f32>6}7 8func.func @also_identity(%arg0: tensor<f32>) -> tensor<f32> {9 return %arg0 : tensor<f32>10}11 12func.func @yet_another_identity(%arg0: tensor<f32>) -> tensor<f32> {13 return %arg0 : tensor<f32>14}15 16func.func @user(%arg0: tensor<f32>) -> tensor<f32> {17 %0 = call @identity(%arg0) : (tensor<f32>) -> tensor<f32>18 %1 = call @also_identity(%0) : (tensor<f32>) -> tensor<f32>19 %2 = call @yet_another_identity(%1) : (tensor<f32>) -> tensor<f32>20 return %2 : tensor<f32>21}22 23// CHECK: @identity24// CHECK-NOT: @also_identity25// CHECK-NOT: @yet_another_identity26// CHECK: @user27// CHECK-3: call @identity28 29// -----30 31func.func @add_lr(%arg0: f32, %arg1: f32) -> f32 {32 %0 = arith.addf %arg0, %arg1 : f3233 return %0 : f3234}35 36func.func @also_add_lr(%arg0: f32, %arg1: f32) -> f32 {37 %0 = arith.addf %arg0, %arg1 : f3238 return %0 : f3239}40 41func.func @add_rl(%arg0: f32, %arg1: f32) -> f32 {42 %0 = arith.addf %arg1, %arg0 : f3243 return %0 : f3244}45 46func.func @also_add_rl(%arg0: f32, %arg1: f32) -> f32 {47 %0 = arith.addf %arg1, %arg0 : f3248 return %0 : f3249}50 51func.func @user(%arg0: f32, %arg1: f32) -> f32 {52 %0 = call @add_lr(%arg0, %arg1) : (f32, f32) -> f3253 %1 = call @also_add_lr(%arg0, %arg1) : (f32, f32) -> f3254 %2 = call @add_rl(%0, %1) : (f32, f32) -> f3255 %3 = call @also_add_rl(%arg0, %2) : (f32, f32) -> f3256 return %3 : f3257}58 59// CHECK: @add_lr60// CHECK-NOT: @also_add_lr61// CHECK: @add_rl62// CHECK-NOT: @also_add_rl63// CHECK: @user64// CHECK-2: call @add_lr65// CHECK-2: call @add_rl66 67// -----68 69func.func @ite(%pred: i1, %then: f32, %else: f32) -> f32 {70 %0 = scf.if %pred -> f32 {71 scf.yield %then : f3272 } else {73 scf.yield %else : f3274 }75 return %0 : f3276}77 78func.func @also_ite(%pred: i1, %then: f32, %else: f32) -> f32 {79 %0 = scf.if %pred -> f32 {80 scf.yield %then : f3281 } else {82 scf.yield %else : f3283 }84 return %0 : f3285}86 87func.func @reverse_ite(%pred: i1, %then: f32, %else: f32) -> f32 {88 %0 = scf.if %pred -> f32 {89 scf.yield %else : f3290 } else {91 scf.yield %then : f3292 }93 return %0 : f3294}95 96func.func @user(%pred : i1, %arg0: f32, %arg1: f32) -> f32 {97 %0 = call @also_ite(%pred, %arg0, %arg1) : (i1, f32, f32) -> f3298 %1 = call @ite(%pred, %arg0, %arg1) : (i1, f32, f32) -> f3299 %2 = call @reverse_ite(%pred, %0, %1) : (i1, f32, f32) -> f32100 return %2 : f32101}102 103// CHECK: @ite104// CHECK-NOT: @also_ite105// CHECK: @reverse_ite106// CHECK: @user107// CHECK-2: call @ite108// CHECK: call @reverse_ite109 110// -----111 112func.func @deep_tree(%p0: i1, %p1: i1, %p2: i1, %p3: i1, %even: f32, %odd: f32)113 -> f32 {114 %0 = scf.if %p0 -> f32 {115 %1 = scf.if %p1 -> f32 {116 %2 = scf.if %p2 -> f32 {117 %3 = scf.if %p3 -> f32 {118 scf.yield %even : f32119 } else {120 scf.yield %odd : f32121 }122 scf.yield %3 : f32123 } else {124 %3 = scf.if %p3 -> f32 {125 scf.yield %odd : f32126 } else {127 scf.yield %even : f32128 }129 scf.yield %3 : f32130 }131 scf.yield %2 : f32132 } else {133 %2 = scf.if %p2 -> f32 {134 %3 = scf.if %p3 -> f32 {135 scf.yield %odd : f32136 } else {137 scf.yield %even : f32138 }139 scf.yield %3 : f32140 } else {141 %3 = scf.if %p3 -> f32 {142 scf.yield %even : f32143 } else {144 scf.yield %odd : f32145 }146 scf.yield %3 : f32147 }148 scf.yield %2 : f32149 }150 scf.yield %1 : f32151 } else {152 %1 = scf.if %p1 -> f32 {153 %2 = scf.if %p2 -> f32 {154 %3 = scf.if %p3 -> f32 {155 scf.yield %odd : f32156 } else {157 scf.yield %even : f32158 }159 scf.yield %3 : f32160 } else {161 %3 = scf.if %p3 -> f32 {162 scf.yield %even : f32163 } else {164 scf.yield %odd : f32165 }166 scf.yield %3 : f32167 }168 scf.yield %2 : f32169 } else {170 %2 = scf.if %p2 -> f32 {171 %3 = scf.if %p3 -> f32 {172 scf.yield %even : f32173 } else {174 scf.yield %odd : f32175 }176 scf.yield %3 : f32177 } else {178 %3 = scf.if %p3 -> f32 {179 scf.yield %odd : f32180 } else {181 scf.yield %even : f32182 }183 scf.yield %3 : f32184 }185 scf.yield %2 : f32186 }187 scf.yield %1 : f32188 }189 return %0 : f32190}191 192func.func @also_deep_tree(%p0: i1, %p1: i1, %p2: i1, %p3: i1, %even: f32,193 %odd: f32) -> f32 {194 %0 = scf.if %p0 -> f32 {195 %1 = scf.if %p1 -> f32 {196 %2 = scf.if %p2 -> f32 {197 %3 = scf.if %p3 -> f32 {198 scf.yield %even : f32199 } else {200 scf.yield %odd : f32201 }202 scf.yield %3 : f32203 } else {204 %3 = scf.if %p3 -> f32 {205 scf.yield %odd : f32206 } else {207 scf.yield %even : f32208 }209 scf.yield %3 : f32210 }211 scf.yield %2 : f32212 } else {213 %2 = scf.if %p2 -> f32 {214 %3 = scf.if %p3 -> f32 {215 scf.yield %odd : f32216 } else {217 scf.yield %even : f32218 }219 scf.yield %3 : f32220 } else {221 %3 = scf.if %p3 -> f32 {222 scf.yield %even : f32223 } else {224 scf.yield %odd : f32225 }226 scf.yield %3 : f32227 }228 scf.yield %2 : f32229 }230 scf.yield %1 : f32231 } else {232 %1 = scf.if %p1 -> f32 {233 %2 = scf.if %p2 -> f32 {234 %3 = scf.if %p3 -> f32 {235 scf.yield %odd : f32236 } else {237 scf.yield %even : f32238 }239 scf.yield %3 : f32240 } else {241 %3 = scf.if %p3 -> f32 {242 scf.yield %even : f32243 } else {244 scf.yield %odd : f32245 }246 scf.yield %3 : f32247 }248 scf.yield %2 : f32249 } else {250 %2 = scf.if %p2 -> f32 {251 %3 = scf.if %p3 -> f32 {252 scf.yield %even : f32253 } else {254 scf.yield %odd : f32255 }256 scf.yield %3 : f32257 } else {258 %3 = scf.if %p3 -> f32 {259 scf.yield %odd : f32260 } else {261 scf.yield %even : f32262 }263 scf.yield %3 : f32264 }265 scf.yield %2 : f32266 }267 scf.yield %1 : f32268 }269 return %0 : f32270}271 272func.func @reverse_deep_tree(%p0: i1, %p1: i1, %p2: i1, %p3: i1, %even: f32,273 %odd: f32) -> f32 {274 %0 = scf.if %p0 -> f32 {275 %1 = scf.if %p1 -> f32 {276 %2 = scf.if %p2 -> f32 {277 %3 = scf.if %p3 -> f32 {278 scf.yield %odd : f32279 } else {280 scf.yield %even : f32281 }282 scf.yield %3 : f32283 } else {284 %3 = scf.if %p3 -> f32 {285 scf.yield %even : f32286 } else {287 scf.yield %odd : f32288 }289 scf.yield %3 : f32290 }291 scf.yield %2 : f32292 } else {293 %2 = scf.if %p2 -> f32 {294 %3 = scf.if %p3 -> f32 {295 scf.yield %even : f32296 } else {297 scf.yield %odd : f32298 }299 scf.yield %3 : f32300 } else {301 %3 = scf.if %p3 -> f32 {302 scf.yield %odd : f32303 } else {304 scf.yield %even : f32305 }306 scf.yield %3 : f32307 }308 scf.yield %2 : f32309 }310 scf.yield %1 : f32311 } else {312 %1 = scf.if %p1 -> f32 {313 %2 = scf.if %p2 -> f32 {314 %3 = scf.if %p3 -> f32 {315 scf.yield %even : f32316 } else {317 scf.yield %odd : f32318 }319 scf.yield %3 : f32320 } else {321 %3 = scf.if %p3 -> f32 {322 scf.yield %odd : f32323 } else {324 scf.yield %even : f32325 }326 scf.yield %3 : f32327 }328 scf.yield %2 : f32329 } else {330 %2 = scf.if %p2 -> f32 {331 %3 = scf.if %p3 -> f32 {332 scf.yield %odd : f32333 } else {334 scf.yield %even : f32335 }336 scf.yield %3 : f32337 } else {338 %3 = scf.if %p3 -> f32 {339 scf.yield %even : f32340 } else {341 scf.yield %odd : f32342 }343 scf.yield %3 : f32344 }345 scf.yield %2 : f32346 }347 scf.yield %1 : f32348 }349 return %0 : f32350}351 352func.func @user(%p0: i1, %p1: i1, %p2: i1, %p3: i1, %odd: f32, %even: f32)353 -> (f32, f32, f32) {354 %0 = call @deep_tree(%p0, %p1, %p2, %p3, %odd, %even)355 : (i1, i1, i1, i1, f32, f32) -> f32356 %1 = call @also_deep_tree(%p0, %p1, %p2, %p3, %odd, %even)357 : (i1, i1, i1, i1, f32, f32) -> f32358 %2 = call @reverse_deep_tree(%p0, %p1, %p2, %p3, %odd, %even)359 : (i1, i1, i1, i1, f32, f32) -> f32360 return %0, %1, %2 : f32, f32, f32361}362 363// CHECK: @deep_tree364// CHECK-NOT: @also_deep_tree365// CHECK: @reverse_deep_tree366// CHECK: @user367// CHECK-2: call @deep_tree368// CHECK: call @reverse_deep_tree369 370// -----371 372func.func private @func_declaration(i32, i32) -> i32373func.func private @func_declaration1(i32, i32) -> i32374 375func.func @user(%arg0: i32, %arg1: i32) -> (i32, i32) {376 %0 = call @func_declaration(%arg0, %arg1) : (i32, i32) -> i32377 %1 = call @func_declaration1(%arg0, %arg1) : (i32, i32) -> i32378 return %0, %1 : i32, i32379}380 381// CHECK: @func_declaration382// CHECK: @func_declaration1383// CHECK: @user384// CHECK: call @func_declaration385// CHECK: call @func_declaration1386 387// -----388 389func.func @identity(%arg0: tensor<f32>) -> tensor<f32> {390 return %arg0 : tensor<f32>391}392 393func.func @also_identity(%arg0: tensor<f32>) -> tensor<f32> {394 return %arg0 : tensor<f32>395}396 397func.func @yet_another_identity(%arg0: tensor<f32>) -> tensor<f32> {398 return %arg0 : tensor<f32>399}400 401func.func @user(%arg0: tensor<f32>) -> tensor<f32> {402 %f = constant @identity : (tensor<f32>) -> tensor<f32>403 %0 = call_indirect %f(%arg0) : (tensor<f32>) -> tensor<f32>404 %f_0 = constant @also_identity : (tensor<f32>) -> tensor<f32>405 %1 = call_indirect %f_0(%0) : (tensor<f32>) -> tensor<f32>406 %2 = call @yet_another_identity(%1) : (tensor<f32>) -> tensor<f32>407 return %2 : tensor<f32>408}409 410// CHECK: @identity411// CHECK-NOT: @also_identity412// CHECK-NOT: @yet_another_identity413// CHECK: @user414// CHECK-2: constant @identity415// CHECK: call @identity416