xref: /llvm-project/llvm/test/CodeGen/WebAssembly/irreducible-cfg.mir (revision cde083e010952722babb3e08b457e473e86f412d)
1# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-fix-irreducible-control-flow %s -o - | FileCheck %s
2
3# This tests if we correctly create at most 2 routing blocks per entry block,
4# and also whether those routing blocks are generated in the correct place. If
5# one of the predecessor is the layout predecessor of an entry, a routing block
6# for the entry should be generated right after the layout predecessor.
7
8--- |
9  target triple = "wasm32-unknown-unknown"
10
11  define void @test0() {
12  pred0:
13    ret void
14  pred1:
15    ret void
16  entry0:
17    ret void
18  entry1:
19    ret void
20  }
21...
22
23---
24# CHECK-LABEL: test0
25name: test0
26liveins:
27  - { reg: '$arguments' }
28body: |
29  bb.0.pred0:
30    successors: %bb.1, %bb.2
31    liveins: $arguments
32    %0:i32 = CONST_I32 100, implicit-def $arguments
33    BR_IF %bb.2, %0:i32, implicit-def $arguments
34  ; CHECK: bb.0.pred0:
35    ; CHECK:      %1:i32 = IMPLICIT_DEF
36    ; CHECK-NEXT: %0:i32 = IMPLICIT_DEF
37    ; CHECK:      BR_IF %bb.2, %0, implicit-def $arguments
38
39  bb.1.pred1:
40  ; predecessors: %bb.1
41    successors: %bb.2, %bb.3
42    BR_IF %bb.3, %0:i32, implicit-def $arguments
43  ; CHECK: bb.1.pred1:
44    ; CHECK:      BR_IF %bb.7, %0, implicit-def $arguments
45    ; This falls through to bb.2, so we don't need an additional BR here
46    ; CHECK-NOT:  BR
47
48  ; Routing block for entry0, when predecessor is outside the loop
49  ; This routing block is shared between the two predecessors: pred0 and pred1.
50  ; CHECK: bb.2:
51    ; CHECK:      %1:i32 = CONST_I32 0, implicit-def $arguments
52    ; CHECK-NEXT: BR %bb.6, implicit-def $arguments
53
54  bb.2.entry0:
55  ; predecessors: %bb.0, %bb.1, %bb.1
56    successors: %bb.3
57    BR %bb.3, implicit-def $arguments
58  ; CHECK: bb.3.entry0:
59    ; CHECK:      BR %bb.4, implicit-def $arguments
60
61  ; Routing block for entry1, when predecessor is inside the loop
62  ; CHECK: bb.4:
63    ; CHECK:      %1:i32 = CONST_I32 1, implicit-def $arguments
64    ; CHECK-NEXT: BR %bb.6, implicit-def $arguments
65
66  bb.3.entry1:
67  ; predecessors: %bb.1, %bb.2
68    successors: %bb.2
69    BR %bb.2, implicit-def $arguments
70  ; CHECK: bb.5.entry1:
71    ; CHECK:      BR %bb.8, implicit-def $arguments
72
73  ; Dispatch block
74  ; CHECK: bb.6:
75    ; CHECK:      BR_TABLE_I32 %1, %bb.3, %bb.5, %bb.5, implicit-def $arguments
76
77  ; Routing block for entry1, when predecessor is outside the loop
78  ; CHECK: bb.7:
79    ; CHECK:      %1:i32 = CONST_I32 1, implicit-def $arguments
80    ; CHECK-NEXT: BR %bb.6, implicit-def $arguments
81
82  ; Routing block for entry0, when predecessor is inside the loop
83  ; CHECK: bb.8:
84    ; CHECK:      %1:i32 = CONST_I32 0, implicit-def $arguments
85    ; CHECK-NEXT: BR %bb.6, implicit-def $arguments
86