190 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -pass-pipeline='builtin.module(func.func(canonicalize{region-simplify=aggressive}))' | FileCheck %s2 3// Test case: Simple case of deleting a dead pure op.4 5// CHECK: func @f(%arg0: f32) {6// CHECK-NEXT: return7 8func.func @f(%arg0: f32) {9 %0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f3210 return11}12 13// -----14 15// Test case: Simple case of deleting a block argument.16 17// CHECK: func @f(%arg0: f32)18// CHECK-NEXT: "test.br"()[^bb1]19// CHECK-NEXT: ^bb1:20// CHECK-NEXT: return21 22func.func @f(%arg0: f32) {23 "test.br"(%arg0)[^succ] : (f32) -> ()24^succ(%0: f32):25 return26}27 28// -----29 30// Test case: Deleting recursively dead block arguments.31 32// CHECK: func @f(%arg0: f32)33// CHECK-NEXT: cf.br ^bb134// CHECK-NEXT: ^bb1:35// CHECK-NEXT: cf.br ^bb136 37 38func.func @f(%arg0: f32) {39 cf.br ^loop(%arg0: f32)40^loop(%loop: f32):41 cf.br ^loop(%loop: f32)42}43 44// -----45 46// Test case: Deleting recursively dead block arguments with pure ops in between.47 48// CHECK: func @f(%arg0: f32)49// CHECK-NEXT: cf.br ^bb150// CHECK-NEXT: ^bb1:51// CHECK-NEXT: cf.br ^bb152 53func.func @f(%arg0: f32) {54 cf.br ^loop(%arg0: f32)55^loop(%0: f32):56 %1 = "math.exp"(%0) : (f32) -> f3257 cf.br ^loop(%1: f32)58}59 60// -----61 62// Test case: Delete block arguments for cf.cond_br.63 64// CHECK: func @f(%arg0: f32, %arg1: i1)65// CHECK-NEXT: return66 67func.func @f(%arg0: f32, %pred: i1) {68 %exp = "math.exp"(%arg0) : (f32) -> f3269 cf.cond_br %pred, ^true(%exp: f32), ^false(%exp: f32)70^true(%0: f32):71 return72^false(%1: f32):73 return74}75 76// -----77 78// Test case: Recursively DCE into enclosed regions.79 80// CHECK: func.func @f(%arg0: f32)81// CHECK-NOT: arith.addf82 83func.func @f(%arg0: f32) {84 "test.region"() (85 {86 %0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f3287 }88 ) : () -> ()89 return90}91 92// -----93 94// Test case: Don't delete pure ops that feed into returns.95 96// CHECK: func @f(%arg0: f32) -> f3297// CHECK-NEXT: [[VAL0:%.+]] = arith.addf %arg0, %arg0 : f3298// CHECK-NEXT: return [[VAL0]] : f3299 100func.func @f(%arg0: f32) -> f32 {101 %0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f32102 return %0 : f32103}104 105// -----106 107// Test case: Don't delete potentially side-effecting ops.108 109// CHECK: func @f(%arg0: f32)110// CHECK-NEXT: "foo.print"(%arg0) : (f32) -> ()111// CHECK-NEXT: return112 113func.func @f(%arg0: f32) {114 "foo.print"(%arg0) : (f32) -> ()115 return116}117 118// -----119 120// Test case: Uses in nested regions are deleted correctly.121 122// CHECK: func @f(%arg0: f32)123// CHECK-NEXT: "foo.has_region"124// CHECK-NEXT: "foo.return"125 126func.func @f(%arg0: f32) {127 %0 = "math.exp"(%arg0) : (f32) -> f32128 "foo.has_region"() ({129 %1 = "math.exp"(%0) : (f32) -> f32130 "foo.return"() : () -> ()131 }) : () -> ()132 return133}134 135// -----136 137// Test case: Test the mechanics of deleting multiple block arguments.138 139// CHECK: func @f(%arg0: tensor<1xf32>, %arg1: tensor<2xf32>, %arg2: tensor<3xf32>, %arg3: tensor<4xf32>, %arg4: tensor<5xf32>)140// CHECK-NEXT: "test.br"()[^bb1]141// CHECK-NEXT: ^bb1:142// CHECK-NEXT: "foo.print"(%arg1)143// CHECK-NEXT: "foo.print"(%arg3)144// CHECK-NEXT: return145 146 147func.func @f(148 %arg0: tensor<1xf32>,149 %arg1: tensor<2xf32>,150 %arg2: tensor<3xf32>,151 %arg3: tensor<4xf32>,152 %arg4: tensor<5xf32>) {153 "test.br"(%arg0, %arg1, %arg2, %arg3, %arg4)[^succ] : (tensor<1xf32>, tensor<2xf32>, tensor<3xf32>, tensor<4xf32>, tensor<5xf32>) -> ()154^succ(%t1: tensor<1xf32>, %t2: tensor<2xf32>, %t3: tensor<3xf32>, %t4: tensor<4xf32>, %t5: tensor<5xf32>):155 "foo.print"(%t2) : (tensor<2xf32>) -> ()156 "foo.print"(%t4) : (tensor<4xf32>) -> ()157 return158}159 160// -----161 162// Test case: Test values with use-def cycles are deleted properly.163 164// CHECK: func @f()165// CHECK-NEXT: test.graph_region166// CHECK-NEXT: "test.terminator"() : () -> ()167 168func.func @f() {169 test.graph_region {170 %0 = "math.exp"(%1) : (f32) -> f32171 %1 = "math.exp"(%0) : (f32) -> f32172 "test.terminator"() : ()->()173 }174 return175}176 177// -----178 179 180// Test case: Delete ops that only have side-effects on an allocated result.181 182// CHECK: func @f()183// CHECK-NOT: test_effects_result184// CHECK-NEXT: return185 186func.func @f() {187 %0 = "test.test_effects_result"() : () -> i32188 return189}190