Chen Li | 145c2f5 | 2015-07-25 03:21:06 +0000 | [diff] [blame] | 1 | ; RUN: opt < %s -loop-unswitch -loop-unswitch-threshold=0 -verify-loop-info -S < %s 2>&1 | FileCheck %s |
| 2 | |
| 3 | ; This test contains two trivial unswitch condition in one loop. |
| 4 | ; LoopUnswitch pass should be able to unswitch the second one |
| 5 | ; after unswitching the first one. |
| 6 | |
| 7 | |
| 8 | ; CHECK: br i1 %cond1, label %..split_crit_edge, label %.loop_exit.split_crit_edge |
| 9 | |
| 10 | ; CHECK: ..split_crit_edge: ; preds = %0 |
| 11 | ; CHECK: br label %.split |
| 12 | |
| 13 | ; CHECK: .split: ; preds = %..split_crit_edge |
| 14 | ; CHECK: br i1 %cond2, label %.split..split.split_crit_edge, label %.split.loop_exit.split1_crit_edge |
| 15 | |
| 16 | ; CHECK: .split..split.split_crit_edge: ; preds = %.split |
| 17 | ; CHECK: br label %.split.split |
| 18 | |
| 19 | ; CHECK: .split.split: ; preds = %.split..split.split_crit_edge |
| 20 | ; CHECK: br label %loop_begin |
| 21 | |
| 22 | ; CHECK: loop_begin: ; preds = %do_something, %.split.split |
| 23 | ; CHECK: br i1 true, label %continue, label %loop_exit |
| 24 | |
| 25 | ; CHECK: continue: ; preds = %loop_begin |
| 26 | ; CHECK: %var_val = load i32, i32* %var |
| 27 | ; CHECK: br i1 true, label %do_something, label %loop_exit |
| 28 | |
| 29 | define i32 @test(i32* %var, i1 %cond1, i1 %cond2) { |
| 30 | br label %loop_begin |
| 31 | |
| 32 | loop_begin: |
| 33 | br i1 %cond1, label %continue, label %loop_exit ; first trivial condition |
| 34 | |
| 35 | continue: |
| 36 | %var_val = load i32, i32* %var |
| 37 | br i1 %cond2, label %do_something, label %loop_exit ; second trivial condition |
| 38 | |
| 39 | do_something: |
| 40 | call void @some_func() noreturn nounwind |
| 41 | br label %loop_begin |
| 42 | |
| 43 | loop_exit: |
| 44 | ret i32 0 |
| 45 | } |
| 46 | |
Xin Tong | e5f8d64 | 2017-01-27 01:42:20 +0000 | [diff] [blame] | 47 | |
| 48 | ; We will not be able trivially unswitch on the SwitchInst, as its input |
| 49 | ; is a constant. However, since its a constant we should be able to figure |
| 50 | ; out that the switch can be folded into a unconditional branch to %continue. |
| 51 | ; Then we unswitch on the br inst in %continue. |
| 52 | ; |
| 53 | ; CHECK: define i32 @test2( |
| 54 | ; This is an indication that the loop has been unswitched on %cond1. |
| 55 | ; CHECK: br i1 %cond1, label %..split_crit_edge, label %.loop_exit.split_crit_edge |
| 56 | |
| 57 | ; CHECK: ..split_crit_edge: ; preds = %0 |
| 58 | ; CHECK: br label %.split |
| 59 | |
| 60 | ; CHECK: .split: ; preds = %..split_crit_edge |
| 61 | ; CHECK: br label %loop_begin |
| 62 | |
| 63 | ; CHECK: loop_begin: ; preds = %do_something, %.split |
| 64 | ; CHECK: switch i32 |
| 65 | |
| 66 | ; CHECK: continue: ; preds = %loop_begin |
| 67 | ; CHECK: %var_val = load i32, i32* %var |
| 68 | ; CHECK: br i1 true, label %do_something, label %loop_exit |
| 69 | |
| 70 | define i32 @test2(i32* %var, i1 %cond1) { |
| 71 | br label %loop_begin |
| 72 | |
| 73 | loop_begin: |
| 74 | switch i32 1, label %continue [ |
| 75 | i32 0, label %loop_exit |
| 76 | i32 1, label %continue |
| 77 | ] |
| 78 | |
| 79 | continue: |
| 80 | %var_val = load i32, i32* %var |
| 81 | br i1 %cond1, label %do_something, label %loop_exit |
| 82 | |
| 83 | do_something: |
| 84 | call void @some_func() noreturn nounwind |
| 85 | br label %loop_begin |
| 86 | |
| 87 | loop_exit: |
| 88 | ret i32 0 |
| 89 | } |
| 90 | |
| 91 | declare void @some_func() noreturn |