1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; then metadata checks MDn were added manually. 3; RUN: opt -passes='loop(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s 4; RUN: opt -verify-memoryssa -passes='loop-mssa(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s 5 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 0 36; CHECK: loop_exit2: 37; CHECK-NEXT: ret i32 0 38; CHECK: loop_exit3: 39; CHECK-NEXT: ret i32 0 40; 41entry: 42 br label %loop_begin 43 44loop_begin: 45 %var_val = load i32, ptr %var 46 switch i32 %cond2, label %loop2 [ 47 i32 0, label %loop0 48 i32 1, label %loop1 49 i32 2, label %loop_exit2 50 ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 102} 51 52loop0: 53 call void @some_func() 54 br label %loop_latch 55 56loop1: 57 call void @some_func() 58 br label %loop_latch 59 60loop2: 61 call void @some_func() 62 br label %loop_latch 63 64loop_latch: 65 br label %loop_begin 66 67loop_exit1: 68 ret i32 0 69 70loop_exit2: 71 ret i32 0 72 73loop_exit3: 74 ret i32 0 75} 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 0 107; CHECK: loop_exit2: 108; CHECK-NEXT: ret i32 0 109; CHECK: loop_exit3: 110; CHECK-NEXT: ret i32 0 111; 112entry: 113 br label %loop_begin 114 115loop_begin: 116 %var_val = load i32, ptr %var 117 switch i32 %cond2, label %loop_exit2 [ 118 i32 0, label %loop0 119 i32 1, label %loop1 120 i32 2, label %loop2 121 ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 102} 122 123loop0: 124 call void @some_func() 125 br label %loop_latch 126 127loop1: 128 call void @some_func() 129 br label %loop_latch 130 131loop2: 132 call void @some_func() 133 br label %loop_latch 134 135loop_latch: 136 br label %loop_begin 137 138loop_exit1: 139 ret i32 0 140 141loop_exit2: 142 ret i32 0 143 144loop_exit3: 145 ret i32 0 146} 147 148; Test for a trivially unswitchable switch with multiple exiting cases and 149; 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 0 181; CHECK: loop_exit2: 182; CHECK-NEXT: ret i32 0 183; CHECK: loop_exit3: 184; CHECK-NEXT: ret i32 0 185; 186entry: 187 br label %loop_begin 188 189loop_begin: 190 %var_val = load i32, ptr %var 191 switch i32 %cond2, label %loop_exit2 [ 192 i32 0, label %loop0 193 i32 1, label %loop1 194 i32 13, label %loop_exit1 195 i32 2, label %loop2 196 i32 42, label %loop_exit3 197 ], !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_latch 202 203loop1: 204 call void @some_func() 205 br label %loop_latch 206 207loop2: 208 call void @some_func() 209 br label %loop_latch 210 211loop_latch: 212 br label %loop_begin 213 214loop_exit1: 215 ret i32 0 216 217loop_exit2: 218 ret i32 0 219 220loop_exit3: 221 ret i32 0 222} 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