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