1; REQUIRES: asserts 2; RUN: opt -loop-unswitch -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s 3; RUN: opt -S -loop-unswitch -verify-loop-info -verify-dom-info < %s | FileCheck %s 4 5; STATS: 2 loop-unswitch - Number of switches unswitched 6 7; CHECK: %1 = icmp eq i32 %c, 1 8; CHECK-NEXT: br i1 %1, label %.split.us, label %..split_crit_edge 9 10; CHECK: ..split_crit_edge: ; preds = %0 11; CHECK-NEXT: br label %.split 12 13; CHECK: .split.us: ; preds = %0 14; CHECK-NEXT: br label %loop_begin.us 15 16; CHECK: loop_begin.us: ; preds = %loop_begin.backedge.us, %.split.us 17; CHECK-NEXT: %var_val.us = load i32, i32* %var 18; CHECK-NEXT: switch i32 1, label %default.us-lcssa.us [ 19; CHECK-NEXT: i32 1, label %inc.us 20 21; CHECK: inc.us: ; preds = %loop_begin.us 22; CHECK-NEXT: call void @incf() [[NOR_NUW:#[0-9]+]] 23; CHECK-NEXT: br label %loop_begin.backedge.us 24 25; CHECK: .split: ; preds = %..split_crit_edge 26; CHECK-NEXT: %2 = icmp eq i32 %c, 2 27; CHECK-NEXT: br i1 %2, label %.split.split.us, label %.split..split.split_crit_edge 28 29; CHECK: .split..split.split_crit_edge: ; preds = %.split 30; CHECK-NEXT: br label %.split.split 31 32; CHECK: .split.split.us: ; preds = %.split 33; CHECK-NEXT: br label %loop_begin.us1 34 35; CHECK: loop_begin.us1: ; preds = %loop_begin.backedge.us5, %.split.split.us 36; CHECK-NEXT: %var_val.us2 = load i32, i32* %var 37; CHECK-NEXT: switch i32 2, label %default.us-lcssa.us-lcssa.us [ 38; CHECK-NEXT: i32 1, label %inc.us4 39; CHECK-NEXT: i32 2, label %dec.us3 40; CHECK-NEXT: ] 41 42; CHECK: dec.us3: ; preds = %loop_begin.us1 43; CHECK-NEXT: call void @decf() [[NOR_NUW]] 44; CHECK-NEXT: br label %loop_begin.backedge.us5 45 46; CHECK: .split.split: ; preds = %.split..split.split_crit_edge 47; CHECK-NEXT: br label %loop_begin 48 49; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split.split 50; CHECK-NEXT: %var_val = load i32, i32* %var 51; CHECK-NEXT: switch i32 %c, label %default.us-lcssa.us-lcssa [ 52; CHECK-NEXT: i32 1, label %inc 53; CHECK-NEXT: i32 2, label %dec 54; CHECK-NEXT: ] 55 56; CHECK: inc: ; preds = %loop_begin 57; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa, label %inc.split 58 59; CHECK: dec: ; preds = %loop_begin 60; CHECK-NEXT: br i1 true, label %us-unreachable6, label %dec.split 61 62define i32 @test(i32* %var) { 63 %mem = alloca i32 64 store i32 2, i32* %mem 65 %c = load i32, i32* %mem 66 67 br label %loop_begin 68 69loop_begin: 70 71 %var_val = load i32, i32* %var 72 73 switch i32 %c, label %default [ 74 i32 1, label %inc 75 i32 2, label %dec 76 ] 77 78inc: 79 call void @incf() noreturn nounwind 80 br label %loop_begin 81dec: 82 call void @decf() noreturn nounwind 83 br label %loop_begin 84default: 85 br label %loop_exit 86loop_exit: 87 ret i32 0 88} 89 90declare void @incf() noreturn 91declare void @decf() noreturn 92 93; CHECK: attributes #0 = { noreturn } 94; CHECK: attributes [[NOR_NUW]] = { noreturn nounwind } 95