xref: /llvm-project/mlir/test/Analysis/DataFlow/test-dead-code-analysis.mlir (revision 13317502da8ee3885854f67700140586c0edafee)
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