1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt %s -S -passes='simplifycfg<switch-to-lookup>' -simplifycfg-require-and-preserve-domtree=1 -switch-range-to-icmp | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5declare void @foo(i32) 6 7define void @test(i1 %a) { 8; CHECK-LABEL: define void @test( 9; CHECK-SAME: i1 [[A:%.*]]) { 10; CHECK-NEXT: [[A_OFF:%.*]] = add i1 [[A]], true 11; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i1 [[A_OFF]], true 12; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]] 13; CHECK: common.ret: 14; CHECK-NEXT: ret void 15; CHECK: true: 16; CHECK-NEXT: call void @foo(i32 1) 17; CHECK-NEXT: br label [[COMMON_RET:%.*]] 18; CHECK: false: 19; CHECK-NEXT: call void @foo(i32 3) 20; CHECK-NEXT: br label [[COMMON_RET]] 21; 22 switch i1 %a, label %default [i1 1, label %true 23 i1 0, label %false] 24true: 25 call void @foo(i32 1) 26 ret void 27false: 28 call void @foo(i32 3) 29 ret void 30default: 31 call void @foo(i32 2) 32 ret void 33} 34 35define void @test2(i2 %a) { 36; CHECK-LABEL: define void @test2( 37; CHECK-SAME: i2 [[A:%.*]]) { 38; CHECK-NEXT: switch i2 [[A]], label [[DOTUNREACHABLEDEFAULT:%.*]] [ 39; CHECK-NEXT: i2 0, label [[CASE0:%.*]] 40; CHECK-NEXT: i2 1, label [[CASE1:%.*]] 41; CHECK-NEXT: i2 -2, label [[CASE2:%.*]] 42; CHECK-NEXT: i2 -1, label [[CASE3:%.*]] 43; CHECK-NEXT: ] 44; CHECK: common.ret: 45; CHECK-NEXT: ret void 46; CHECK: case0: 47; CHECK-NEXT: call void @foo(i32 0) 48; CHECK-NEXT: br label [[COMMON_RET:%.*]] 49; CHECK: case1: 50; CHECK-NEXT: call void @foo(i32 1) 51; CHECK-NEXT: br label [[COMMON_RET]] 52; CHECK: case2: 53; CHECK-NEXT: call void @foo(i32 2) 54; CHECK-NEXT: br label [[COMMON_RET]] 55; CHECK: case3: 56; CHECK-NEXT: call void @foo(i32 3) 57; CHECK-NEXT: br label [[COMMON_RET]] 58; CHECK: .unreachabledefault: 59; CHECK-NEXT: unreachable 60; 61 switch i2 %a, label %default [i2 0, label %case0 62 i2 1, label %case1 63 i2 2, label %case2 64 i2 3, label %case3] 65case0: 66 call void @foo(i32 0) 67 ret void 68case1: 69 call void @foo(i32 1) 70 ret void 71case2: 72 call void @foo(i32 2) 73 ret void 74case3: 75 call void @foo(i32 3) 76 ret void 77default: 78 call void @foo(i32 4) 79 ret void 80} 81 82; We can replace the default branch with case 3 since it is the only case that is missing. 83define void @test3(i2 %a) { 84; CHECK-LABEL: define void @test3( 85; CHECK-SAME: i2 [[A:%.*]]) { 86; CHECK-NEXT: switch i2 [[A]], label [[DOTUNREACHABLEDEFAULT:%.*]] [ 87; CHECK-NEXT: i2 0, label [[CASE0:%.*]] 88; CHECK-NEXT: i2 1, label [[CASE1:%.*]] 89; CHECK-NEXT: i2 -2, label [[CASE2:%.*]] 90; CHECK-NEXT: i2 -1, label [[DEFAULT:%.*]] 91; CHECK-NEXT: ] 92; CHECK: common.ret: 93; CHECK-NEXT: ret void 94; CHECK: case0: 95; CHECK-NEXT: call void @foo(i32 0) 96; CHECK-NEXT: br label [[COMMON_RET:%.*]] 97; CHECK: case1: 98; CHECK-NEXT: call void @foo(i32 1) 99; CHECK-NEXT: br label [[COMMON_RET]] 100; CHECK: case2: 101; CHECK-NEXT: call void @foo(i32 2) 102; CHECK-NEXT: br label [[COMMON_RET]] 103; CHECK: .unreachabledefault: 104; CHECK-NEXT: unreachable 105; CHECK: default: 106; CHECK-NEXT: call void @foo(i32 3) 107; CHECK-NEXT: br label [[COMMON_RET]] 108; 109 switch i2 %a, label %default [i2 0, label %case0 110 i2 1, label %case1 111 i2 2, label %case2] 112 113case0: 114 call void @foo(i32 0) 115 ret void 116case1: 117 call void @foo(i32 1) 118 ret void 119case2: 120 call void @foo(i32 2) 121 ret void 122default: 123 call void @foo(i32 3) 124 ret void 125} 126 127define void @test3_prof(i2 %a) { 128; CHECK-LABEL: define void @test3_prof( 129; CHECK-SAME: i2 [[A:%.*]]) { 130; CHECK-NEXT: switch i2 [[A]], label [[DOTUNREACHABLEDEFAULT:%.*]] [ 131; CHECK-NEXT: i2 0, label [[CASE0:%.*]] 132; CHECK-NEXT: i2 1, label [[CASE1:%.*]] 133; CHECK-NEXT: i2 -2, label [[CASE2:%.*]] 134; CHECK-NEXT: i2 -1, label [[DEFAULT:%.*]] 135; CHECK-NEXT: ], !prof [[PROF0:![0-9]+]] 136; CHECK: common.ret: 137; CHECK-NEXT: ret void 138; CHECK: case0: 139; CHECK-NEXT: call void @foo(i32 0) 140; CHECK-NEXT: br label [[COMMON_RET:%.*]] 141; CHECK: case1: 142; CHECK-NEXT: call void @foo(i32 1) 143; CHECK-NEXT: br label [[COMMON_RET]] 144; CHECK: case2: 145; CHECK-NEXT: call void @foo(i32 2) 146; CHECK-NEXT: br label [[COMMON_RET]] 147; CHECK: .unreachabledefault: 148; CHECK-NEXT: unreachable 149; CHECK: default: 150; CHECK-NEXT: call void @foo(i32 3) 151; CHECK-NEXT: br label [[COMMON_RET]] 152; 153 switch i2 %a, label %default [i2 0, label %case0 154 i2 1, label %case1 155 i2 2, label %case2], !prof !0 156 157case0: 158 call void @foo(i32 0) 159 ret void 160case1: 161 call void @foo(i32 1) 162 ret void 163case2: 164 call void @foo(i32 2) 165 ret void 166default: 167 call void @foo(i32 3) 168 ret void 169} 170 171; Negative test - check for possible overflow when computing 172; number of possible cases. 173define void @test4(i128 %a) { 174; CHECK-LABEL: define void @test4( 175; CHECK-SAME: i128 [[A:%.*]]) { 176; CHECK-NEXT: switch i128 [[A]], label [[DEFAULT:%.*]] [ 177; CHECK-NEXT: i128 0, label [[CASE0:%.*]] 178; CHECK-NEXT: i128 1, label [[CASE1:%.*]] 179; CHECK-NEXT: ] 180; CHECK: common.ret: 181; CHECK-NEXT: ret void 182; CHECK: case0: 183; CHECK-NEXT: call void @foo(i32 0) 184; CHECK-NEXT: br label [[COMMON_RET:%.*]] 185; CHECK: case1: 186; CHECK-NEXT: call void @foo(i32 1) 187; CHECK-NEXT: br label [[COMMON_RET]] 188; CHECK: default: 189; CHECK-NEXT: call void @foo(i32 2) 190; CHECK-NEXT: br label [[COMMON_RET]] 191; 192 switch i128 %a, label %default [i128 0, label %case0 193 i128 1, label %case1] 194 195case0: 196 call void @foo(i32 0) 197 ret void 198case1: 199 call void @foo(i32 1) 200 ret void 201default: 202 call void @foo(i32 2) 203 ret void 204} 205 206; All but one bit known zero 207define void @test5(i8 %a) { 208; CHECK-LABEL: define void @test5( 209; CHECK-SAME: i8 [[A:%.*]]) { 210; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A]], 2 211; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 212; CHECK-NEXT: [[A_OFF:%.*]] = add i8 [[A]], -1 213; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1 214; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]] 215; CHECK: common.ret: 216; CHECK-NEXT: ret void 217; CHECK: true: 218; CHECK-NEXT: call void @foo(i32 1) 219; CHECK-NEXT: br label [[COMMON_RET:%.*]] 220; CHECK: false: 221; CHECK-NEXT: call void @foo(i32 3) 222; CHECK-NEXT: br label [[COMMON_RET]] 223; 224 %cmp = icmp ult i8 %a, 2 225 call void @llvm.assume(i1 %cmp) 226 switch i8 %a, label %default [i8 1, label %true 227 i8 0, label %false] 228true: 229 call void @foo(i32 1) 230 ret void 231false: 232 call void @foo(i32 3) 233 ret void 234default: 235 call void @foo(i32 2) 236 ret void 237} 238 239;; All but one bit known one 240define void @test6(i8 %a) { 241; CHECK-LABEL: define void @test6( 242; CHECK-SAME: i8 [[A:%.*]]) { 243; CHECK-NEXT: [[AND:%.*]] = and i8 [[A]], -2 244; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], -2 245; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 246; CHECK-NEXT: [[A_OFF:%.*]] = add i8 [[A]], 1 247; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1 248; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]] 249; CHECK: common.ret: 250; CHECK-NEXT: ret void 251; CHECK: true: 252; CHECK-NEXT: call void @foo(i32 1) 253; CHECK-NEXT: br label [[COMMON_RET:%.*]] 254; CHECK: false: 255; CHECK-NEXT: call void @foo(i32 3) 256; CHECK-NEXT: br label [[COMMON_RET]] 257; 258 %and = and i8 %a, 254 259 %cmp = icmp eq i8 %and, 254 260 call void @llvm.assume(i1 %cmp) 261 switch i8 %a, label %default [i8 255, label %true 262 i8 254, label %false] 263true: 264 call void @foo(i32 1) 265 ret void 266false: 267 call void @foo(i32 3) 268 ret void 269default: 270 call void @foo(i32 2) 271 ret void 272} 273 274; Check that we can eliminate both dead cases and dead defaults 275; within a single run of simplifycfg 276define void @test7(i8 %a) { 277; CHECK-LABEL: define void @test7( 278; CHECK-SAME: i8 [[A:%.*]]) { 279; CHECK-NEXT: [[AND:%.*]] = and i8 [[A]], -2 280; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], -2 281; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 282; CHECK-NEXT: [[A_OFF:%.*]] = add i8 [[A]], 1 283; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1 284; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]] 285; CHECK: common.ret: 286; CHECK-NEXT: ret void 287; CHECK: true: 288; CHECK-NEXT: call void @foo(i32 1) 289; CHECK-NEXT: br label [[COMMON_RET:%.*]] 290; CHECK: false: 291; CHECK-NEXT: call void @foo(i32 3) 292; CHECK-NEXT: br label [[COMMON_RET]] 293; 294 %and = and i8 %a, 254 295 %cmp = icmp eq i8 %and, 254 296 call void @llvm.assume(i1 %cmp) 297 switch i8 %a, label %default [i8 255, label %true 298 i8 254, label %false 299 i8 0, label %also_dead] 300true: 301 call void @foo(i32 1) 302 ret void 303false: 304 call void @foo(i32 3) 305 ret void 306also_dead: 307 call void @foo(i32 5) 308 ret void 309default: 310 call void @foo(i32 2) 311 ret void 312} 313 314declare void @llvm.assume(i1) 315 316define zeroext i1 @test8(i128 %a) { 317; We should not transform conditions wider than 64 bit. 318; CHECK-LABEL: define zeroext i1 @test8( 319; CHECK-SAME: i128 [[A:%.*]]) { 320; CHECK-NEXT: entry: 321; CHECK-NEXT: [[TMP0:%.*]] = and i128 [[A]], 3894222643901120721397872246915072 322; CHECK-NEXT: switch i128 [[TMP0]], label [[LOR_RHS:%.*]] [ 323; CHECK-NEXT: i128 1298074214633706907132624082305024, label [[LOR_END:%.*]] 324; CHECK-NEXT: i128 2596148429267413814265248164610048, label [[LOR_END]] 325; CHECK-NEXT: i128 3894222643901120721397872246915072, label [[LOR_END]] 326; CHECK-NEXT: ] 327; CHECK: lor.rhs: 328; CHECK-NEXT: br label [[LOR_END]] 329; CHECK: lor.end: 330; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ] 331; CHECK-NEXT: ret i1 [[TMP1]] 332; 333entry: 334 %0 = and i128 %a, 3894222643901120721397872246915072 335 switch i128 %0, label %lor.rhs [ 336 i128 1298074214633706907132624082305024, label %lor.end 337 i128 2596148429267413814265248164610048, label %lor.end 338 i128 3894222643901120721397872246915072, label %lor.end 339 ] 340 341lor.rhs: ; preds = %entry 342 br label %lor.end 343 344lor.end: ; preds = %entry, %entry, %entry, %lor.rhs 345 %1 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ] 346 ret i1 %1 347} 348 349!0 = !{!"branch_weights", i32 8, i32 4, i32 2, i32 1} 350;. 351; CHECK: [[PROF0]] = !{!"branch_weights", i32 0, i32 4, i32 2, i32 1, i32 8} 352;. 353