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