1; RUN: llc < %s -asm-verbose=false | FileCheck %s 2 3; Test the CFG stackifier pass. 4 5target datalayout = "e-p:32:32-i64:64-n32:64-S128" 6target triple = "wasm32-unknown-unknown" 7 8declare void @something() 9 10; Test that loops are made contiguous, even in the presence of split backedges. 11 12; CHECK-LABEL: test0: 13; CHECK: loop 14; CHECK: i32.add 15; CHECK: br_if 16; CHECK: call 17; CHECK: br BB0_1{{$}} 18; CHECK: return{{$}} 19define void @test0(i32 %n) { 20entry: 21 br label %header 22 23header: 24 %i = phi i32 [ 0, %entry ], [ %i.next, %back ] 25 %i.next = add i32 %i, 1 26 27 %c = icmp slt i32 %i.next, %n 28 br i1 %c, label %back, label %exit 29 30exit: 31 ret void 32 33back: 34 call void @something() 35 br label %header 36} 37 38; Same as test0, but the branch condition is reversed. 39 40; CHECK-LABEL: test1: 41; CHECK: loop 42; CHECK: i32.add 43; CHECK: br_if 44; CHECK: call 45; CHECK: br BB1_1{{$}} 46; CHECK: return{{$}} 47define void @test1(i32 %n) { 48entry: 49 br label %header 50 51header: 52 %i = phi i32 [ 0, %entry ], [ %i.next, %back ] 53 %i.next = add i32 %i, 1 54 55 %c = icmp sge i32 %i.next, %n 56 br i1 %c, label %exit, label %back 57 58exit: 59 ret void 60 61back: 62 call void @something() 63 br label %header 64} 65 66; Test that a simple loop is handled as expected. 67 68; CHECK-LABEL: test2: 69; CHECK: block BB2_2{{$}} 70; CHECK: br_if {{.*}}, BB2_2{{$}} 71; CHECK: BB2_1: 72; CHECK: br_if $pop{{[0-9]+}}, BB2_1{{$}} 73; CHECK: BB2_2: 74; CHECK: return{{$}} 75define void @test2(double* nocapture %p, i32 %n) { 76entry: 77 %cmp.4 = icmp sgt i32 %n, 0 78 br i1 %cmp.4, label %for.body.preheader, label %for.end 79 80for.body.preheader: 81 br label %for.body 82 83for.body: 84 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] 85 %arrayidx = getelementptr inbounds double, double* %p, i32 %i.05 86 %0 = load double, double* %arrayidx, align 8 87 %mul = fmul double %0, 3.200000e+00 88 store double %mul, double* %arrayidx, align 8 89 %inc = add nuw nsw i32 %i.05, 1 90 %exitcond = icmp eq i32 %inc, %n 91 br i1 %exitcond, label %for.end.loopexit, label %for.body 92 93for.end.loopexit: 94 br label %for.end 95 96for.end: 97 ret void 98} 99 100; CHECK-LABEL: doublediamond: 101; CHECK: block BB3_5{{$}} 102; CHECK: block BB3_2{{$}} 103; CHECK: br_if $pop{{[0-9]+}}, BB3_2{{$}} 104; CHECK: block BB3_4{{$}} 105; CHECK: br_if $pop{{[0-9]+}}, BB3_4{{$}} 106; CHECK: br BB3_5{{$}} 107; CHECK: BB3_4: 108; CHECK: BB3_5: 109; CHECK: return ${{[0-9]+}}{{$}} 110define i32 @doublediamond(i32 %a, i32 %b, i32* %p) { 111entry: 112 %c = icmp eq i32 %a, 0 113 %d = icmp eq i32 %b, 0 114 store volatile i32 0, i32* %p 115 br i1 %c, label %true, label %false 116true: 117 store volatile i32 1, i32* %p 118 br label %exit 119false: 120 store volatile i32 2, i32* %p 121 br i1 %d, label %ft, label %ff 122ft: 123 store volatile i32 3, i32* %p 124 br label %exit 125ff: 126 store volatile i32 4, i32* %p 127 br label %exit 128exit: 129 store volatile i32 5, i32* %p 130 ret i32 0 131} 132 133; CHECK-LABEL: triangle: 134; CHECK: block BB4_2{{$}} 135; CHECK: br_if $pop{{[0-9]+}}, BB4_2{{$}} 136; CHECK: BB4_2: 137; CHECK: return ${{[0-9]+}}{{$}} 138define i32 @triangle(i32* %p, i32 %a) { 139entry: 140 %c = icmp eq i32 %a, 0 141 store volatile i32 0, i32* %p 142 br i1 %c, label %true, label %exit 143true: 144 store volatile i32 1, i32* %p 145 br label %exit 146exit: 147 store volatile i32 2, i32* %p 148 ret i32 0 149} 150 151; CHECK-LABEL: diamond: 152; CHECK: block BB5_3{{$}} 153; CHECK: block BB5_2{{$}} 154; CHECK: br_if $pop{{[0-9]+}}, BB5_2{{$}} 155; CHECK: br BB5_3{{$}} 156; CHECK: BB5_2: 157; CHECK: BB5_3: 158; CHECK: return ${{[0-9]+}}{{$}} 159define i32 @diamond(i32* %p, i32 %a) { 160entry: 161 %c = icmp eq i32 %a, 0 162 store volatile i32 0, i32* %p 163 br i1 %c, label %true, label %false 164true: 165 store volatile i32 1, i32* %p 166 br label %exit 167false: 168 store volatile i32 2, i32* %p 169 br label %exit 170exit: 171 store volatile i32 3, i32* %p 172 ret i32 0 173} 174 175; CHECK-LABEL: single_block: 176; CHECK-NOT: br 177; CHECK: return ${{[0-9]+}}{{$}} 178define i32 @single_block(i32* %p) { 179entry: 180 store volatile i32 0, i32* %p 181 ret i32 0 182} 183 184; CHECK-LABEL: minimal_loop: 185; CHECK-NOT: br 186; CHECK: BB7_1: 187; CHECK: i32.store $discard=, $0, $pop{{[0-9]+}}{{$}} 188; CHECK: br BB7_1{{$}} 189; CHECK: BB7_2: 190define i32 @minimal_loop(i32* %p) { 191entry: 192 store volatile i32 0, i32* %p 193 br label %loop 194loop: 195 store volatile i32 1, i32* %p 196 br label %loop 197} 198 199; CHECK-LABEL: simple_loop: 200; CHECK-NOT: br 201; CHECK: BB8_1: 202; CHECK: loop BB8_2{{$}} 203; CHECK: br_if $pop{{[0-9]+}}, BB8_1{{$}} 204; CHECK: BB8_2: 205; CHECK: return ${{[0-9]+}}{{$}} 206define i32 @simple_loop(i32* %p, i32 %a) { 207entry: 208 %c = icmp eq i32 %a, 0 209 store volatile i32 0, i32* %p 210 br label %loop 211loop: 212 store volatile i32 1, i32* %p 213 br i1 %c, label %loop, label %exit 214exit: 215 store volatile i32 2, i32* %p 216 ret i32 0 217} 218 219; CHECK-LABEL: doubletriangle: 220; CHECK: block BB9_4{{$}} 221; CHECK: br_if $pop{{[0-9]+}}, BB9_4{{$}} 222; CHECK: block BB9_3{{$}} 223; CHECK: br_if $pop{{[0-9]+}}, BB9_3{{$}} 224; CHECK: BB9_3: 225; CHECK: BB9_4: 226; CHECK: return ${{[0-9]+}}{{$}} 227define i32 @doubletriangle(i32 %a, i32 %b, i32* %p) { 228entry: 229 %c = icmp eq i32 %a, 0 230 %d = icmp eq i32 %b, 0 231 store volatile i32 0, i32* %p 232 br i1 %c, label %true, label %exit 233true: 234 store volatile i32 2, i32* %p 235 br i1 %d, label %tt, label %tf 236tt: 237 store volatile i32 3, i32* %p 238 br label %tf 239tf: 240 store volatile i32 4, i32* %p 241 br label %exit 242exit: 243 store volatile i32 5, i32* %p 244 ret i32 0 245} 246 247; CHECK-LABEL: ifelse_earlyexits: 248; CHECK: block BB10_4{{$}} 249; CHECK: block BB10_2{{$}} 250; CHECK: br_if $pop{{[0-9]+}}, BB10_2{{$}} 251; CHECK: br BB10_4{{$}} 252; CHECK: BB10_2: 253; CHECK: br_if $pop{{[0-9]+}}, BB10_4{{$}} 254; CHECK: BB10_4: 255; CHECK: return ${{[0-9]+}}{{$}} 256define i32 @ifelse_earlyexits(i32 %a, i32 %b, i32* %p) { 257entry: 258 %c = icmp eq i32 %a, 0 259 %d = icmp eq i32 %b, 0 260 store volatile i32 0, i32* %p 261 br i1 %c, label %true, label %false 262true: 263 store volatile i32 1, i32* %p 264 br label %exit 265false: 266 store volatile i32 2, i32* %p 267 br i1 %d, label %ft, label %exit 268ft: 269 store volatile i32 3, i32* %p 270 br label %exit 271exit: 272 store volatile i32 4, i32* %p 273 ret i32 0 274} 275 276; CHECK-LABEL: doublediamond_in_a_loop: 277; CHECK: BB11_1: 278; CHECK: loop BB11_7{{$}} 279; CHECK: block BB11_6{{$}} 280; CHECK: block BB11_3{{$}} 281; CHECK: br_if $pop{{.*}}, BB11_3{{$}} 282; CHECK: br BB11_6{{$}} 283; CHECK: BB11_3: 284; CHECK: block BB11_5{{$}} 285; CHECK: br_if $pop{{.*}}, BB11_5{{$}} 286; CHECK: br BB11_6{{$}} 287; CHECK: BB11_5: 288; CHECK: BB11_6: 289; CHECK: br BB11_1{{$}} 290; CHECK: BB11_7: 291define i32 @doublediamond_in_a_loop(i32 %a, i32 %b, i32* %p) { 292entry: 293 br label %header 294header: 295 %c = icmp eq i32 %a, 0 296 %d = icmp eq i32 %b, 0 297 store volatile i32 0, i32* %p 298 br i1 %c, label %true, label %false 299true: 300 store volatile i32 1, i32* %p 301 br label %exit 302false: 303 store volatile i32 2, i32* %p 304 br i1 %d, label %ft, label %ff 305ft: 306 store volatile i32 3, i32* %p 307 br label %exit 308ff: 309 store volatile i32 4, i32* %p 310 br label %exit 311exit: 312 store volatile i32 5, i32* %p 313 br label %header 314} 315 316; Test that nested loops are handled. 317 318declare void @bar() 319 320define void @test3(i32 %w) { 321entry: 322 br i1 undef, label %outer.ph, label %exit 323 324outer.ph: 325 br label %outer 326 327outer: 328 %tobool = icmp eq i32 undef, 0 329 br i1 %tobool, label %inner, label %unreachable 330 331unreachable: 332 unreachable 333 334inner: 335 %c = icmp eq i32 undef, %w 336 br i1 %c, label %if.end, label %inner 337 338exit: 339 ret void 340 341if.end: 342 call void @bar() 343 br label %outer 344} 345