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 datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
10  target triple = "wasm32-unknown-unknown"
11
12  define void @test0() {
13  pred0:
14    ret void
15  pred1:
16    ret void
17  entry0:
18    ret void
19  entry1:
20    ret void
21  }
22...
23
24---
25# CHECK-LABEL: test0
26name: test0
27liveins:
28  - { reg: '$arguments' }
29body: |
30  bb.0.pred0:
31    successors: %bb.1, %bb.2
32    liveins: $arguments
33    %0:i32 = CONST_I32 100, implicit-def $arguments
34    BR_IF %bb.2, %0:i32, implicit-def $arguments
35  ; CHECK: bb.0.pred0:
36    ; CHECK: BR_IF %bb.2, %0, implicit-def $arguments
37
38  bb.1.pred1:
39  ; predecessors: %bb.1
40    successors: %bb.2, %bb.3
41    BR_IF %bb.3, %0:i32, implicit-def $arguments
42  ; CHECK: bb.1.pred1:
43    ; CHECK: BR_IF %bb.7, %0, implicit-def $arguments
44    ; This falls through to bb.2, so we don't need an additional BR here
45    ; CHECK-NOT: BR
46
47  ; Routing block for entry0, when predecessor is outside the loop
48  ; This routing block is shared between the two predecessors: pred0 and pred1.
49  ; CHECK: bb.2:
50    ; CHECK: %1:i32 = CONST_I32 0, implicit-def $arguments
51    ; CHECK: BR %bb.6, implicit-def $arguments
52
53  bb.2.entry0:
54  ; predecessors: %bb.0, %bb.1, %bb.1
55    successors: %bb.3
56    BR %bb.3, implicit-def $arguments
57  ; CHECK: bb.3.entry0:
58    ; CHECK: BR %bb.4, implicit-def $arguments
59
60  ; Routing block for entry1, when predecessor is inside the loop
61  ; CHECK: bb.4:
62    ; CHECK: %1:i32 = CONST_I32 1, implicit-def $arguments
63    ; CHECK: BR %bb.6, implicit-def $arguments
64
65  bb.3.entry1:
66  ; predecessors: %bb.1, %bb.2
67    successors: %bb.2
68    BR %bb.2, implicit-def $arguments
69  ; CHECK: bb.5.entry1:
70    ; CHECK: BR %bb.8, implicit-def $arguments
71
72  ; Dispatch block
73  ; CHECK: bb.6:
74    ; CHECK: BR_TABLE_I32 %1, %bb.3, %bb.5, %bb.5, implicit-def $arguments
75
76  ; Routing block for entry1, when predecessor is outside the loop
77  ; CHECK: bb.7:
78    ; CHECK: %1:i32 = CONST_I32 1, implicit-def $arguments
79    ; CHECK: BR %bb.6, implicit-def $arguments
80
81  ; Routing block for entry0, when predecessor is inside the loop
82  ; CHECK: bb.8:
83    ; CHECK: %1:i32 = CONST_I32 0, implicit-def $arguments
84    ; CHECK: BR %bb.6, implicit-def $arguments
85