272 lines · plain
1// RUN: mlir-opt -test-dead-code-analysis 2>&1 %s | FileCheck %s2 3// CHECK: test_cfg:4// CHECK: region #05// CHECK: ^bb0 = live6// CHECK: ^bb1 = live7// CHECK: from ^bb1 = live8// CHECK: from ^bb0 = live9// CHECK: ^bb2 = live10// CHECK: from ^bb1 = live11func.func @test_cfg(%cond: i1) -> ()12 attributes {tag = "test_cfg"} {13 cf.br ^bb114 15^bb1:16 cf.cond_br %cond, ^bb1, ^bb217 18^bb2:19 return20}21 22func.func @test_region_control_flow(%cond: i1, %arg0: i64, %arg1: i64) -> () {23 // CHECK: test_if:24 // CHECK: region #025 // CHECK: region_preds: (all) predecessors:26 // CHECK: scf.if27 // CHECK: region #128 // CHECK: region_preds: (all) predecessors:29 // CHECK: scf.if30 // CHECK: op_preds: (all) predecessors:31 // CHECK: scf.yield {then}32 // CHECK: scf.yield {else}33 scf.if %cond {34 scf.yield {then}35 } else {36 scf.yield {else}37 } {tag = "test_if"}38 39 // test_while:40 // region #041 // region_preds: (all) predecessors:42 // scf.while43 // scf.yield44 // region #145 // region_preds: (all) predecessors:46 // scf.condition47 // op_preds: (all) predecessors:48 // scf.condition49 %c2_i64 = arith.constant 2 : i6450 %0:2 = scf.while (%arg2 = %arg0) : (i64) -> (i64, i64) {51 %1 = arith.cmpi slt, %arg2, %arg1 : i6452 scf.condition(%1) %arg2, %arg2 : i64, i6453 } do {54 ^bb0(%arg2: i64, %arg3: i64):55 %1 = arith.muli %arg3, %c2_i64 : i6456 scf.yield %1 : i6457 } attributes {tag = "test_while"}58 59 return60}61 62// CHECK: foo:63// CHECK: region #064// CHECK: ^bb0 = live65// CHECK: op_preds: (all) predecessors:66// CHECK: func.call @foo(%{{.*}}) {tag = "a"}67// CHECK: func.call @foo(%{{.*}}) {tag = "b"}68func.func private @foo(%arg0: i32) -> i3269 attributes {tag = "foo"} {70 return {a} %arg0 : i3271}72 73// CHECK: bar:74// CHECK: region #075// CHECK: ^bb0 = live76// CHECK: op_preds: predecessors:77// CHECK: func.call @bar(%{{.*}}) {tag = "c"}78func.func @bar(%cond: i1) -> i3279 attributes {tag = "bar"} {80 cf.cond_br %cond, ^bb1, ^bb281 82^bb1:83 %c0 = arith.constant 0 : i3284 return {b} %c0 : i3285 86^bb2:87 %c1 = arith.constant 1 : i3288 return {c} %c1 : i3289}90 91// CHECK: baz92// CHECK: op_preds: (all) predecessors:93func.func private @baz(i32) -> i32 attributes {tag = "baz"}94 95func.func @test_callgraph(%cond: i1, %arg0: i32) -> i32 {96 // CHECK: a:97 // CHECK: op_preds: (all) predecessors:98 // CHECK: func.return {a}99 %0 = func.call @foo(%arg0) {tag = "a"} : (i32) -> i32100 cf.cond_br %cond, ^bb1, ^bb2101 102^bb1:103 // CHECK: b:104 // CHECK: op_preds: (all) predecessors:105 // CHECK: func.return {a}106 %1 = func.call @foo(%arg0) {tag = "b"} : (i32) -> i32107 return %1 : i32108 109^bb2:110 // CHECK: c:111 // CHECK: op_preds: (all) predecessors:112 // CHECK: func.return {b}113 // CHECK: func.return {c}114 %2 = func.call @bar(%cond) {tag = "c"} : (i1) -> i32115 // CHECK: d:116 // CHECK: op_preds: predecessors:117 %3 = func.call @baz(%arg0) {tag = "d"} : (i32) -> i32118 return %2 : i32119}120 121func.func private @bax(%arg0: i32) {122 return {void_return}123}124 125func.func @test_callgraph_void_return(%arg0: i32) -> i32 {126 // CHECK: call_void_return:127 // CHECK: op_preds: (all) predecessors:128 // CHECK: func.return {void_return}129 func.call @bax(%arg0) {tag = "call_void_return"}: (i32) -> ()130 return %arg0 : i32131}132 133// CHECK: test_unknown_branch:134// CHECK: region #0135// CHECK: ^bb0 = live136// CHECK: ^bb1 = live137// CHECK: from ^bb0 = live138// CHECK: ^bb2 = live139// CHECK: from ^bb0 = live140func.func @test_unknown_branch() -> ()141 attributes {tag = "test_unknown_branch"} {142 "test.unknown_br"() [^bb1, ^bb2] : () -> ()143 144^bb1:145 return146 147^bb2:148 return149}150 151// CHECK: test_unknown_region:152// CHECK: region #0153// CHECK: ^bb0 = live154// CHECK: region #1155// CHECK: ^bb0 = live156func.func @test_unknown_region() -> () {157 "test.unknown_region_br"() ({158 ^bb0:159 "test.unknown_region_end"() : () -> ()160 }, {161 ^bb0:162 "test.unknown_region_end"() : () -> ()163 }) {tag = "test_unknown_region"} : () -> ()164 return165}166 167// CHECK: test_known_dead_block:168// CHECK: region #0169// CHECK: ^bb0 = live170// CHECK: ^bb1 = live171// CHECK: ^bb2 = dead172func.func @test_known_dead_block() -> ()173 attributes {tag = "test_known_dead_block"} {174 %true = arith.constant true175 cf.cond_br %true, ^bb1, ^bb2176 177^bb1:178 return179 180^bb2:181 return182}183 184// CHECK: test_known_dead_edge:185// CHECK: ^bb2 = live186// CHECK: from ^bb1 = dead187// CHECK: from ^bb0 = live188func.func @test_known_dead_edge(%arg0: i1) -> ()189 attributes {tag = "test_known_dead_edge"} {190 cf.cond_br %arg0, ^bb1, ^bb2191 192^bb1:193 %true = arith.constant true194 cf.cond_br %true, ^bb3, ^bb2195 196^bb2:197 return198 199^bb3:200 return201}202 203func.func @test_known_region_predecessors() -> () {204 %false = arith.constant false205 // CHECK: test_known_if:206 // CHECK: region #0207 // CHECK: ^bb0 = dead208 // CHECK: region #1209 // CHECK: ^bb0 = live210 // CHECK: region_preds: (all) predecessors:211 // CHECK: scf.if212 // CHECK: op_preds: (all) predecessors:213 // CHECK: scf.yield {else}214 scf.if %false {215 scf.yield {then}216 } else {217 scf.yield {else}218 } {tag = "test_known_if"}219 return220}221 222// CHECK: callable:223// CHECK: region #0224// CHECK: ^bb0 = live225// CHECK: op_preds: predecessors:226// CHECK: func.call @callable() {then}227func.func @callable() attributes {tag = "callable"} {228 return229}230 231func.func @test_dead_callsite() -> () {232 %true = arith.constant true233 scf.if %true {234 func.call @callable() {then} : () -> ()235 scf.yield236 } else {237 func.call @callable() {else} : () -> ()238 scf.yield239 }240 return241}242 243func.func private @test_dead_return(%arg0: i32) -> i32 {244 %true = arith.constant true245 cf.cond_br %true, ^bb1, ^bb1246 247^bb1:248 return {true} %arg0 : i32249 250^bb2:251 return {false} %arg0 : i32252}253 254func.func @test_call_dead_return(%arg0: i32) -> () {255 // CHECK: test_dead_return:256 // CHECK: op_preds: (all) predecessors:257 // CHECK: func.return {true}258 %0 = func.call @test_dead_return(%arg0) {tag = "test_dead_return"} : (i32) -> i32259 return260}261 262func.func @test_dca_doesnt_crash() -> () {263 %0 = scf.execute_region -> tensor<5x16xi16> {264 llvm.unreachable265 } 266 return267}268 269func.func @test_dca_doesnt_crash_2() -> () attributes {symbol = @notexistant} {270 return271}272