1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -ipsccp < %s | FileCheck %s 3 4; Make sure we always consider the default edge executable for a switch 5; with no cases. 6declare void @foo() 7define void @test1() { 8; CHECK-LABEL: @test1( 9; CHECK-NEXT: switch i32 undef, label [[D:%.*]] [ 10; CHECK-NEXT: ] 11; CHECK: d: 12; CHECK-NEXT: call void @foo() 13; CHECK-NEXT: ret void 14; 15 switch i32 undef, label %d [] 16d: 17 call void @foo() 18 ret void 19} 20 21define i32 @test_duplicate_successors_phi(i1 %c, i32 %x) { 22; CHECK-LABEL: @test_duplicate_successors_phi( 23; CHECK-NEXT: entry: 24; CHECK-NEXT: br i1 [[C:%.*]], label [[SWITCH:%.*]], label [[END:%.*]] 25; CHECK: switch: 26; CHECK-NEXT: br label [[SWITCH_DEFAULT:%.*]] 27; CHECK: switch.default: 28; CHECK-NEXT: ret i32 -1 29; CHECK: end: 30; CHECK-NEXT: ret i32 [[X:%.*]] 31; 32entry: 33 br i1 %c, label %switch, label %end 34 35switch: 36 switch i32 -1, label %switch.default [ 37 i32 0, label %end 38 i32 1, label %end 39 ] 40 41switch.default: 42 ret i32 -1 43 44end: 45 %phi = phi i32 [ %x, %entry ], [ 1, %switch ], [ 1, %switch ] 46 ret i32 %phi 47} 48 49define i32 @test_duplicate_successors_phi_2(i1 %c, i32 %x) { 50; CHECK-LABEL: @test_duplicate_successors_phi_2( 51; CHECK-NEXT: entry: 52; CHECK-NEXT: br i1 [[C:%.*]], label [[SWITCH:%.*]], label [[END:%.*]] 53; CHECK: switch: 54; CHECK-NEXT: br label [[END]] 55; CHECK: end: 56; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ 1, [[SWITCH]] ] 57; CHECK-NEXT: ret i32 [[PHI]] 58; 59entry: 60 br i1 %c, label %switch, label %end 61 62switch: 63 switch i32 0, label %switch.default [ 64 i32 0, label %end 65 i32 1, label %end 66 ] 67 68switch.default: 69 ret i32 -1 70 71end: 72 %phi = phi i32 [ %x, %entry ], [ 1, %switch ], [ 1, %switch ] 73 ret i32 %phi 74} 75 76define i32 @test_duplicate_successors_phi_3(i1 %c1, i32* %p, i32 %y) { 77; CHECK-LABEL: @test_duplicate_successors_phi_3( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: br i1 [[C1:%.*]], label [[SWITCH:%.*]], label [[SWITCH_1:%.*]] 80; CHECK: switch: 81; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range !0 82; CHECK-NEXT: switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [ 83; CHECK-NEXT: i32 0, label [[SWITCH_DEFAULT]] 84; CHECK-NEXT: i32 1, label [[SWITCH_0:%.*]] 85; CHECK-NEXT: i32 2, label [[SWITCH_0]] 86; CHECK-NEXT: ] 87; CHECK: switch.default: 88; CHECK-NEXT: ret i32 -1 89; CHECK: switch.0: 90; CHECK-NEXT: ret i32 0 91; CHECK: switch.1: 92; CHECK-NEXT: ret i32 [[Y:%.*]] 93; 94entry: 95 br i1 %c1, label %switch, label %switch.1 96 97switch: 98 %x = load i32, i32* %p, !range !{i32 0, i32 3} 99 switch i32 %x, label %switch.default [ 100 i32 0, label %switch.default 101 i32 1, label %switch.0 102 i32 2, label %switch.0 103 i32 3, label %switch.1 104 i32 4, label %switch.1 105 ] 106 107switch.default: 108 ret i32 -1 109 110switch.0: 111 ret i32 0 112 113switch.1: 114 %phi = phi i32 [ %y, %entry ], [ 0, %switch ], [ 0, %switch ] 115 ret i32 %phi 116} 117 118; TODO: Determine that the default destination is dead. 119define i32 @test_local_range(i32* %p) { 120; CHECK-LABEL: @test_local_range( 121; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range !0 122; CHECK-NEXT: switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [ 123; CHECK-NEXT: i32 0, label [[SWITCH_0:%.*]] 124; CHECK-NEXT: i32 1, label [[SWITCH_1:%.*]] 125; CHECK-NEXT: i32 2, label [[SWITCH_2:%.*]] 126; CHECK-NEXT: ] 127; CHECK: switch.default: 128; CHECK-NEXT: ret i32 -1 129; CHECK: switch.0: 130; CHECK-NEXT: ret i32 0 131; CHECK: switch.1: 132; CHECK-NEXT: ret i32 1 133; CHECK: switch.2: 134; CHECK-NEXT: ret i32 2 135; 136 %x = load i32, i32* %p, !range !{i32 0, i32 3} 137 switch i32 %x, label %switch.default [ 138 i32 0, label %switch.0 139 i32 1, label %switch.1 140 i32 2, label %switch.2 141 i32 3, label %switch.3 142 ] 143 144switch.default: 145 ret i32 -1 146 147switch.0: 148 ret i32 0 149 150switch.1: 151 ret i32 1 152 153switch.2: 154 ret i32 2 155 156switch.3: 157 ret i32 3 158} 159 160; TODO: Determine that case i3 is dead, even though the edge is shared? 161define i32 @test_duplicate_successors(i32* %p) { 162; CHECK-LABEL: @test_duplicate_successors( 163; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range !0 164; CHECK-NEXT: switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [ 165; CHECK-NEXT: i32 0, label [[SWITCH_0:%.*]] 166; CHECK-NEXT: i32 1, label [[SWITCH_0]] 167; CHECK-NEXT: i32 2, label [[SWITCH_1:%.*]] 168; CHECK-NEXT: i32 3, label [[SWITCH_1]] 169; CHECK-NEXT: ] 170; CHECK: switch.default: 171; CHECK-NEXT: ret i32 -1 172; CHECK: switch.0: 173; CHECK-NEXT: ret i32 0 174; CHECK: switch.1: 175; CHECK-NEXT: ret i32 1 176; 177 %x = load i32, i32* %p, !range !{i32 0, i32 3} 178 switch i32 %x, label %switch.default [ 179 i32 0, label %switch.0 180 i32 1, label %switch.0 181 i32 2, label %switch.1 182 i32 3, label %switch.1 183 i32 4, label %switch.2 184 i32 5, label %switch.2 185 ] 186 187switch.default: 188 ret i32 -1 189 190switch.0: 191 ret i32 0 192 193switch.1: 194 ret i32 1 195 196switch.2: 197 ret i32 2 198} 199 200; Case i32 2 is dead as well, but this cannot be determined based on 201; range information. 202define internal i32 @test_ip_range(i32 %x) { 203; CHECK-LABEL: @test_ip_range( 204; CHECK-NEXT: switch i32 [[X:%.*]], label [[SWITCH_DEFAULT:%.*]] [ 205; CHECK-NEXT: i32 3, label [[SWITCH_3:%.*]] 206; CHECK-NEXT: i32 1, label [[SWITCH_1:%.*]] 207; CHECK-NEXT: i32 2, label [[SWITCH_2:%.*]] 208; CHECK-NEXT: ], !prof !1 209; CHECK: switch.default: 210; CHECK-NEXT: ret i32 -1 211; CHECK: switch.1: 212; CHECK-NEXT: ret i32 1 213; CHECK: switch.2: 214; CHECK-NEXT: ret i32 2 215; CHECK: switch.3: 216; CHECK-NEXT: ret i32 3 217; 218 switch i32 %x, label %switch.default [ 219 i32 0, label %switch.0 220 i32 1, label %switch.1 221 i32 2, label %switch.2 222 i32 3, label %switch.3 223 ], !prof !{!"branch_weights", i32 1, i32 2, i32 3, i32 4, i32 5} 224 225switch.default: 226 ret i32 -1 227 228switch.0: 229 ret i32 0 230 231switch.1: 232 ret i32 1 233 234switch.2: 235 ret i32 2 236 237switch.3: 238 ret i32 3 239} 240 241define void @call_test_ip_range() { 242; CHECK-LABEL: @call_test_ip_range( 243; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test_ip_range(i32 1) 244; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test_ip_range(i32 3) 245; CHECK-NEXT: ret void 246; 247 call i32 @test_ip_range(i32 1) 248 call i32 @test_ip_range(i32 3) 249 ret void 250} 251 252declare void @llvm.assume(i1) 253 254; CHECK: !1 = !{!"branch_weights", i32 1, i32 5, i32 3, i32 4} 255