1c095afcbSMogball// RUN: mlir-opt -test-dead-code-analysis 2>&1 %s | FileCheck %s 2c095afcbSMogball 3c095afcbSMogball// CHECK: test_cfg: 4c095afcbSMogball// CHECK: region #0 5c095afcbSMogball// CHECK: ^bb0 = live 6c095afcbSMogball// CHECK: ^bb1 = live 7c095afcbSMogball// CHECK: from ^bb1 = live 8c095afcbSMogball// CHECK: from ^bb0 = live 9c095afcbSMogball// CHECK: ^bb2 = live 10c095afcbSMogball// CHECK: from ^bb1 = live 11c095afcbSMogballfunc.func @test_cfg(%cond: i1) -> () 12c095afcbSMogball attributes {tag = "test_cfg"} { 13c095afcbSMogball cf.br ^bb1 14c095afcbSMogball 15c095afcbSMogball^bb1: 16c095afcbSMogball cf.cond_br %cond, ^bb1, ^bb2 17c095afcbSMogball 18c095afcbSMogball^bb2: 19c095afcbSMogball return 20c095afcbSMogball} 21c095afcbSMogball 22c095afcbSMogballfunc.func @test_region_control_flow(%cond: i1, %arg0: i64, %arg1: i64) -> () { 23c095afcbSMogball // CHECK: test_if: 24c095afcbSMogball // CHECK: region #0 25c095afcbSMogball // CHECK: region_preds: (all) predecessors: 26c095afcbSMogball // CHECK: scf.if 27c095afcbSMogball // CHECK: region #1 28c095afcbSMogball // CHECK: region_preds: (all) predecessors: 29c095afcbSMogball // CHECK: scf.if 30c095afcbSMogball // CHECK: op_preds: (all) predecessors: 31c095afcbSMogball // CHECK: scf.yield {then} 32c095afcbSMogball // CHECK: scf.yield {else} 33c095afcbSMogball scf.if %cond { 34c095afcbSMogball scf.yield {then} 35c095afcbSMogball } else { 36c095afcbSMogball scf.yield {else} 37c095afcbSMogball } {tag = "test_if"} 38c095afcbSMogball 39c095afcbSMogball // test_while: 40c095afcbSMogball // region #0 41c095afcbSMogball // region_preds: (all) predecessors: 42c095afcbSMogball // scf.while 43c095afcbSMogball // scf.yield 44c095afcbSMogball // region #1 45c095afcbSMogball // region_preds: (all) predecessors: 46c095afcbSMogball // scf.condition 47c095afcbSMogball // op_preds: (all) predecessors: 48c095afcbSMogball // scf.condition 49c095afcbSMogball %c2_i64 = arith.constant 2 : i64 50c095afcbSMogball %0:2 = scf.while (%arg2 = %arg0) : (i64) -> (i64, i64) { 51c095afcbSMogball %1 = arith.cmpi slt, %arg2, %arg1 : i64 52c095afcbSMogball scf.condition(%1) %arg2, %arg2 : i64, i64 53c095afcbSMogball } do { 54c095afcbSMogball ^bb0(%arg2: i64, %arg3: i64): 55c095afcbSMogball %1 = arith.muli %arg3, %c2_i64 : i64 56c095afcbSMogball scf.yield %1 : i64 57c095afcbSMogball } attributes {tag = "test_while"} 58c095afcbSMogball 59c095afcbSMogball return 60c095afcbSMogball} 61c095afcbSMogball 62c095afcbSMogball// CHECK: foo: 63c095afcbSMogball// CHECK: region #0 64c095afcbSMogball// CHECK: ^bb0 = live 65c095afcbSMogball// CHECK: op_preds: (all) predecessors: 66c095afcbSMogball// CHECK: func.call @foo(%{{.*}}) {tag = "a"} 67c095afcbSMogball// CHECK: func.call @foo(%{{.*}}) {tag = "b"} 68c095afcbSMogballfunc.func private @foo(%arg0: i32) -> i32 69c095afcbSMogball attributes {tag = "foo"} { 70c095afcbSMogball return {a} %arg0 : i32 71c095afcbSMogball} 72c095afcbSMogball 73c095afcbSMogball// CHECK: bar: 74c095afcbSMogball// CHECK: region #0 75c095afcbSMogball// CHECK: ^bb0 = live 76c095afcbSMogball// CHECK: op_preds: predecessors: 77c095afcbSMogball// CHECK: func.call @bar(%{{.*}}) {tag = "c"} 78c095afcbSMogballfunc.func @bar(%cond: i1) -> i32 79c095afcbSMogball attributes {tag = "bar"} { 80c095afcbSMogball cf.cond_br %cond, ^bb1, ^bb2 81c095afcbSMogball 82c095afcbSMogball^bb1: 83c095afcbSMogball %c0 = arith.constant 0 : i32 84c095afcbSMogball return {b} %c0 : i32 85c095afcbSMogball 86c095afcbSMogball^bb2: 87c095afcbSMogball %c1 = arith.constant 1 : i32 88c095afcbSMogball return {c} %c1 : i32 89c095afcbSMogball} 90c095afcbSMogball 91c095afcbSMogball// CHECK: baz 92c095afcbSMogball// CHECK: op_preds: (all) predecessors: 93c095afcbSMogballfunc.func private @baz(i32) -> i32 attributes {tag = "baz"} 94c095afcbSMogball 95c095afcbSMogballfunc.func @test_callgraph(%cond: i1, %arg0: i32) -> i32 { 96c095afcbSMogball // CHECK: a: 97c095afcbSMogball // CHECK: op_preds: (all) predecessors: 98c095afcbSMogball // CHECK: func.return {a} 99c095afcbSMogball %0 = func.call @foo(%arg0) {tag = "a"} : (i32) -> i32 100c095afcbSMogball cf.cond_br %cond, ^bb1, ^bb2 101c095afcbSMogball 102c095afcbSMogball^bb1: 103c095afcbSMogball // CHECK: b: 104c095afcbSMogball // CHECK: op_preds: (all) predecessors: 105c095afcbSMogball // CHECK: func.return {a} 106c095afcbSMogball %1 = func.call @foo(%arg0) {tag = "b"} : (i32) -> i32 107c095afcbSMogball return %1 : i32 108c095afcbSMogball 109c095afcbSMogball^bb2: 110c095afcbSMogball // CHECK: c: 111c095afcbSMogball // CHECK: op_preds: (all) predecessors: 112c095afcbSMogball // CHECK: func.return {b} 113c095afcbSMogball // CHECK: func.return {c} 114c095afcbSMogball %2 = func.call @bar(%cond) {tag = "c"} : (i1) -> i32 115c095afcbSMogball // CHECK: d: 116c095afcbSMogball // CHECK: op_preds: predecessors: 117c095afcbSMogball %3 = func.call @baz(%arg0) {tag = "d"} : (i32) -> i32 118c095afcbSMogball return %2 : i32 119c095afcbSMogball} 120c095afcbSMogball 1214732b0cbSJacob Mai Pengfunc.func private @bax(%arg0: i32) { 1224732b0cbSJacob Mai Peng return {void_return} 1234732b0cbSJacob Mai Peng} 1244732b0cbSJacob Mai Peng 1254732b0cbSJacob Mai Pengfunc.func @test_callgraph_void_return(%arg0: i32) -> i32 { 1264732b0cbSJacob Mai Peng // CHECK: call_void_return: 1274732b0cbSJacob Mai Peng // CHECK: op_preds: (all) predecessors: 1284732b0cbSJacob Mai Peng // CHECK: func.return {void_return} 1294732b0cbSJacob Mai Peng func.call @bax(%arg0) {tag = "call_void_return"}: (i32) -> () 1304732b0cbSJacob Mai Peng return %arg0 : i32 1314732b0cbSJacob Mai Peng} 1324732b0cbSJacob Mai Peng 133c095afcbSMogball// CHECK: test_unknown_branch: 134c095afcbSMogball// CHECK: region #0 135c095afcbSMogball// CHECK: ^bb0 = live 136c095afcbSMogball// CHECK: ^bb1 = live 137c095afcbSMogball// CHECK: from ^bb0 = live 138c095afcbSMogball// CHECK: ^bb2 = live 139c095afcbSMogball// CHECK: from ^bb0 = live 140c095afcbSMogballfunc.func @test_unknown_branch() -> () 141c095afcbSMogball attributes {tag = "test_unknown_branch"} { 142c095afcbSMogball "test.unknown_br"() [^bb1, ^bb2] : () -> () 143c095afcbSMogball 144c095afcbSMogball^bb1: 145c095afcbSMogball return 146c095afcbSMogball 147c095afcbSMogball^bb2: 148c095afcbSMogball return 149c095afcbSMogball} 150c095afcbSMogball 151c095afcbSMogball// CHECK: test_unknown_region: 152c095afcbSMogball// CHECK: region #0 153c095afcbSMogball// CHECK: ^bb0 = live 154c095afcbSMogball// CHECK: region #1 155c095afcbSMogball// CHECK: ^bb0 = live 156c095afcbSMogballfunc.func @test_unknown_region() -> () { 157c095afcbSMogball "test.unknown_region_br"() ({ 158c095afcbSMogball ^bb0: 159c095afcbSMogball "test.unknown_region_end"() : () -> () 160c095afcbSMogball }, { 161c095afcbSMogball ^bb0: 162c095afcbSMogball "test.unknown_region_end"() : () -> () 163c095afcbSMogball }) {tag = "test_unknown_region"} : () -> () 164c095afcbSMogball return 165c095afcbSMogball} 166c095afcbSMogball 167c095afcbSMogball// CHECK: test_known_dead_block: 168c095afcbSMogball// CHECK: region #0 169c095afcbSMogball// CHECK: ^bb0 = live 170c095afcbSMogball// CHECK: ^bb1 = live 171c095afcbSMogball// CHECK: ^bb2 = dead 172c095afcbSMogballfunc.func @test_known_dead_block() -> () 173c095afcbSMogball attributes {tag = "test_known_dead_block"} { 174c095afcbSMogball %true = arith.constant true 175c095afcbSMogball cf.cond_br %true, ^bb1, ^bb2 176c095afcbSMogball 177c095afcbSMogball^bb1: 178c095afcbSMogball return 179c095afcbSMogball 180c095afcbSMogball^bb2: 181c095afcbSMogball return 182c095afcbSMogball} 183c095afcbSMogball 184c095afcbSMogball// CHECK: test_known_dead_edge: 185c095afcbSMogball// CHECK: ^bb2 = live 186c095afcbSMogball// CHECK: from ^bb1 = dead 187c095afcbSMogball// CHECK: from ^bb0 = live 188c095afcbSMogballfunc.func @test_known_dead_edge(%arg0: i1) -> () 189c095afcbSMogball attributes {tag = "test_known_dead_edge"} { 190c095afcbSMogball cf.cond_br %arg0, ^bb1, ^bb2 191c095afcbSMogball 192c095afcbSMogball^bb1: 193c095afcbSMogball %true = arith.constant true 194c095afcbSMogball cf.cond_br %true, ^bb3, ^bb2 195c095afcbSMogball 196c095afcbSMogball^bb2: 197c095afcbSMogball return 198c095afcbSMogball 199c095afcbSMogball^bb3: 200c095afcbSMogball return 201c095afcbSMogball} 202c095afcbSMogball 203c095afcbSMogballfunc.func @test_known_region_predecessors() -> () { 204c095afcbSMogball %false = arith.constant false 205c095afcbSMogball // CHECK: test_known_if: 206c095afcbSMogball // CHECK: region #0 207c095afcbSMogball // CHECK: ^bb0 = dead 208c095afcbSMogball // CHECK: region #1 209c095afcbSMogball // CHECK: ^bb0 = live 210c095afcbSMogball // CHECK: region_preds: (all) predecessors: 211c095afcbSMogball // CHECK: scf.if 212c095afcbSMogball // CHECK: op_preds: (all) predecessors: 213c095afcbSMogball // CHECK: scf.yield {else} 214c095afcbSMogball scf.if %false { 215c095afcbSMogball scf.yield {then} 216c095afcbSMogball } else { 217c095afcbSMogball scf.yield {else} 218c095afcbSMogball } {tag = "test_known_if"} 219c095afcbSMogball return 220c095afcbSMogball} 221c095afcbSMogball 222c095afcbSMogball// CHECK: callable: 223c095afcbSMogball// CHECK: region #0 224c095afcbSMogball// CHECK: ^bb0 = live 225c095afcbSMogball// CHECK: op_preds: predecessors: 226c095afcbSMogball// CHECK: func.call @callable() {then} 227c095afcbSMogballfunc.func @callable() attributes {tag = "callable"} { 228c095afcbSMogball return 229c095afcbSMogball} 230c095afcbSMogball 231c095afcbSMogballfunc.func @test_dead_callsite() -> () { 232c095afcbSMogball %true = arith.constant true 233c095afcbSMogball scf.if %true { 234c095afcbSMogball func.call @callable() {then} : () -> () 235c095afcbSMogball scf.yield 236c095afcbSMogball } else { 237c095afcbSMogball func.call @callable() {else} : () -> () 238c095afcbSMogball scf.yield 239c095afcbSMogball } 240c095afcbSMogball return 241c095afcbSMogball} 242c095afcbSMogball 243c095afcbSMogballfunc.func private @test_dead_return(%arg0: i32) -> i32 { 244c095afcbSMogball %true = arith.constant true 245c095afcbSMogball cf.cond_br %true, ^bb1, ^bb1 246c095afcbSMogball 247c095afcbSMogball^bb1: 248c095afcbSMogball return {true} %arg0 : i32 249c095afcbSMogball 250c095afcbSMogball^bb2: 251c095afcbSMogball return {false} %arg0 : i32 252c095afcbSMogball} 253c095afcbSMogball 254c095afcbSMogballfunc.func @test_call_dead_return(%arg0: i32) -> () { 255c095afcbSMogball // CHECK: test_dead_return: 256c095afcbSMogball // CHECK: op_preds: (all) predecessors: 257c095afcbSMogball // CHECK: func.return {true} 258c095afcbSMogball %0 = func.call @test_dead_return(%arg0) {tag = "test_dead_return"} : (i32) -> i32 259c095afcbSMogball return 260c095afcbSMogball} 2616833a380SJustin Fargnoli 2626833a380SJustin Fargnolifunc.func @test_dca_doesnt_crash() -> () { 2636833a380SJustin Fargnoli %0 = scf.execute_region -> tensor<5x16xi16> { 2646833a380SJustin Fargnoli llvm.unreachable 2656833a380SJustin Fargnoli } 2666833a380SJustin Fargnoli return 2676833a380SJustin Fargnoli} 268*13317502SShlomi Regev 269*13317502SShlomi Regevfunc.func @test_dca_doesnt_crash_2() -> () attributes {symbol = @notexistant} { 270*13317502SShlomi Regev return 271*13317502SShlomi Regev} 272