229 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; then metadata checks MDn were added manually.3; RUN: opt -passes='loop(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s4; RUN: opt -verify-memoryssa -passes='loop-mssa(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s5 6declare void @some_func()7 8; Test for a trivially unswitchable switch with non-default case exiting.9define i32 @test2(ptr %var, i32 %cond1, i32 %cond2) {10; CHECK-LABEL: @test2(11; CHECK-NEXT: entry:12; CHECK-NEXT: switch i32 [[COND2:%.*]], label [[ENTRY_SPLIT:%.*]] [13; CHECK-NEXT: i32 2, label [[LOOP_EXIT2:%.*]]14; CHECK-NEXT: ], !prof ![[MD0:[0-9]+]]15; CHECK: entry.split:16; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]]17; CHECK: loop_begin:18; CHECK-NEXT: [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]]19; CHECK-NEXT: switch i32 [[COND2]], label [[LOOP2:%.*]] [20; CHECK-NEXT: i32 0, label [[LOOP0:%.*]]21; CHECK-NEXT: i32 1, label [[LOOP1:%.*]]22; CHECK-NEXT: ], !prof ![[MD1:[0-9]+]]23; CHECK: loop0:24; CHECK-NEXT: call void @some_func()25; CHECK-NEXT: br label [[LOOP_LATCH:%.*]]26; CHECK: loop1:27; CHECK-NEXT: call void @some_func()28; CHECK-NEXT: br label [[LOOP_LATCH]]29; CHECK: loop2:30; CHECK-NEXT: call void @some_func()31; CHECK-NEXT: br label [[LOOP_LATCH]]32; CHECK: loop_latch:33; CHECK-NEXT: br label [[LOOP_BEGIN]]34; CHECK: loop_exit1:35; CHECK-NEXT: ret i32 036; CHECK: loop_exit2:37; CHECK-NEXT: ret i32 038; CHECK: loop_exit3:39; CHECK-NEXT: ret i32 040;41entry:42 br label %loop_begin43 44loop_begin:45 %var_val = load i32, ptr %var46 switch i32 %cond2, label %loop2 [47 i32 0, label %loop048 i32 1, label %loop149 i32 2, label %loop_exit250 ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 102}51 52loop0:53 call void @some_func()54 br label %loop_latch55 56loop1:57 call void @some_func()58 br label %loop_latch59 60loop2:61 call void @some_func()62 br label %loop_latch63 64loop_latch:65 br label %loop_begin66 67loop_exit1:68 ret i32 069 70loop_exit2:71 ret i32 072 73loop_exit3:74 ret i32 075}76 77; Test for a trivially unswitchable switch with only the default case exiting.78define i32 @test3(ptr %var, i32 %cond1, i32 %cond2) {79; CHECK-LABEL: @test3(80; CHECK-NEXT: entry:81; CHECK-NEXT: switch i32 [[COND2:%.*]], label [[LOOP_EXIT2:%.*]] [82; CHECK-NEXT: i32 0, label [[ENTRY_SPLIT:%.*]]83; CHECK-NEXT: i32 1, label [[ENTRY_SPLIT]]84; CHECK-NEXT: i32 2, label [[ENTRY_SPLIT]]85; CHECK-NEXT: ], !prof ![[MD2:[0-9]+]]86; CHECK: entry.split:87; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]]88; CHECK: loop_begin:89; CHECK-NEXT: [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]]90; CHECK-NEXT: switch i32 [[COND2]], label [[LOOP2:%.*]] [91; CHECK-NEXT: i32 0, label [[LOOP0:%.*]]92; CHECK-NEXT: i32 1, label [[LOOP1:%.*]]93; CHECK-NEXT: ], !prof ![[MD3:[0-9]+]]94; CHECK: loop0:95; CHECK-NEXT: call void @some_func()96; CHECK-NEXT: br label [[LOOP_LATCH:%.*]]97; CHECK: loop1:98; CHECK-NEXT: call void @some_func()99; CHECK-NEXT: br label [[LOOP_LATCH]]100; CHECK: loop2:101; CHECK-NEXT: call void @some_func()102; CHECK-NEXT: br label [[LOOP_LATCH]]103; CHECK: loop_latch:104; CHECK-NEXT: br label [[LOOP_BEGIN]]105; CHECK: loop_exit1:106; CHECK-NEXT: ret i32 0107; CHECK: loop_exit2:108; CHECK-NEXT: ret i32 0109; CHECK: loop_exit3:110; CHECK-NEXT: ret i32 0111;112entry:113 br label %loop_begin114 115loop_begin:116 %var_val = load i32, ptr %var117 switch i32 %cond2, label %loop_exit2 [118 i32 0, label %loop0119 i32 1, label %loop1120 i32 2, label %loop2121 ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 102}122 123loop0:124 call void @some_func()125 br label %loop_latch126 127loop1:128 call void @some_func()129 br label %loop_latch130 131loop2:132 call void @some_func()133 br label %loop_latch134 135loop_latch:136 br label %loop_begin137 138loop_exit1:139 ret i32 0140 141loop_exit2:142 ret i32 0143 144loop_exit3:145 ret i32 0146}147 148; Test for a trivially unswitchable switch with multiple exiting cases and149; multiple looping cases.150define i32 @test4(ptr %var, i32 %cond1, i32 %cond2) {151; CHECK-LABEL: @test4(152; CHECK-NEXT: entry:153; CHECK-NEXT: switch i32 [[COND2:%.*]], label [[LOOP_EXIT2:%.*]] [154; CHECK-NEXT: i32 13, label [[LOOP_EXIT1:%.*]]155; CHECK-NEXT: i32 42, label [[LOOP_EXIT3:%.*]]156; CHECK-NEXT: i32 0, label [[ENTRY_SPLIT:%.*]]157; CHECK-NEXT: i32 1, label [[ENTRY_SPLIT]]158; CHECK-NEXT: i32 2, label [[ENTRY_SPLIT]]159; CHECK-NEXT: ], !prof ![[MD4:[0-9]+]]160; CHECK: entry.split:161; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]]162; CHECK: loop_begin:163; CHECK-NEXT: [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]]164; CHECK-NEXT: switch i32 [[COND2]], label [[LOOP2:%.*]] [165; CHECK-NEXT: i32 0, label [[LOOP0:%.*]]166; CHECK-NEXT: i32 1, label [[LOOP1:%.*]]167; CHECK-NEXT: ], !prof ![[MD3:[0-9]+]]168; CHECK: loop0:169; CHECK-NEXT: call void @some_func()170; CHECK-NEXT: br label [[LOOP_LATCH:%.*]]171; CHECK: loop1:172; CHECK-NEXT: call void @some_func()173; CHECK-NEXT: br label [[LOOP_LATCH]]174; CHECK: loop2:175; CHECK-NEXT: call void @some_func()176; CHECK-NEXT: br label [[LOOP_LATCH]]177; CHECK: loop_latch:178; CHECK-NEXT: br label [[LOOP_BEGIN]]179; CHECK: loop_exit1:180; CHECK-NEXT: ret i32 0181; CHECK: loop_exit2:182; CHECK-NEXT: ret i32 0183; CHECK: loop_exit3:184; CHECK-NEXT: ret i32 0185;186entry:187 br label %loop_begin188 189loop_begin:190 %var_val = load i32, ptr %var191 switch i32 %cond2, label %loop_exit2 [192 i32 0, label %loop0193 i32 1, label %loop1194 i32 13, label %loop_exit1195 i32 2, label %loop2196 i32 42, label %loop_exit3197 ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 113, i32 102, i32 142}198 199loop0:200 call void @some_func()201 br label %loop_latch202 203loop1:204 call void @some_func()205 br label %loop_latch206 207loop2:208 call void @some_func()209 br label %loop_latch210 211loop_latch:212 br label %loop_begin213 214loop_exit1:215 ret i32 0216 217loop_exit2:218 ret i32 0219 220loop_exit3:221 ret i32 0222}223 224; CHECK: ![[MD0]] = !{!"branch_weights", i32 300, i32 102}225; CHECK: ![[MD1]] = !{!"branch_weights", i32 99, i32 100, i32 101}226; CHECK: ![[MD2]] = !{!"branch_weights", i32 99, i32 100, i32 101, i32 102}227; CHECK: ![[MD3]] = !{!"branch_weights", i32 102, i32 100, i32 101}228; CHECK: ![[MD4]] = !{!"branch_weights", i32 99, i32 113, i32 142, i32 100, i32 101, i32 102}229