1 // RUN: mlir-opt -test-dead-code-analysis 2>&1 %s | FileCheck %s
7 // CHECK: from ^bb1 = live
8 // CHECK: from ^bb0 = live
10 // CHECK: from ^bb1 = live
11 func.func @test_cfg(%cond: i1) -> ()
12 attributes {tag = "test_cfg"} {
16 cf.cond_br %cond, ^bb1, ^bb2
22 func.func @test_region_control_flow(%cond: i1, %arg0: i64, %arg1: i64) -> () {
25 // CHECK: region_preds: (all) predecessors:
28 // CHECK: region_preds: (all) predecessors:
30 // CHECK: op_preds: (all) predecessors:
31 // CHECK: scf.yield {then}
32 // CHECK: scf.yield {else}
41 // region_preds: (all) predecessors:
45 // region_preds: (all) predecessors:
47 // op_preds: (all) predecessors:
49 %c2_i64 = arith.constant 2 : i64
50 %0:2 = scf.while (%arg2 = %arg0) : (i64) -> (i64, i64) {
51 %1 = arith.cmpi slt, %arg2, %arg1 : i64
52 scf.condition(%1) %arg2, %arg2 : i64, i64
54 ^bb0(%arg2: i64, %arg3: i64):
55 %1 = arith.muli %arg3, %c2_i64 : i64
57 } attributes {tag = "test_while"}
65 // CHECK: op_preds: (all) predecessors:
66 // CHECK: func.call @foo(%{{.*}}) {tag = "a"}
67 // CHECK: func.call @foo(%{{.*}}) {tag = "b"}
68 func.func private @foo(%arg0: i32) -> i32
69 attributes {tag = "foo"} {
70 return {a} %arg0 : i32
76 // CHECK: op_preds: predecessors:
77 // CHECK: func.call @bar(%{{.*}}) {tag = "c"}
78 func.func @bar(%cond: i1) -> i32
79 attributes {tag = "bar"} {
80 cf.cond_br %cond, ^bb1, ^bb2
83 %c0 = arith.constant 0 : i32
87 %c1 = arith.constant 1 : i32
92 // CHECK: op_preds: (all) predecessors:
93 func.func private @baz(i32) -> i32 attributes {tag = "baz"}
95 func.func @test_callgraph(%cond: i1, %arg0: i32) -> i32 {
97 // CHECK: op_preds: (all) predecessors:
98 // CHECK: func.return {a}
99 %0 = func.call @foo(%arg0) {tag = "a"} : (i32) -> i32
100 cf.cond_br %cond, ^bb1, ^bb2
104 // CHECK: op_preds: (all) predecessors:
105 // CHECK: func.return {a}
106 %1 = func.call @foo(%arg0) {tag = "b"} : (i32) -> i32
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) -> i32
116 // CHECK: op_preds: predecessors:
117 %3 = func.call @baz(%arg0) {tag = "d"} : (i32) -> i32
121 func.func private @bax(%arg0: i32) {
125 func.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) -> ()
133 // CHECK: test_unknown_branch:
135 // CHECK: ^bb0 = live
136 // CHECK: ^bb1 = live
137 // CHECK: from ^bb0 = live
138 // CHECK: ^bb2 = live
139 // CHECK: from ^bb0 = live
140 func.func @test_unknown_branch() -> ()
141 attributes {tag = "test_unknown_branch"} {
142 "test.unknown_br"() [^bb1, ^bb2] : () -> ()
151 // CHECK: test_unknown_region:
153 // CHECK: ^bb0 = live
155 // CHECK: ^bb0 = live
156 func.func @test_unknown_region() -> () {
157 "test.unknown_region_br"() ({
159 "test.unknown_region_end"() : () -> ()
162 "test.unknown_region_end"() : () -> ()
163 }) {tag = "test_unknown_region"} : () -> ()
167 // CHECK: test_known_dead_block:
169 // CHECK: ^bb0 = live
170 // CHECK: ^bb1 = live
171 // CHECK: ^bb2 = dead
172 func.func @test_known_dead_block() -> ()
173 attributes {tag = "test_known_dead_block"} {
174 %true = arith.constant true
175 cf.cond_br %true, ^bb1, ^bb2
184 // CHECK: test_known_dead_edge:
185 // CHECK: ^bb2 = live
186 // CHECK: from ^bb1 = dead
187 // CHECK: from ^bb0 = live
188 func.func @test_known_dead_edge(%arg0: i1) -> ()
189 attributes {tag = "test_known_dead_edge"} {
190 cf.cond_br %arg0, ^bb1, ^bb2
193 %true = arith.constant true
194 cf.cond_br %true, ^bb3, ^bb2
203 func.func @test_known_region_predecessors() -> () {
204 %false = arith.constant false
205 // CHECK: test_known_if:
207 // CHECK: ^bb0 = dead
209 // CHECK: ^bb0 = live
210 // CHECK: region_preds: (all) predecessors:
212 // CHECK: op_preds: (all) predecessors:
213 // CHECK: scf.yield {else}
218 } {tag = "test_known_if"}
224 // CHECK: ^bb0 = live
225 // CHECK: op_preds: predecessors:
226 // CHECK: func.call @callable() {then}
227 func.func @callable() attributes {tag = "callable"} {
231 func.func @test_dead_callsite() -> () {
232 %true = arith.constant true
234 func.call @callable() {then} : () -> ()
237 func.call @callable() {else} : () -> ()
243 func.func private @test_dead_return(%arg0: i32) -> i32 {
244 %true = arith.constant true
245 cf.cond_br %true, ^bb1, ^bb1
248 return {true} %arg0 : i32
251 return {false} %arg0 : i32
254 func.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) -> i32
262 func.func @test_dca_doesnt_crash() -> () {
263 %0 = scf.execute_region -> tensor<5x16xi16> {
269 func.func @test_dca_doesnt_crash_2() -> () attributes {symbol = @notexistant} {