| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -passes='loop(simple-loop-unswitch)' -S %s | FileCheck %s |
| |
| declare void @some_func() |
| |
| define i32 @need_freeze_of_individual_or_conditions1(i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4) { |
| ; CHECK-LABEL: @need_freeze_of_individual_or_conditions1( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]] |
| ; CHECK-NEXT: [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND4_FR]], [[COND1_FR]] |
| ; CHECK-NEXT: br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[OR:%.*]] = or i1 [[COND2:%.*]], [[COND3:%.*]] |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[OR]], true |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 false |
| ; CHECK-NEXT: br i1 [[AND2]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]] |
| ; CHECK: loop.latch: |
| ; CHECK-NEXT: call void @some_func() |
| ; CHECK-NEXT: br label [[LOOP_HEADER]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %or = or i1 %cond2, %cond3 |
| %and1 = and i1 %or, %cond1 |
| %and2 = select i1 %and1, i1 %cond4, i1 false |
| br i1 %and2, label %loop.latch, label %exit |
| |
| loop.latch: |
| call void @some_func() |
| br label %loop.header |
| |
| exit: |
| ret i32 0 |
| } |
| |
| define i32 @need_freeze_of_individual_or_conditions2(i1 noundef %cond1, i1 %cond2, i1 %cond3, i1 %cond4) { |
| ; CHECK-LABEL: @need_freeze_of_individual_or_conditions2( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND4_FR]], [[COND1:%.*]] |
| ; CHECK-NEXT: br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[OR:%.*]] = or i1 [[COND2:%.*]], [[COND3:%.*]] |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[OR]], true |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 false |
| ; CHECK-NEXT: br i1 [[AND2]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]] |
| ; CHECK: loop.latch: |
| ; CHECK-NEXT: call void @some_func() |
| ; CHECK-NEXT: br label [[LOOP_HEADER]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %or = or i1 %cond2, %cond3 |
| %and1 = and i1 %or, %cond1 |
| %and2 = select i1 %and1, i1 %cond4, i1 false |
| br i1 %and2, label %loop.latch, label %exit |
| |
| loop.latch: |
| call void @some_func() |
| br label %loop.header |
| |
| exit: |
| ret i32 0 |
| } |
| |
| define i32 @need_freeze_of_individual_or_conditions3(i1 %cond1, i1 %cond2, i1 %cond3, i1 noundef %cond4) { |
| ; CHECK-LABEL: @need_freeze_of_individual_or_conditions3( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND4:%.*]], [[COND1_FR]] |
| ; CHECK-NEXT: br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[OR:%.*]] = or i1 [[COND2:%.*]], [[COND3:%.*]] |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[OR]], true |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 false |
| ; CHECK-NEXT: br i1 [[AND2]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]] |
| ; CHECK: loop.latch: |
| ; CHECK-NEXT: call void @some_func() |
| ; CHECK-NEXT: br label [[LOOP_HEADER]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %or = or i1 %cond2, %cond3 |
| %and1 = and i1 %or, %cond1 |
| %and2 = select i1 %and1, i1 %cond4, i1 false |
| br i1 %and2, label %loop.latch, label %exit |
| |
| loop.latch: |
| call void @some_func() |
| br label %loop.header |
| |
| exit: |
| ret i32 0 |
| } |
| |
| define i32 @need_freeze_of_individual_and_conditions1(i1 %cond1, i1 %cond4) { |
| ; CHECK-LABEL: @need_freeze_of_individual_and_conditions1( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]] |
| ; CHECK-NEXT: [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4_FR]], [[COND1_FR]] |
| ; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[COND_OR1:%.*]] = or i1 undef, false |
| ; CHECK-NEXT: [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false |
| ; CHECK-NEXT: br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]] |
| ; CHECK: loop.latch: |
| ; CHECK-NEXT: br label [[LOOP_HEADER]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %cond_or1 = or i1 undef, %cond1 |
| %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4 |
| br i1 %cond_or6, label %exit, label %loop.latch |
| |
| loop.latch: |
| br label %loop.header |
| |
| exit: |
| ret i32 0 |
| } |
| |
| define i32 @need_freeze_of_individual_and_conditions2(i1 noundef %cond1, i1 %cond4) { |
| ; CHECK-LABEL: @need_freeze_of_individual_and_conditions2( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4_FR]], [[COND1:%.*]] |
| ; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[COND_OR1:%.*]] = or i1 undef, false |
| ; CHECK-NEXT: [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false |
| ; CHECK-NEXT: br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]] |
| ; CHECK: loop.latch: |
| ; CHECK-NEXT: br label [[LOOP_HEADER]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %cond_or1 = or i1 undef, %cond1 |
| %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4 |
| br i1 %cond_or6, label %exit, label %loop.latch |
| |
| loop.latch: |
| br label %loop.header |
| |
| exit: |
| ret i32 0 |
| } |
| |
| define i32 @need_freeze_of_individual_and_conditions3(i1 %cond1, i1 noundef %cond4) { |
| ; CHECK-LABEL: @need_freeze_of_individual_and_conditions3( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND1_FR]] |
| ; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[COND_OR1:%.*]] = or i1 undef, false |
| ; CHECK-NEXT: [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false |
| ; CHECK-NEXT: br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]] |
| ; CHECK: loop.latch: |
| ; CHECK-NEXT: br label [[LOOP_HEADER]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %cond_or1 = or i1 undef, %cond1 |
| %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4 |
| br i1 %cond_or6, label %exit, label %loop.latch |
| |
| loop.latch: |
| br label %loop.header |
| |
| exit: |
| ret i32 0 |
| } |
| |
| define i32 @need_freeze_of_individual_and_conditions4(i1 noundef %cond1, i1 noundef %cond4) { |
| ; CHECK-LABEL: @need_freeze_of_individual_and_conditions4( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND1:%.*]] |
| ; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[COND_OR1:%.*]] = or i1 undef, false |
| ; CHECK-NEXT: [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false |
| ; CHECK-NEXT: br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]] |
| ; CHECK: loop.latch: |
| ; CHECK-NEXT: br label [[LOOP_HEADER]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %cond_or1 = or i1 undef, %cond1 |
| %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4 |
| br i1 %cond_or6, label %exit, label %loop.latch |
| |
| loop.latch: |
| br label %loop.header |
| |
| exit: |
| ret i32 0 |
| } |