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 63 define 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 70 loop_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 79 inc: 80 call void @incf() noreturn nounwind 81 br label %loop_begin 82 dec: 83 call void @decf() noreturn nounwind 84 br label %loop_begin 85 default: 86 br label %loop_exit 87 loop_exit: 88 ret i32 0 89 } 90 91 declare void @incf() noreturn 92 declare void @decf() noreturn 93 94 ; CHECK: attributes #0 = { noreturn } 95 ; CHECK: attributes [[NOR_NUW]] = { noreturn nounwind } 96