1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals 2; RUN: opt < %s -passes=simplifycfg -switch-to-lookup=true -keep-loops=false -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s 3; RUN: opt < %s -passes='simplifycfg<no-keep-loops;switch-to-lookup>' -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7; A simple int-to-int selection switch. 8; It is dense enough to be replaced by table lookup. 9; The result is directly by a ret from an otherwise empty bb, 10; so we return early, directly from the lookup bb. 11 12;. 13; CHECK: @.str = private unnamed_addr constant [4 x i8] c"foo\00", align 1 14; CHECK: @.str1 = private unnamed_addr constant [4 x i8] c"bar\00", align 1 15; CHECK: @.str2 = private unnamed_addr constant [4 x i8] c"baz\00", align 1 16; CHECK: @.str3 = private unnamed_addr constant [4 x i8] c"qux\00", align 1 17; CHECK: @.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1 18; CHECK: @tls_a = thread_local global i32 0 19; CHECK: @tls_b = thread_local global i32 0 20; CHECK: @tls_c = thread_local global i32 0 21; CHECK: @tls_d = thread_local global i32 0 22; CHECK: @dllimport_a = external dllimport global [3 x i32] 23; CHECK: @dllimport_b = external dllimport global [3 x i32] 24; CHECK: @dllimport_c = external dllimport global [3 x i32] 25; CHECK: @dllimport_d = external dllimport global [3 x i32] 26; CHECK: @switch.table.f = private unnamed_addr constant [7 x i32] [i32 55, i32 123, i32 0, i32 -1, i32 27, i32 62, i32 1], align 4 27; CHECK: @switch.table.char = private unnamed_addr constant [9 x i8] c"7{\00\FF\1B>\01!T", align 1 28; CHECK: @switch.table.h = private unnamed_addr constant [4 x float] [float 0x40091EB860000000, float 0x3FF3BE76C0000000, float 0x4012449BA0000000, float 0x4001AE1480000000], align 4 29; CHECK: @switch.table.foostring = private unnamed_addr constant [4 x ptr] [ptr @.str, ptr @.str1, ptr @.str2, ptr @.str3], align 8 30; CHECK: @switch.table.earlyreturncrash = private unnamed_addr constant [4 x i32] [i32 42, i32 9, i32 88, i32 5], align 4 31; CHECK: @switch.table.earlyreturncrash.1 = private unnamed_addr constant [4 x i32] [i32 3, i32 4, i32 1, i32 5], align 4 32; CHECK: @switch.table.large = private unnamed_addr constant [199 x i32] [i32 1, i32 4, i32 9, i32 16, i32 25, i32 36, i32 49, i32 64, i32 81, i32 100, i32 121, i32 144, i32 169, i32 196, i32 225, i32 256, i32 289, i32 342, i32 361, i32 400, i32 441, i32 484, i32 529, i32 576, i32 625, i32 676, i32 729, i32 784, i32 841, i32 900, i32 961, i32 1024, i32 1089, i32 1156, i32 1260, i32 1296, i32 1369, i32 1444, i32 1521, i32 1600, i32 1681, i32 1764, i32 1849, i32 1980, i32 2025, i32 2116, i32 2209, i32 2304, i32 2401, i32 2500, i32 2601, i32 2704, i32 2809, i32 2970, i32 3025, i32 3136, i32 3249, i32 3364, i32 3481, i32 3600, i32 3721, i32 3844, i32 3969, i32 4096, i32 4225, i32 4356, i32 4489, i32 4624, i32 4761, i32 4900, i32 5112, i32 5184, i32 5329, i32 5476, i32 5625, i32 5776, i32 5929, i32 6084, i32 6241, i32 6400, i32 6561, i32 6724, i32 6889, i32 7056, i32 7225, i32 7396, i32 7569, i32 7744, i32 7921, i32 8100, i32 8281, i32 8464, i32 8649, i32 8836, i32 9025, i32 9216, i32 9409, i32 9604, i32 9801, i32 10000, i32 10201, i32 10404, i32 10609, i32 10816, i32 11025, i32 11236, i32 11449, i32 11664, i32 11881, i32 12100, i32 12321, i32 12544, i32 12769, i32 12996, i32 13225, i32 13456, i32 13689, i32 13924, i32 14161, i32 14400, i32 14641, i32 14884, i32 15129, i32 15376, i32 15625, i32 15876, i32 16129, i32 16384, i32 16641, i32 16900, i32 17161, i32 17424, i32 17689, i32 17956, i32 18225, i32 18496, i32 18769, i32 19044, i32 19321, i32 19600, i32 19881, i32 20164, i32 20449, i32 20736, i32 21025, i32 21316, i32 21609, i32 21904, i32 22201, i32 22500, i32 22801, i32 23104, i32 23409, i32 23716, i32 24025, i32 24336, i32 24649, i32 24964, i32 25281, i32 25600, i32 25921, i32 26244, i32 26569, i32 26896, i32 27225, i32 27556, i32 27889, i32 28224, i32 28561, i32 28900, i32 29241, i32 29584, i32 29929, i32 30276, i32 30625, i32 30976, i32 31329, i32 31684, i32 32041, i32 32400, i32 32761, i32 33124, i32 33489, i32 33856, i32 34225, i32 34596, i32 34969, i32 35344, i32 35721, i32 36100, i32 36481, i32 36864, i32 37249, i32 37636, i32 38025, i32 38416, i32 38809, i32 39204, i32 39601], align 4 33; CHECK: @switch.table.cprop = private unnamed_addr constant [7 x i32] [i32 5, i32 42, i32 126, i32 -452, i32 128, i32 6, i32 7], align 4 34; CHECK: @switch.table.unreachable_case = private unnamed_addr constant [9 x i32] [i32 0, i32 0, i32 0, i32 2, i32 -1, i32 1, i32 1, i32 1, i32 1], align 4 35; CHECK: @switch.table.unreachable_default = private unnamed_addr constant [4 x i32] [i32 42, i32 52, i32 1, i32 2], align 4 36; CHECK: @switch.table.nodefaultnoholes = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1], align 4 37; CHECK: @switch.table.nodefaultwithholes = private unnamed_addr constant [6 x i32] [i32 55, i32 123, i32 0, i32 -1, i32 poison, i32 -1], align 4 38; CHECK: @switch.table.threecases = private unnamed_addr constant [3 x i32] [i32 10, i32 7, i32 5], align 4 39; CHECK: @switch.table.covered_switch_with_bit_tests = private unnamed_addr constant [8 x i32] [i32 2, i32 2, i32 poison, i32 poison, i32 poison, i32 poison, i32 1, i32 1], align 4 40; CHECK: @switch.table.signed_overflow1 = private unnamed_addr constant [4 x i32] [i32 3333, i32 4444, i32 1111, i32 2222], align 4 41; CHECK: @switch.table.signed_overflow2 = private unnamed_addr constant [4 x i32] [i32 3333, i32 4444, i32 poison, i32 2222], align 4 42; CHECK: @switch.table.constant_hole_unreachable_default_firstundef = private unnamed_addr constant [5 x i32] [i32 undef, i32 poison, i32 1, i32 1, i32 1], align 4 43; CHECK: @switch.table.constant_hole_unreachable_default_lastundef = private unnamed_addr constant [5 x i32] [i32 1, i32 poison, i32 1, i32 1, i32 undef], align 4 44; CHECK: @switch.table.linearmap_hole_unreachable_default = private unnamed_addr constant [5 x i32] [i32 1, i32 poison, i32 5, i32 7, i32 9], align 4 45;. 46define i32 @f(i32 %c) { 47; CHECK-LABEL: @f( 48; CHECK-NEXT: entry: 49; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 50; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 51; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] 52; CHECK: switch.lookup: 53; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.f, i32 0, i32 [[SWITCH_TABLEIDX]] 54; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 55; CHECK-NEXT: br label [[RETURN]] 56; CHECK: return: 57; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ] 58; CHECK-NEXT: ret i32 [[RETVAL_0]] 59; 60entry: 61 switch i32 %c, label %sw.default [ 62 i32 42, label %return 63 i32 43, label %sw.bb1 64 i32 44, label %sw.bb2 65 i32 45, label %sw.bb3 66 i32 46, label %sw.bb4 67 i32 47, label %sw.bb5 68 i32 48, label %sw.bb6 69 ] 70 71sw.bb1: br label %return 72sw.bb2: br label %return 73sw.bb3: br label %return 74sw.bb4: br label %return 75sw.bb5: br label %return 76sw.bb6: br label %return 77sw.default: br label %return 78return: 79 %retval.0 = phi i32 [ 15, %sw.default ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] 80 ret i32 %retval.0 81 82} 83 84; Same thing, but with i8's 85 86define i8 @char(i32 %c) { 87; CHECK-LABEL: @char( 88; CHECK-NEXT: entry: 89; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 90; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 9 91; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] 92; CHECK: switch.lookup: 93; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i8], ptr @switch.table.char, i32 0, i32 [[SWITCH_TABLEIDX]] 94; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1 95; CHECK-NEXT: br label [[RETURN]] 96; CHECK: return: 97; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ] 98; CHECK-NEXT: ret i8 [[RETVAL_0]] 99; 100entry: 101 switch i32 %c, label %sw.default [ 102 i32 42, label %return 103 i32 43, label %sw.bb1 104 i32 44, label %sw.bb2 105 i32 45, label %sw.bb3 106 i32 46, label %sw.bb4 107 i32 47, label %sw.bb5 108 i32 48, label %sw.bb6 109 i32 49, label %sw.bb7 110 i32 50, label %sw.bb8 111 ] 112 113sw.bb1: br label %return 114sw.bb2: br label %return 115sw.bb3: br label %return 116sw.bb4: br label %return 117sw.bb5: br label %return 118sw.bb6: br label %return 119sw.bb7: br label %return 120sw.bb8: br label %return 121sw.default: br label %return 122return: 123 %retval.0 = phi i8 [ 15, %sw.default ], [ 84, %sw.bb8 ], [ 33, %sw.bb7 ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] 124 ret i8 %retval.0 125 126} 127 128; A switch used to initialize two variables, an i8 and a float. 129 130declare void @dummy(i8 signext, float) 131define void @h(i32 %x) { 132; CHECK-LABEL: @h( 133; CHECK-NEXT: entry: 134; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 135; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]] 136; CHECK: switch.lookup: 137; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i32 [[X]], 8 138; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 89655594, [[SWITCH_SHIFTAMT]] 139; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8 140; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], ptr @switch.table.h, i32 0, i32 [[X]] 141; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load float, ptr [[SWITCH_GEP]], align 4 142; CHECK-NEXT: br label [[SW_EPILOG]] 143; CHECK: sw.epilog: 144; CHECK-NEXT: [[A_0:%.*]] = phi i8 [ [[SWITCH_MASKED]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ] 145; CHECK-NEXT: [[B_0:%.*]] = phi float [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 0x4023FAE140000000, [[ENTRY]] ] 146; CHECK-NEXT: call void @dummy(i8 signext [[A_0]], float [[B_0]]) 147; CHECK-NEXT: ret void 148; 149entry: 150 switch i32 %x, label %sw.default [ 151 i32 0, label %sw.epilog 152 i32 1, label %sw.bb1 153 i32 2, label %sw.bb2 154 i32 3, label %sw.bb3 155 ] 156 157sw.bb1: br label %sw.epilog 158sw.bb2: br label %sw.epilog 159sw.bb3: br label %sw.epilog 160sw.default: br label %sw.epilog 161 162sw.epilog: 163 %a.0 = phi i8 [ 7, %sw.default ], [ 5, %sw.bb3 ], [ 88, %sw.bb2 ], [ 9, %sw.bb1 ], [ 42, %entry ] 164 %b.0 = phi float [ 0x4023FAE140000000, %sw.default ], [ 0x4001AE1480000000, %sw.bb3 ], [ 0x4012449BA0000000, %sw.bb2 ], [ 0x3FF3BE76C0000000, %sw.bb1 ], [ 0x40091EB860000000, %entry ] 165 call void @dummy(i8 signext %a.0, float %b.0) 166 ret void 167 168} 169 170 171; Switch used to return a string. 172 173@.str = private unnamed_addr constant [4 x i8] c"foo\00", align 1 174@.str1 = private unnamed_addr constant [4 x i8] c"bar\00", align 1 175@.str2 = private unnamed_addr constant [4 x i8] c"baz\00", align 1 176@.str3 = private unnamed_addr constant [4 x i8] c"qux\00", align 1 177@.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1 178 179define ptr @foostring(i32 %x) { 180; CHECK-LABEL: @foostring( 181; CHECK-NEXT: entry: 182; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 183; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] 184; CHECK: switch.lookup: 185; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x ptr], ptr @switch.table.foostring, i32 0, i32 [[X]] 186; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load ptr, ptr [[SWITCH_GEP]], align 8 187; CHECK-NEXT: br label [[RETURN]] 188; CHECK: return: 189; CHECK-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ @.str4, [[ENTRY:%.*]] ] 190; CHECK-NEXT: ret ptr [[RETVAL_0]] 191; 192entry: 193 switch i32 %x, label %sw.default [ 194 i32 0, label %return 195 i32 1, label %sw.bb1 196 i32 2, label %sw.bb2 197 i32 3, label %sw.bb3 198 ] 199 200sw.bb1: br label %return 201sw.bb2: br label %return 202sw.bb3: br label %return 203sw.default: br label %return 204 205return: 206 %retval.0 = phi ptr [ @.str4, %sw.default ], 207 [ @.str3, %sw.bb3 ], 208 [ @.str2, %sw.bb2 ], 209 [ @.str1, %sw.bb1 ], 210 [ @.str, %entry ] 211 ret ptr %retval.0 212 213} 214 215; Switch used to initialize two values. The first value is returned, the second 216; value is not used. This used to make the transformation generate illegal code. 217 218define i32 @earlyreturncrash(i32 %x) { 219; CHECK-LABEL: @earlyreturncrash( 220; CHECK-NEXT: entry: 221; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 222; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]] 223; CHECK: switch.lookup: 224; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.earlyreturncrash, i32 0, i32 [[X]] 225; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 226; CHECK-NEXT: [[SWITCH_GEP1:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.earlyreturncrash.1, i32 0, i32 [[X]] 227; CHECK-NEXT: [[SWITCH_LOAD2:%.*]] = load i32, ptr [[SWITCH_GEP1]], align 4 228; CHECK-NEXT: br label [[SW_EPILOG]] 229; CHECK: sw.epilog: 230; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ] 231; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ [[SWITCH_LOAD2]], [[SWITCH_LOOKUP]] ], [ 10, [[ENTRY]] ] 232; CHECK-NEXT: ret i32 [[A_0]] 233; 234entry: 235 switch i32 %x, label %sw.default [ 236 i32 0, label %sw.epilog 237 i32 1, label %sw.bb1 238 i32 2, label %sw.bb2 239 i32 3, label %sw.bb3 240 ] 241 242sw.bb1: br label %sw.epilog 243sw.bb2: br label %sw.epilog 244sw.bb3: br label %sw.epilog 245sw.default: br label %sw.epilog 246 247sw.epilog: 248 %a.0 = phi i32 [ 7, %sw.default ], [ 5, %sw.bb3 ], [ 88, %sw.bb2 ], [ 9, %sw.bb1 ], [ 42, %entry ] 249 %b.0 = phi i32 [ 10, %sw.default ], [ 5, %sw.bb3 ], [ 1, %sw.bb2 ], [ 4, %sw.bb1 ], [ 3, %entry ] 250 ret i32 %a.0 251 252} 253 254 255; Example 7 from http://blog.regehr.org/archives/320 256; It is not dense enough for a regular table, but the results 257; can be packed into a bitmap. 258 259define i32 @crud(i8 zeroext %c) { 260; CHECK-LABEL: @crud( 261; CHECK-NEXT: entry: 262; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33 263; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]] 264; CHECK: switch.early.test: 265; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C]], 34 266; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 59 267; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[LOR_END]] 268; CHECK: switch.lookup: 269; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i8 [[SWITCH_TABLEIDX]] to i59 270; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i59 [[SWITCH_CAST]], 1 271; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i59 -288230375765830623, [[SWITCH_SHIFTAMT]] 272; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i59 [[SWITCH_DOWNSHIFT]] to i1 273; CHECK-NEXT: br label [[LOR_END]] 274; CHECK: lor.end: 275; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[SWITCH_MASKED]], [[SWITCH_LOOKUP]] ], [ false, [[SWITCH_EARLY_TEST]] ] 276; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP1]] to i32 277; CHECK-NEXT: ret i32 [[LOR_EXT]] 278; 279entry: 280 %cmp = icmp ult i8 %c, 33 281 br i1 %cmp, label %lor.end, label %switch.early.test 282 283switch.early.test: 284 switch i8 %c, label %lor.rhs [ 285 i8 92, label %lor.end 286 i8 62, label %lor.end 287 i8 60, label %lor.end 288 i8 59, label %lor.end 289 i8 58, label %lor.end 290 i8 46, label %lor.end 291 i8 44, label %lor.end 292 i8 34, label %lor.end 293 i8 39, label %switch.edge 294 ] 295 296switch.edge: br label %lor.end 297lor.rhs: br label %lor.end 298 299lor.end: 300 %0 = phi i1 [ true, %switch.early.test ], 301 [ false, %lor.rhs ], 302 [ true, %entry ], 303 [ true, %switch.early.test ], 304 [ true, %switch.early.test ], 305 [ true, %switch.early.test ], 306 [ true, %switch.early.test ], 307 [ true, %switch.early.test ], 308 [ true, %switch.early.test ], 309 [ true, %switch.early.test ], 310 [ true, %switch.edge ] 311 %lor.ext = zext i1 %0 to i32 312 ret i32 %lor.ext 313 314} 315 316; PR13946 317define i32 @overflow(i32 %type) { 318; CHECK-LABEL: @overflow( 319; CHECK-NEXT: entry: 320; CHECK-NEXT: switch i32 [[TYPE:%.*]], label [[SW_DEFAULT:%.*]] [ 321; CHECK-NEXT: i32 3, label [[SW_BB3:%.*]] 322; CHECK-NEXT: i32 -2147483645, label [[SW_BB3]] 323; CHECK-NEXT: i32 1, label [[IF_END:%.*]] 324; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]] 325; CHECK-NEXT: ] 326; CHECK: sw.bb2: 327; CHECK-NEXT: br label [[IF_END]] 328; CHECK: sw.bb3: 329; CHECK-NEXT: br label [[IF_END]] 330; CHECK: sw.default: 331; CHECK-NEXT: br label [[IF_END]] 332; CHECK: if.end: 333; CHECK-NEXT: [[DIRENT_TYPE_0:%.*]] = phi i32 [ 3, [[SW_DEFAULT]] ], [ 6, [[SW_BB3]] ], [ 5, [[SW_BB2]] ], [ 0, [[ENTRY:%.*]] ] 334; CHECK-NEXT: ret i32 [[DIRENT_TYPE_0]] 335; 336entry: 337 switch i32 %type, label %sw.default [ 338 i32 -2147483648, label %sw.bb 339 i32 0, label %sw.bb 340 i32 1, label %sw.bb1 341 i32 2, label %sw.bb2 342 i32 -2147483645, label %sw.bb3 343 i32 3, label %sw.bb3 344 ] 345 346sw.bb: ; preds = %entry, %entry 347 br label %if.end 348 349sw.bb1: ; preds = %entry 350 br label %if.end 351 352sw.bb2: ; preds = %entry 353 br label %if.end 354 355sw.bb3: ; preds = %entry, %entry 356 br label %if.end 357 358sw.default: ; preds = %entry 359 br label %if.end 360 361if.end: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb 362 %dirent_type.0 = phi i32 [ 3, %sw.default ], [ 6, %sw.bb3 ], [ 5, %sw.bb2 ], [ 0, %sw.bb1 ], [ 3, %sw.bb ] 363 ret i32 %dirent_type.0 364} 365 366; PR13985 367define i1 @undef(i32 %tmp) { 368; CHECK-LABEL: @undef( 369; CHECK-NEXT: bb: 370; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[TMP:%.*]], 9 371; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[TMP]] to i9 372; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i9 [[SWITCH_CAST]], 1 373; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i9 3, [[SWITCH_SHIFTAMT]] 374; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i9 [[SWITCH_DOWNSHIFT]] to i1 375; CHECK-NEXT: [[_TMP4:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 undef 376; CHECK-NEXT: ret i1 [[_TMP4]] 377; 378bb: 379 switch i32 %tmp, label %bb3 [ 380 i32 0, label %bb1 381 i32 1, label %bb1 382 i32 7, label %bb2 383 i32 8, label %bb2 384 ] 385 386bb1: br label %bb3 387bb2: br label %bb3 388 389bb3: 390 %_tmp4 = phi i1 [ undef, %bb ], [ false, %bb2 ], [ true, %bb1 ] 391 ret i1 %_tmp4 392} 393 394; Also handle large switches that would be rejected by 395; isValueEqualityComparison() 396 397define i32 @large(i32 %x) { 398; CHECK-LABEL: @large( 399; CHECK-NEXT: entry: 400; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 401; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X]], -10 402; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 [[MUL]], i32 [[X]] 403; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[SPEC_SELECT]], 1 404; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 199 405; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] 406; CHECK: switch.lookup: 407; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [199 x i32], ptr @switch.table.large, i32 0, i32 [[SWITCH_TABLEIDX]] 408; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 409; CHECK-NEXT: br label [[RETURN]] 410; CHECK: return: 411; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ] 412; CHECK-NEXT: ret i32 [[RETVAL_0]] 413; 414entry: 415 %cmp = icmp slt i32 %x, 0 416 br i1 %cmp, label %if.then, label %if.end 417 418if.then: 419 %mul = mul i32 %x, -10 420 br label %if.end 421 422if.end: 423 %x.addr.0 = phi i32 [ %mul, %if.then ], [ %x, %entry ] 424 switch i32 %x.addr.0, label %return [ 425 i32 199, label %sw.bb203 426 i32 1, label %sw.bb1 427 i32 2, label %sw.bb2 428 i32 3, label %sw.bb3 429 i32 4, label %sw.bb4 430 i32 5, label %sw.bb5 431 i32 6, label %sw.bb6 432 i32 7, label %sw.bb7 433 i32 8, label %sw.bb8 434 i32 9, label %sw.bb9 435 i32 10, label %sw.bb10 436 i32 11, label %sw.bb11 437 i32 12, label %sw.bb12 438 i32 13, label %sw.bb13 439 i32 14, label %sw.bb14 440 i32 15, label %sw.bb15 441 i32 16, label %sw.bb16 442 i32 17, label %sw.bb17 443 i32 18, label %sw.bb18 444 i32 19, label %sw.bb19 445 i32 20, label %sw.bb20 446 i32 21, label %sw.bb21 447 i32 22, label %sw.bb22 448 i32 23, label %sw.bb23 449 i32 24, label %sw.bb24 450 i32 25, label %sw.bb25 451 i32 26, label %sw.bb26 452 i32 27, label %sw.bb27 453 i32 28, label %sw.bb28 454 i32 29, label %sw.bb29 455 i32 30, label %sw.bb30 456 i32 31, label %sw.bb31 457 i32 32, label %sw.bb32 458 i32 33, label %sw.bb33 459 i32 34, label %sw.bb34 460 i32 35, label %sw.bb35 461 i32 36, label %sw.bb37 462 i32 37, label %sw.bb38 463 i32 38, label %sw.bb39 464 i32 39, label %sw.bb40 465 i32 40, label %sw.bb41 466 i32 41, label %sw.bb42 467 i32 42, label %sw.bb43 468 i32 43, label %sw.bb44 469 i32 44, label %sw.bb45 470 i32 45, label %sw.bb47 471 i32 46, label %sw.bb48 472 i32 47, label %sw.bb49 473 i32 48, label %sw.bb50 474 i32 49, label %sw.bb51 475 i32 50, label %sw.bb52 476 i32 51, label %sw.bb53 477 i32 52, label %sw.bb54 478 i32 53, label %sw.bb55 479 i32 54, label %sw.bb56 480 i32 55, label %sw.bb58 481 i32 56, label %sw.bb59 482 i32 57, label %sw.bb60 483 i32 58, label %sw.bb61 484 i32 59, label %sw.bb62 485 i32 60, label %sw.bb63 486 i32 61, label %sw.bb64 487 i32 62, label %sw.bb65 488 i32 63, label %sw.bb66 489 i32 64, label %sw.bb67 490 i32 65, label %sw.bb68 491 i32 66, label %sw.bb69 492 i32 67, label %sw.bb70 493 i32 68, label %sw.bb71 494 i32 69, label %sw.bb72 495 i32 70, label %sw.bb73 496 i32 71, label %sw.bb74 497 i32 72, label %sw.bb76 498 i32 73, label %sw.bb77 499 i32 74, label %sw.bb78 500 i32 75, label %sw.bb79 501 i32 76, label %sw.bb80 502 i32 77, label %sw.bb81 503 i32 78, label %sw.bb82 504 i32 79, label %sw.bb83 505 i32 80, label %sw.bb84 506 i32 81, label %sw.bb85 507 i32 82, label %sw.bb86 508 i32 83, label %sw.bb87 509 i32 84, label %sw.bb88 510 i32 85, label %sw.bb89 511 i32 86, label %sw.bb90 512 i32 87, label %sw.bb91 513 i32 88, label %sw.bb92 514 i32 89, label %sw.bb93 515 i32 90, label %sw.bb94 516 i32 91, label %sw.bb95 517 i32 92, label %sw.bb96 518 i32 93, label %sw.bb97 519 i32 94, label %sw.bb98 520 i32 95, label %sw.bb99 521 i32 96, label %sw.bb100 522 i32 97, label %sw.bb101 523 i32 98, label %sw.bb102 524 i32 99, label %sw.bb103 525 i32 100, label %sw.bb104 526 i32 101, label %sw.bb105 527 i32 102, label %sw.bb106 528 i32 103, label %sw.bb107 529 i32 104, label %sw.bb108 530 i32 105, label %sw.bb109 531 i32 106, label %sw.bb110 532 i32 107, label %sw.bb111 533 i32 108, label %sw.bb112 534 i32 109, label %sw.bb113 535 i32 110, label %sw.bb114 536 i32 111, label %sw.bb115 537 i32 112, label %sw.bb116 538 i32 113, label %sw.bb117 539 i32 114, label %sw.bb118 540 i32 115, label %sw.bb119 541 i32 116, label %sw.bb120 542 i32 117, label %sw.bb121 543 i32 118, label %sw.bb122 544 i32 119, label %sw.bb123 545 i32 120, label %sw.bb124 546 i32 121, label %sw.bb125 547 i32 122, label %sw.bb126 548 i32 123, label %sw.bb127 549 i32 124, label %sw.bb128 550 i32 125, label %sw.bb129 551 i32 126, label %sw.bb130 552 i32 127, label %sw.bb131 553 i32 128, label %sw.bb132 554 i32 129, label %sw.bb133 555 i32 130, label %sw.bb134 556 i32 131, label %sw.bb135 557 i32 132, label %sw.bb136 558 i32 133, label %sw.bb137 559 i32 134, label %sw.bb138 560 i32 135, label %sw.bb139 561 i32 136, label %sw.bb140 562 i32 137, label %sw.bb141 563 i32 138, label %sw.bb142 564 i32 139, label %sw.bb143 565 i32 140, label %sw.bb144 566 i32 141, label %sw.bb145 567 i32 142, label %sw.bb146 568 i32 143, label %sw.bb147 569 i32 144, label %sw.bb148 570 i32 145, label %sw.bb149 571 i32 146, label %sw.bb150 572 i32 147, label %sw.bb151 573 i32 148, label %sw.bb152 574 i32 149, label %sw.bb153 575 i32 150, label %sw.bb154 576 i32 151, label %sw.bb155 577 i32 152, label %sw.bb156 578 i32 153, label %sw.bb157 579 i32 154, label %sw.bb158 580 i32 155, label %sw.bb159 581 i32 156, label %sw.bb160 582 i32 157, label %sw.bb161 583 i32 158, label %sw.bb162 584 i32 159, label %sw.bb163 585 i32 160, label %sw.bb164 586 i32 161, label %sw.bb165 587 i32 162, label %sw.bb166 588 i32 163, label %sw.bb167 589 i32 164, label %sw.bb168 590 i32 165, label %sw.bb169 591 i32 166, label %sw.bb170 592 i32 167, label %sw.bb171 593 i32 168, label %sw.bb172 594 i32 169, label %sw.bb173 595 i32 170, label %sw.bb174 596 i32 171, label %sw.bb175 597 i32 172, label %sw.bb176 598 i32 173, label %sw.bb177 599 i32 174, label %sw.bb178 600 i32 175, label %sw.bb179 601 i32 176, label %sw.bb180 602 i32 177, label %sw.bb181 603 i32 178, label %sw.bb182 604 i32 179, label %sw.bb183 605 i32 180, label %sw.bb184 606 i32 181, label %sw.bb185 607 i32 182, label %sw.bb186 608 i32 183, label %sw.bb187 609 i32 184, label %sw.bb188 610 i32 185, label %sw.bb189 611 i32 186, label %sw.bb190 612 i32 187, label %sw.bb191 613 i32 188, label %sw.bb192 614 i32 189, label %sw.bb193 615 i32 190, label %sw.bb194 616 i32 191, label %sw.bb195 617 i32 192, label %sw.bb196 618 i32 193, label %sw.bb197 619 i32 194, label %sw.bb198 620 i32 195, label %sw.bb199 621 i32 196, label %sw.bb200 622 i32 197, label %sw.bb201 623 i32 198, label %sw.bb202 624 ] 625 626sw.bb1: br label %return 627sw.bb2: br label %return 628sw.bb3: br label %return 629sw.bb4: br label %return 630sw.bb5: br label %return 631sw.bb6: br label %return 632sw.bb7: br label %return 633sw.bb8: br label %return 634sw.bb9: br label %return 635sw.bb10: br label %return 636sw.bb11: br label %return 637sw.bb12: br label %return 638sw.bb13: br label %return 639sw.bb14: br label %return 640sw.bb15: br label %return 641sw.bb16: br label %return 642sw.bb17: br label %return 643sw.bb18: br label %return 644sw.bb19: br label %return 645sw.bb20: br label %return 646sw.bb21: br label %return 647sw.bb22: br label %return 648sw.bb23: br label %return 649sw.bb24: br label %return 650sw.bb25: br label %return 651sw.bb26: br label %return 652sw.bb27: br label %return 653sw.bb28: br label %return 654sw.bb29: br label %return 655sw.bb30: br label %return 656sw.bb31: br label %return 657sw.bb32: br label %return 658sw.bb33: br label %return 659sw.bb34: br label %return 660sw.bb35: br label %return 661sw.bb37: br label %return 662sw.bb38: br label %return 663sw.bb39: br label %return 664sw.bb40: br label %return 665sw.bb41: br label %return 666sw.bb42: br label %return 667sw.bb43: br label %return 668sw.bb44: br label %return 669sw.bb45: br label %return 670sw.bb47: br label %return 671sw.bb48: br label %return 672sw.bb49: br label %return 673sw.bb50: br label %return 674sw.bb51: br label %return 675sw.bb52: br label %return 676sw.bb53: br label %return 677sw.bb54: br label %return 678sw.bb55: br label %return 679sw.bb56: br label %return 680sw.bb58: br label %return 681sw.bb59: br label %return 682sw.bb60: br label %return 683sw.bb61: br label %return 684sw.bb62: br label %return 685sw.bb63: br label %return 686sw.bb64: br label %return 687sw.bb65: br label %return 688sw.bb66: br label %return 689sw.bb67: br label %return 690sw.bb68: br label %return 691sw.bb69: br label %return 692sw.bb70: br label %return 693sw.bb71: br label %return 694sw.bb72: br label %return 695sw.bb73: br label %return 696sw.bb74: br label %return 697sw.bb76: br label %return 698sw.bb77: br label %return 699sw.bb78: br label %return 700sw.bb79: br label %return 701sw.bb80: br label %return 702sw.bb81: br label %return 703sw.bb82: br label %return 704sw.bb83: br label %return 705sw.bb84: br label %return 706sw.bb85: br label %return 707sw.bb86: br label %return 708sw.bb87: br label %return 709sw.bb88: br label %return 710sw.bb89: br label %return 711sw.bb90: br label %return 712sw.bb91: br label %return 713sw.bb92: br label %return 714sw.bb93: br label %return 715sw.bb94: br label %return 716sw.bb95: br label %return 717sw.bb96: br label %return 718sw.bb97: br label %return 719sw.bb98: br label %return 720sw.bb99: br label %return 721sw.bb100: br label %return 722sw.bb101: br label %return 723sw.bb102: br label %return 724sw.bb103: br label %return 725sw.bb104: br label %return 726sw.bb105: br label %return 727sw.bb106: br label %return 728sw.bb107: br label %return 729sw.bb108: br label %return 730sw.bb109: br label %return 731sw.bb110: br label %return 732sw.bb111: br label %return 733sw.bb112: br label %return 734sw.bb113: br label %return 735sw.bb114: br label %return 736sw.bb115: br label %return 737sw.bb116: br label %return 738sw.bb117: br label %return 739sw.bb118: br label %return 740sw.bb119: br label %return 741sw.bb120: br label %return 742sw.bb121: br label %return 743sw.bb122: br label %return 744sw.bb123: br label %return 745sw.bb124: br label %return 746sw.bb125: br label %return 747sw.bb126: br label %return 748sw.bb127: br label %return 749sw.bb128: br label %return 750sw.bb129: br label %return 751sw.bb130: br label %return 752sw.bb131: br label %return 753sw.bb132: br label %return 754sw.bb133: br label %return 755sw.bb134: br label %return 756sw.bb135: br label %return 757sw.bb136: br label %return 758sw.bb137: br label %return 759sw.bb138: br label %return 760sw.bb139: br label %return 761sw.bb140: br label %return 762sw.bb141: br label %return 763sw.bb142: br label %return 764sw.bb143: br label %return 765sw.bb144: br label %return 766sw.bb145: br label %return 767sw.bb146: br label %return 768sw.bb147: br label %return 769sw.bb148: br label %return 770sw.bb149: br label %return 771sw.bb150: br label %return 772sw.bb151: br label %return 773sw.bb152: br label %return 774sw.bb153: br label %return 775sw.bb154: br label %return 776sw.bb155: br label %return 777sw.bb156: br label %return 778sw.bb157: br label %return 779sw.bb158: br label %return 780sw.bb159: br label %return 781sw.bb160: br label %return 782sw.bb161: br label %return 783sw.bb162: br label %return 784sw.bb163: br label %return 785sw.bb164: br label %return 786sw.bb165: br label %return 787sw.bb166: br label %return 788sw.bb167: br label %return 789sw.bb168: br label %return 790sw.bb169: br label %return 791sw.bb170: br label %return 792sw.bb171: br label %return 793sw.bb172: br label %return 794sw.bb173: br label %return 795sw.bb174: br label %return 796sw.bb175: br label %return 797sw.bb176: br label %return 798sw.bb177: br label %return 799sw.bb178: br label %return 800sw.bb179: br label %return 801sw.bb180: br label %return 802sw.bb181: br label %return 803sw.bb182: br label %return 804sw.bb183: br label %return 805sw.bb184: br label %return 806sw.bb185: br label %return 807sw.bb186: br label %return 808sw.bb187: br label %return 809sw.bb188: br label %return 810sw.bb189: br label %return 811sw.bb190: br label %return 812sw.bb191: br label %return 813sw.bb192: br label %return 814sw.bb193: br label %return 815sw.bb194: br label %return 816sw.bb195: br label %return 817sw.bb196: br label %return 818sw.bb197: br label %return 819sw.bb198: br label %return 820sw.bb199: br label %return 821sw.bb200: br label %return 822sw.bb201: br label %return 823sw.bb202: br label %return 824sw.bb203: br label %return 825 826return: 827 %retval.0 = phi i32 [ 39204, %sw.bb202 ], [ 38809, %sw.bb201 ], [ 38416, %sw.bb200 ], [ 38025, %sw.bb199 ], [ 37636, %sw.bb198 ], [ 37249, %sw.bb197 ], [ 36864, %sw.bb196 ], [ 36481, %sw.bb195 ], [ 36100, %sw.bb194 ], [ 35721, %sw.bb193 ], [ 35344, %sw.bb192 ], [ 34969, %sw.bb191 ], [ 34596, %sw.bb190 ], [ 34225, %sw.bb189 ], [ 33856, %sw.bb188 ], [ 33489, %sw.bb187 ], [ 33124, %sw.bb186 ], [ 32761, %sw.bb185 ], [ 32400, %sw.bb184 ], [ 32041, %sw.bb183 ], [ 31684, %sw.bb182 ], [ 31329, %sw.bb181 ], [ 30976, %sw.bb180 ], [ 30625, %sw.bb179 ], [ 30276, %sw.bb178 ], [ 29929, %sw.bb177 ], [ 29584, %sw.bb176 ], [ 29241, %sw.bb175 ], [ 28900, %sw.bb174 ], [ 28561, %sw.bb173 ], [ 28224, %sw.bb172 ], [ 27889, %sw.bb171 ], [ 27556, %sw.bb170 ], [ 27225, %sw.bb169 ], [ 26896, %sw.bb168 ], [ 26569, %sw.bb167 ], [ 26244, %sw.bb166 ], [ 25921, %sw.bb165 ], [ 25600, %sw.bb164 ], [ 25281, %sw.bb163 ], [ 24964, %sw.bb162 ], [ 24649, %sw.bb161 ], [ 24336, %sw.bb160 ], [ 24025, %sw.bb159 ], [ 23716, %sw.bb158 ], [ 23409, %sw.bb157 ], [ 23104, %sw.bb156 ], [ 22801, %sw.bb155 ], [ 22500, %sw.bb154 ], [ 22201, %sw.bb153 ], [ 21904, %sw.bb152 ], [ 21609, %sw.bb151 ], [ 21316, %sw.bb150 ], [ 21025, %sw.bb149 ], [ 20736, %sw.bb148 ], [ 20449, %sw.bb147 ], [ 20164, %sw.bb146 ], [ 19881, %sw.bb145 ], [ 19600, %sw.bb144 ], [ 19321, %sw.bb143 ], [ 19044, %sw.bb142 ], [ 18769, %sw.bb141 ], [ 18496, %sw.bb140 ], [ 18225, %sw.bb139 ], [ 17956, %sw.bb138 ], [ 17689, %sw.bb137 ], [ 17424, %sw.bb136 ], [ 17161, %sw.bb135 ], [ 16900, %sw.bb134 ], [ 16641, %sw.bb133 ], [ 16384, %sw.bb132 ], [ 16129, %sw.bb131 ], [ 15876, %sw.bb130 ], [ 15625, %sw.bb129 ], [ 15376, %sw.bb128 ], [ 15129, %sw.bb127 ], [ 14884, %sw.bb126 ], [ 14641, %sw.bb125 ], [ 14400, %sw.bb124 ], [ 14161, %sw.bb123 ], [ 13924, %sw.bb122 ], [ 13689, %sw.bb121 ], [ 13456, %sw.bb120 ], [ 13225, %sw.bb119 ], [ 12996, %sw.bb118 ], [ 12769, %sw.bb117 ], [ 12544, %sw.bb116 ], [ 12321, %sw.bb115 ], [ 12100, %sw.bb114 ], [ 11881, %sw.bb113 ], [ 11664, %sw.bb112 ], [ 11449, %sw.bb111 ], [ 11236, %sw.bb110 ], [ 11025, %sw.bb109 ], [ 10816, %sw.bb108 ], [ 10609, %sw.bb107 ], [ 10404, %sw.bb106 ], [ 10201, %sw.bb105 ], [ 10000, %sw.bb104 ], [ 9801, %sw.bb103 ], [ 9604, %sw.bb102 ], [ 9409, %sw.bb101 ], [ 9216, %sw.bb100 ], [ 9025, %sw.bb99 ], [ 8836, %sw.bb98 ], [ 8649, %sw.bb97 ], [ 8464, %sw.bb96 ], [ 8281, %sw.bb95 ], [ 8100, %sw.bb94 ], [ 7921, %sw.bb93 ], [ 7744, %sw.bb92 ], [ 7569, %sw.bb91 ], [ 7396, %sw.bb90 ], [ 7225, %sw.bb89 ], [ 7056, %sw.bb88 ], [ 6889, %sw.bb87 ], [ 6724, %sw.bb86 ], [ 6561, %sw.bb85 ], [ 6400, %sw.bb84 ], [ 6241, %sw.bb83 ], [ 6084, %sw.bb82 ], [ 5929, %sw.bb81 ], [ 5776, %sw.bb80 ], [ 5625, %sw.bb79 ], [ 5476, %sw.bb78 ], [ 5329, %sw.bb77 ], [ 5184, %sw.bb76 ], [ 5112, %sw.bb74 ], [ 4900, %sw.bb73 ], [ 4761, %sw.bb72 ], [ 4624, %sw.bb71 ], [ 4489, %sw.bb70 ], [ 4356, %sw.bb69 ], [ 4225, %sw.bb68 ], [ 4096, %sw.bb67 ], [ 3969, %sw.bb66 ], [ 3844, %sw.bb65 ], [ 3721, %sw.bb64 ], [ 3600, %sw.bb63 ], [ 3481, %sw.bb62 ], [ 3364, %sw.bb61 ], [ 3249, %sw.bb60 ], [ 3136, %sw.bb59 ], [ 3025, %sw.bb58 ], [ 2970, %sw.bb56 ], [ 2809, %sw.bb55 ], [ 2704, %sw.bb54 ], [ 2601, %sw.bb53 ], [ 2500, %sw.bb52 ], [ 2401, %sw.bb51 ], [ 2304, %sw.bb50 ], [ 2209, %sw.bb49 ], [ 2116, %sw.bb48 ], [ 2025, %sw.bb47 ], [ 1980, %sw.bb45 ], [ 1849, %sw.bb44 ], [ 1764, %sw.bb43 ], [ 1681, %sw.bb42 ], [ 1600, %sw.bb41 ], [ 1521, %sw.bb40 ], [ 1444, %sw.bb39 ], [ 1369, %sw.bb38 ], [ 1296, %sw.bb37 ], [ 1260, %sw.bb35 ], [ 1156, %sw.bb34 ], [ 1089, %sw.bb33 ], [ 1024, %sw.bb32 ], [ 961, %sw.bb31 ], [ 900, %sw.bb30 ], [ 841, %sw.bb29 ], [ 784, %sw.bb28 ], [ 729, %sw.bb27 ], [ 676, %sw.bb26 ], [ 625, %sw.bb25 ], [ 576, %sw.bb24 ], [ 529, %sw.bb23 ], [ 484, %sw.bb22 ], [ 441, %sw.bb21 ], [ 400, %sw.bb20 ], [ 361, %sw.bb19 ], [ 342, %sw.bb18 ], [ 289, %sw.bb17 ], [ 256, %sw.bb16 ], [ 225, %sw.bb15 ], [ 196, %sw.bb14 ], [ 169, %sw.bb13 ], [ 144, %sw.bb12 ], [ 121, %sw.bb11 ], [ 100, %sw.bb10 ], [ 81, %sw.bb9 ], [ 64, %sw.bb8 ], [ 49, %sw.bb7 ], [ 36, %sw.bb6 ], [ 25, %sw.bb5 ], [ 16, %sw.bb4 ], [ 9, %sw.bb3 ], [ 4, %sw.bb2 ], [ 1, %sw.bb1 ], [ 39601, %sw.bb203 ], [ 0, %if.end ] 828 ret i32 %retval.0 829} 830 831define i32 @cprop(i32 %x, i32 %y) { 832; CHECK-LABEL: @cprop( 833; CHECK-NEXT: entry: 834; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[X:%.*]], 1 835; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 836; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] 837; CHECK: switch.lookup: 838; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.cprop, i32 0, i32 [[SWITCH_TABLEIDX]] 839; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 840; CHECK-NEXT: br label [[RETURN]] 841; CHECK: return: 842; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 123, [[ENTRY:%.*]] ] 843; CHECK-NEXT: ret i32 [[RETVAL_0]] 844; 845entry: 846 switch i32 %x, label %sw.default [ 847 i32 1, label %return 848 i32 2, label %sw.bb1 849 i32 3, label %sw.bb2 850 i32 4, label %sw.bb2 851 i32 5, label %sw.bb2 852 i32 6, label %sw.bb3 853 i32 7, label %sw.bb3 854 ] 855 856sw.bb1: br label %return 857 858sw.bb2: 859 %and = and i32 %x, 1 860 %and.ptr = inttoptr i32 %and to ptr 861 %tobool = icmp ne ptr %and.ptr, null 862 %cond = select i1 %tobool, i32 -123, i32 456 863 %sub = sub nsw i32 %x, %cond 864 br label %return 865 866sw.bb3: 867 %trunc = trunc i32 %x to i8 868 %sext = sext i8 %trunc to i32 869 %select.i = icmp sgt i32 %sext, 0 870 %select = select i1 %select.i, i32 %sext, i32 %y 871 br label %return 872 873sw.default: 874 br label %return 875 876return: 877 %retval.0 = phi i32 [ 123, %sw.default ], [ %select, %sw.bb3 ], [ %sub, %sw.bb2 ], [ 42, %sw.bb1 ], [ 5, %entry ] 878 ret i32 %retval.0 879 880} 881 882define i32 @unreachable_case(i32 %x) { 883; CHECK-LABEL: @unreachable_case( 884; CHECK-NEXT: entry: 885; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 9 886; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] 887; CHECK: switch.lookup: 888; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i32], ptr @switch.table.unreachable_case, i32 0, i32 [[X]] 889; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 890; CHECK-NEXT: br label [[RETURN]] 891; CHECK: return: 892; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 2, [[ENTRY:%.*]] ] 893; CHECK-NEXT: ret i32 [[RETVAL_0]] 894; 895entry: 896 switch i32 %x, label %sw.default [ 897 i32 0, label %sw.bb 898 i32 1, label %sw.bb 899 i32 2, label %sw.bb 900 i32 3, label %sw.bb1 901 i32 4, label %sw.bb2 902 i32 5, label %sw.bb3 903 i32 6, label %sw.bb3 904 i32 7, label %sw.bb3 905 i32 8, label %sw.bb3 906 ] 907 908sw.bb: br label %return 909sw.bb1: unreachable 910sw.bb2: br label %return 911sw.bb3: br label %return 912sw.default: br label %return 913 914return: 915 %retval.0 = phi i32 [ 1, %sw.bb3 ], [ -1, %sw.bb2 ], [ 0, %sw.bb ], [ 2, %sw.default ] 916 ret i32 %retval.0 917 918} 919 920define i32 @unreachable_default(i32 %x) { 921; CHECK-LABEL: @unreachable_default( 922; CHECK-NEXT: entry: 923; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.unreachable_default, i32 0, i32 [[X:%.*]] 924; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 925; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 926; 927entry: 928 switch i32 %x, label %default [ 929 i32 0, label %bb0 930 i32 1, label %bb1 931 i32 2, label %bb2 932 i32 3, label %bb3 933 ] 934 935bb0: br label %return 936bb1: br label %return 937bb2: br label %return 938bb3: br label %return 939default: unreachable 940 941return: 942 %retval = phi i32 [ 42, %bb0 ], [ 52, %bb1 ], [ 1, %bb2 ], [ 2, %bb3 ] 943 ret i32 %retval 944 945} 946 947; Don't create a table with illegal type 948define i96 @illegaltype(i32 %c) { 949; CHECK-LABEL: @illegaltype( 950; CHECK-NEXT: entry: 951; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [ 952; CHECK-NEXT: i32 42, label [[RETURN:%.*]] 953; CHECK-NEXT: i32 43, label [[SW_BB1:%.*]] 954; CHECK-NEXT: i32 44, label [[SW_BB2:%.*]] 955; CHECK-NEXT: i32 45, label [[SW_BB3:%.*]] 956; CHECK-NEXT: i32 46, label [[SW_BB4:%.*]] 957; CHECK-NEXT: ] 958; CHECK: sw.bb1: 959; CHECK-NEXT: br label [[RETURN]] 960; CHECK: sw.bb2: 961; CHECK-NEXT: br label [[RETURN]] 962; CHECK: sw.bb3: 963; CHECK-NEXT: br label [[RETURN]] 964; CHECK: sw.bb4: 965; CHECK-NEXT: br label [[RETURN]] 966; CHECK: sw.default: 967; CHECK-NEXT: br label [[RETURN]] 968; CHECK: return: 969; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i96 [ 15, [[SW_DEFAULT]] ], [ 27, [[SW_BB4]] ], [ -1, [[SW_BB3]] ], [ 0, [[SW_BB2]] ], [ 123, [[SW_BB1]] ], [ 55, [[ENTRY:%.*]] ] 970; CHECK-NEXT: ret i96 [[RETVAL_0]] 971; 972entry: 973 switch i32 %c, label %sw.default [ 974 i32 42, label %return 975 i32 43, label %sw.bb1 976 i32 44, label %sw.bb2 977 i32 45, label %sw.bb3 978 i32 46, label %sw.bb4 979 ] 980 981sw.bb1: br label %return 982sw.bb2: br label %return 983sw.bb3: br label %return 984sw.bb4: br label %return 985sw.default: br label %return 986return: 987 %retval.0 = phi i96 [ 15, %sw.default ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] 988 ret i96 %retval.0 989 990} 991 992; If we can build a lookup table without any holes, we don't need a default result. 993declare void @exit(i32) 994define i32 @nodefaultnoholes(i32 %c) { 995; CHECK-LABEL: @nodefaultnoholes( 996; CHECK-NEXT: entry: 997; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[C:%.*]], 4 998; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_DEFAULT:%.*]] 999; CHECK: sw.default: 1000; CHECK-NEXT: call void @exit(i32 1) 1001; CHECK-NEXT: unreachable 1002; CHECK: switch.lookup: 1003; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.nodefaultnoholes, i32 0, i32 [[C]] 1004; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 1005; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 1006; 1007entry: 1008 switch i32 %c, label %sw.default [ 1009 i32 0, label %return 1010 i32 1, label %sw.bb1 1011 i32 2, label %sw.bb2 1012 i32 3, label %sw.bb3 1013 ] 1014 1015sw.bb1: br label %return 1016sw.bb2: br label %return 1017sw.bb3: br label %return 1018sw.default: call void @exit(i32 1) 1019 unreachable 1020return: 1021 %x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] 1022 ret i32 %x 1023 1024} 1025 1026; This lookup table will have holes, so we need to test for the holes. 1027define i32 @nodefaultwithholes(i32 %c) { 1028; CHECK-LABEL: @nodefaultwithholes( 1029; CHECK-NEXT: entry: 1030; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[C:%.*]], 6 1031; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_HOLE_CHECK:%.*]], label [[SW_DEFAULT:%.*]] 1032; CHECK: sw.default: 1033; CHECK-NEXT: call void @exit(i32 1) 1034; CHECK-NEXT: unreachable 1035; CHECK: switch.hole_check: 1036; CHECK-NEXT: [[SWITCH_MASKINDEX:%.*]] = trunc i32 [[C]] to i8 1037; CHECK-NEXT: [[SWITCH_SHIFTED:%.*]] = lshr i8 47, [[SWITCH_MASKINDEX]] 1038; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = trunc i8 [[SWITCH_SHIFTED]] to i1 1039; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[SW_DEFAULT]] 1040; CHECK: switch.lookup: 1041; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [6 x i32], ptr @switch.table.nodefaultwithholes, i32 0, i32 [[C]] 1042; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 1043; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 1044; 1045entry: 1046 switch i32 %c, label %sw.default [ 1047 i32 0, label %return 1048 i32 1, label %sw.bb1 1049 i32 2, label %sw.bb2 1050 i32 3, label %sw.bb3 1051 i32 5, label %sw.bb3 1052 ] 1053 1054sw.bb1: br label %return 1055sw.bb2: br label %return 1056sw.bb3: br label %return 1057sw.default: call void @exit(i32 1) 1058 unreachable 1059return: 1060 %x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] 1061 ret i32 %x 1062 1063; The mask is binary 101111. 1064} 1065 1066; We don't build lookup tables with holes for switches with less than four cases. 1067define i32 @threecasesholes(i32 %c) { 1068; CHECK-LABEL: @threecasesholes( 1069; CHECK-NEXT: entry: 1070; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [ 1071; CHECK-NEXT: i32 0, label [[RETURN:%.*]] 1072; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]] 1073; CHECK-NEXT: i32 3, label [[SW_BB2:%.*]] 1074; CHECK-NEXT: ] 1075; CHECK: sw.bb1: 1076; CHECK-NEXT: br label [[RETURN]] 1077; CHECK: sw.bb2: 1078; CHECK-NEXT: br label [[RETURN]] 1079; CHECK: sw.default: 1080; CHECK-NEXT: br label [[RETURN]] 1081; CHECK: return: 1082; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[C]], [[SW_DEFAULT]] ], [ 5, [[SW_BB2]] ], [ 7, [[SW_BB1]] ], [ 9, [[ENTRY:%.*]] ] 1083; CHECK-NEXT: ret i32 [[X]] 1084; 1085entry: 1086 switch i32 %c, label %sw.default [ 1087 i32 0, label %return 1088 i32 1, label %sw.bb1 1089 i32 3, label %sw.bb2 1090 ] 1091sw.bb1: br label %return 1092sw.bb2: br label %return 1093sw.default: br label %return 1094return: 1095 %x = phi i32 [ %c, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 9, %entry ] 1096 ret i32 %x 1097} 1098 1099; We build lookup tables for switches with three or more cases. 1100define i32 @threecases(i32 %c) { 1101; CHECK-LABEL: @threecases( 1102; CHECK-NEXT: entry: 1103; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[C:%.*]], 3 1104; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] 1105; CHECK: switch.lookup: 1106; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32], ptr @switch.table.threecases, i32 0, i32 [[C]] 1107; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 1108; CHECK-NEXT: br label [[RETURN]] 1109; CHECK: return: 1110; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 3, [[ENTRY:%.*]] ] 1111; CHECK-NEXT: ret i32 [[X]] 1112; 1113entry: 1114 switch i32 %c, label %sw.default [ 1115 i32 0, label %return 1116 i32 1, label %sw.bb1 1117 i32 2, label %sw.bb2 1118 ] 1119sw.bb1: 1120 br label %return 1121sw.bb2: 1122 br label %return 1123sw.default: 1124 br label %return 1125return: 1126 %x = phi i32 [ 3, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 10, %entry ] 1127 ret i32 %x 1128} 1129 1130; We don't build tables for switches with two cases. 1131define i32 @twocases(i32 %c) { 1132; CHECK-LABEL: @twocases( 1133; CHECK-NEXT: entry: 1134; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[C:%.*]], 1 1135; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 7, i32 3 1136; CHECK-NEXT: [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[C]], 0 1137; CHECK-NEXT: [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i32 9, i32 [[SWITCH_SELECT]] 1138; CHECK-NEXT: ret i32 [[SWITCH_SELECT2]] 1139; 1140entry: 1141 switch i32 %c, label %sw.default [ 1142 i32 0, label %return 1143 i32 1, label %sw.bb1 1144 ] 1145sw.bb1: 1146 br label %return 1147sw.default: 1148 br label %return 1149return: 1150 %x = phi i32 [ 3, %sw.default ], [ 7, %sw.bb1 ], [ 9, %entry ] 1151 ret i32 %x 1152} 1153 1154; Don't build tables for switches with TLS variables. 1155@tls_a = thread_local global i32 0 1156@tls_b = thread_local global i32 0 1157@tls_c = thread_local global i32 0 1158@tls_d = thread_local global i32 0 1159define ptr @tls(i32 %x) { 1160; CHECK-LABEL: @tls( 1161; CHECK-NEXT: entry: 1162; CHECK-NEXT: switch i32 [[X:%.*]], label [[SW_DEFAULT:%.*]] [ 1163; CHECK-NEXT: i32 0, label [[RETURN:%.*]] 1164; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]] 1165; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]] 1166; CHECK-NEXT: ] 1167; CHECK: sw.bb1: 1168; CHECK-NEXT: br label [[RETURN]] 1169; CHECK: sw.bb2: 1170; CHECK-NEXT: br label [[RETURN]] 1171; CHECK: sw.default: 1172; CHECK-NEXT: br label [[RETURN]] 1173; CHECK: return: 1174; CHECK-NEXT: [[RETVAL_0:%.*]] = phi ptr [ @tls_d, [[SW_DEFAULT]] ], [ @tls_c, [[SW_BB2]] ], [ @tls_b, [[SW_BB1]] ], [ @tls_a, [[ENTRY:%.*]] ] 1175; CHECK-NEXT: ret ptr [[RETVAL_0]] 1176; 1177entry: 1178 switch i32 %x, label %sw.default [ 1179 i32 0, label %return 1180 i32 1, label %sw.bb1 1181 i32 2, label %sw.bb2 1182 ] 1183sw.bb1: 1184 br label %return 1185sw.bb2: 1186 br label %return 1187sw.default: 1188 br label %return 1189return: 1190 %retval.0 = phi ptr [ @tls_d, %sw.default ], [ @tls_c, %sw.bb2 ], [ @tls_b, %sw.bb1 ], [ @tls_a, %entry ] 1191 ret ptr %retval.0 1192} 1193 1194; Don't build tables for switches with dllimport variables. 1195@dllimport_a = external dllimport global [3x i32] 1196@dllimport_b = external dllimport global [3x i32] 1197@dllimport_c = external dllimport global [3x i32] 1198@dllimport_d = external dllimport global [3x i32] 1199define ptr @dllimport(i32 %x) { 1200; CHECK-LABEL: @dllimport( 1201; CHECK-NEXT: entry: 1202; CHECK-NEXT: switch i32 [[X:%.*]], label [[SW_DEFAULT:%.*]] [ 1203; CHECK-NEXT: i32 0, label [[RETURN:%.*]] 1204; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]] 1205; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]] 1206; CHECK-NEXT: ] 1207; CHECK: sw.bb1: 1208; CHECK-NEXT: br label [[RETURN]] 1209; CHECK: sw.bb2: 1210; CHECK-NEXT: br label [[RETURN]] 1211; CHECK: sw.default: 1212; CHECK-NEXT: br label [[RETURN]] 1213; CHECK: return: 1214; CHECK-NEXT: [[RETVAL_0:%.*]] = phi ptr [ @dllimport_d, [[SW_DEFAULT]] ], [ @dllimport_c, [[SW_BB2]] ], [ @dllimport_b, [[SW_BB1]] ], [ @dllimport_a, [[ENTRY:%.*]] ] 1215; CHECK-NEXT: ret ptr [[RETVAL_0]] 1216; 1217entry: 1218 switch i32 %x, label %sw.default [ 1219 i32 0, label %return 1220 i32 1, label %sw.bb1 1221 i32 2, label %sw.bb2 1222 ] 1223sw.bb1: 1224 br label %return 1225sw.bb2: 1226 br label %return 1227sw.default: 1228 br label %return 1229return: 1230 %retval.0 = phi ptr [ @dllimport_d, %sw.default ], 1231 [ @dllimport_c, %sw.bb2 ], 1232 [ @dllimport_b, %sw.bb1 ], 1233 [ @dllimport_a, %entry ] 1234 ret ptr %retval.0 1235} 1236 1237; We can use linear mapping. 1238define i8 @linearmap1(i32 %c) { 1239; CHECK-LABEL: @linearmap1( 1240; CHECK-NEXT: entry: 1241; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 1242; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 1243; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 1244; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i8 [[SWITCH_IDX_CAST]], -5 1245; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i8 [[SWITCH_IDX_MULT]], 18 1246; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_OFFSET]], i8 3 1247; CHECK-NEXT: ret i8 [[X]] 1248; 1249entry: 1250 switch i32 %c, label %sw.default [ 1251 i32 10, label %return 1252 i32 11, label %sw.bb1 1253 i32 12, label %sw.bb2 1254 i32 13, label %sw.bb3 1255 ] 1256sw.bb1: br label %return 1257sw.bb2: br label %return 1258sw.bb3: br label %return 1259sw.default: br label %return 1260return: 1261 %x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 8, %sw.bb2 ], [ 13, %sw.bb1 ], [ 18, %entry ] 1262 ret i8 %x 1263} 1264 1265; Linear mapping in a different configuration. 1266define i32 @linearmap2(i8 %c) { 1267; CHECK-LABEL: @linearmap2( 1268; CHECK-NEXT: entry: 1269; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C:%.*]], -13 1270; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 4 1271; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i8 [[SWITCH_TABLEIDX]] to i32 1272; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_CAST]], 18 1273; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 3 1274; CHECK-NEXT: ret i32 [[X]] 1275; 1276entry: 1277 switch i8 %c, label %sw.default [ 1278 i8 -10, label %return 1279 i8 -11, label %sw.bb1 1280 i8 -12, label %sw.bb2 1281 i8 -13, label %sw.bb3 1282 ] 1283sw.bb1: br label %return 1284sw.bb2: br label %return 1285sw.bb3: br label %return 1286sw.default: br label %return 1287return: 1288 %x = phi i32 [ 3, %sw.default ], [ 18, %sw.bb3 ], [ 19, %sw.bb2 ], [ 20, %sw.bb1 ], [ 21, %entry ] 1289 ret i32 %x 1290} 1291 1292; Linear mapping with overflows. 1293define i8 @linearmap3(i32 %c) { 1294; CHECK-LABEL: @linearmap3( 1295; CHECK-NEXT: entry: 1296; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 1297; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 1298; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 1299; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], 100 1300; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_IDX_MULT]], i8 3 1301; CHECK-NEXT: ret i8 [[X]] 1302; 1303entry: 1304 switch i32 %c, label %sw.default [ 1305 i32 10, label %return 1306 i32 11, label %sw.bb1 1307 i32 12, label %sw.bb2 1308 i32 13, label %sw.bb3 1309 ] 1310sw.bb1: br label %return 1311sw.bb2: br label %return 1312sw.bb3: br label %return 1313sw.default: br label %return 1314return: 1315 %x = phi i8 [ 3, %sw.default ], [ 44, %sw.bb3 ], [ -56, %sw.bb2 ], [ 100, %sw.bb1 ], [ 0, %entry ] 1316 ret i8 %x 1317} 1318 1319; Linear mapping with with multiplier 1 and offset 0. 1320define i8 @linearmap4(i32 %c) { 1321; CHECK-LABEL: @linearmap4( 1322; CHECK-NEXT: entry: 1323; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], -2 1324; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 1325; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 1326; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_IDX_CAST]], i8 3 1327; CHECK-NEXT: ret i8 [[X]] 1328; 1329entry: 1330 switch i32 %c, label %sw.default [ 1331 i32 -2, label %return 1332 i32 -1, label %sw.bb1 1333 i32 0, label %sw.bb2 1334 i32 1, label %sw.bb3 1335 ] 1336sw.bb1: br label %return 1337sw.bb2: br label %return 1338sw.bb3: br label %return 1339sw.default: br label %return 1340return: 1341 %x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %entry ] 1342 ret i8 %x 1343} 1344 1345; Reuse the inverted table range compare. 1346define i32 @reuse_cmp1(i32 %x) { 1347; CHECK-LABEL: @reuse_cmp1( 1348; CHECK-NEXT: entry: 1349; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 1350; CHECK-NEXT: [[INVERTED_CMP:%.*]] = xor i1 [[TMP0]], true 1351; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[X]], 10 1352; CHECK-NEXT: [[R_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 1353; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0 1354; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[INVERTED_CMP]], i32 100, i32 [[R_0]] 1355; CHECK-NEXT: ret i32 [[RETVAL_0]] 1356; 1357entry: 1358 switch i32 %x, label %sw.default [ 1359 i32 0, label %sw.bb 1360 i32 1, label %sw.bb1 1361 i32 2, label %sw.bb2 1362 i32 3, label %sw.bb3 1363 ] 1364sw.bb: br label %sw.epilog 1365sw.bb1: br label %sw.epilog 1366sw.bb2: br label %sw.epilog 1367sw.bb3: br label %sw.epilog 1368sw.default: br label %sw.epilog 1369sw.epilog: 1370 %r.0 = phi i32 [ 0, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ] 1371 %cmp = icmp eq i32 %r.0, 0 ; This compare can be "replaced". 1372 br i1 %cmp, label %if.then, label %if.end 1373if.then: br label %return 1374if.end: br label %return 1375return: 1376 %retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ] 1377 ret i32 %retval.0 1378} 1379 1380; Reuse the table range compare. 1381define i32 @reuse_cmp2(i32 %x) { 1382; CHECK-LABEL: @reuse_cmp2( 1383; CHECK-NEXT: entry: 1384; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 1385; CHECK-NEXT: [[X_:%.*]] = select i1 [[TMP0]], i32 [[X]], i32 4 1386; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X_]], 4 1387; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP0]], i32 [[X_]], i32 100 1388; CHECK-NEXT: ret i32 [[RETVAL_0]] 1389; 1390entry: 1391 switch i32 %x, label %sw.default [ 1392 i32 0, label %sw.bb 1393 i32 1, label %sw.bb1 1394 i32 2, label %sw.bb2 1395 i32 3, label %sw.bb3 1396 ] 1397sw.bb: br label %sw.epilog 1398sw.bb1: br label %sw.epilog 1399sw.bb2: br label %sw.epilog 1400sw.bb3: br label %sw.epilog 1401sw.default: br label %sw.epilog 1402sw.epilog: 1403 %r.0 = phi i32 [ 4, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %sw.bb ] 1404 %cmp = icmp ne i32 %r.0, 4 ; This compare can be "replaced". 1405 br i1 %cmp, label %if.then, label %if.end 1406if.then: br label %return 1407if.end: br label %return 1408return: 1409 %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ] 1410 ret i32 %retval.0 1411} 1412 1413; Cannot reuse the table range compare, because the default value is the same 1414; as one of the case values. 1415define i32 @no_reuse_cmp(i32 %x) { 1416; CHECK-LABEL: @no_reuse_cmp( 1417; CHECK-NEXT: entry: 1418; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 1419; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[X]], 10 1420; CHECK-NEXT: [[R_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 12 1421; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[R_0]], 0 1422; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i32 [[R_0]], i32 100 1423; CHECK-NEXT: ret i32 [[RETVAL_0]] 1424; 1425entry: 1426 switch i32 %x, label %sw.default [ 1427 i32 0, label %sw.bb 1428 i32 1, label %sw.bb1 1429 i32 2, label %sw.bb2 1430 i32 3, label %sw.bb3 1431 ] 1432sw.bb: br label %sw.epilog 1433sw.bb1: br label %sw.epilog 1434sw.bb2: br label %sw.epilog 1435sw.bb3: br label %sw.epilog 1436sw.default: br label %sw.epilog 1437sw.epilog: 1438 %r.0 = phi i32 [ 12, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ] 1439 %cmp = icmp ne i32 %r.0, 0 1440 br i1 %cmp, label %if.then, label %if.end 1441if.then: br label %return 1442if.end: br label %return 1443return: 1444 %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ] 1445 ret i32 %retval.0 1446} 1447 1448; Cannot reuse the table range compare, because the phi at the switch merge 1449; point is not dominated by the switch. 1450define i32 @no_reuse_cmp2(i32 %x, i32 %y) { 1451; CHECK-LABEL: @no_reuse_cmp2( 1452; CHECK-NEXT: entry: 1453; CHECK-NEXT: [[EC:%.*]] = icmp ne i32 [[Y:%.*]], 0 1454; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 1455; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[X]], 10 1456; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 1457; CHECK-NEXT: [[R_0:%.*]] = select i1 [[EC]], i32 [[SPEC_SELECT]], i32 100 1458; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0 1459; CHECK-NEXT: [[DOTR_0:%.*]] = select i1 [[CMP]], i32 100, i32 [[R_0]] 1460; CHECK-NEXT: ret i32 [[DOTR_0]] 1461; 1462entry: 1463 %ec = icmp ne i32 %y, 0 1464 br i1 %ec, label %switch.entry, label %sw.epilog 1465switch.entry: 1466 switch i32 %x, label %sw.default [ 1467 i32 0, label %sw.bb 1468 i32 1, label %sw.bb1 1469 i32 2, label %sw.bb2 1470 i32 3, label %sw.bb3 1471 ] 1472sw.bb: br label %sw.epilog 1473sw.bb1: br label %sw.epilog 1474sw.bb2: br label %sw.epilog 1475sw.bb3: br label %sw.epilog 1476sw.default: br label %sw.epilog 1477sw.epilog: 1478 %r.0 = phi i32 [100, %entry], [ 0, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ] 1479 %cmp = icmp eq i32 %r.0, 0 ; This compare can be "replaced". 1480 br i1 %cmp, label %if.then, label %if.end 1481if.then: br label %return 1482if.end: br label %return 1483return: 1484 %retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ] 1485 ret i32 %retval.0 1486} 1487 1488define void @pr20210(i8 %x, i1 %y) { 1489; %z has uses outside of its BB or the phi it feeds into, 1490; so doing a table lookup and jumping directly to while.cond would 1491; cause %z to cease dominating all its uses. 1492; CHECK-LABEL: @pr20210( 1493; CHECK-NEXT: entry: 1494; CHECK-NEXT: br i1 [[Y:%.*]], label [[SW:%.*]], label [[INTERMEDIATE:%.*]] 1495; CHECK: sw: 1496; CHECK-NEXT: switch i8 [[X:%.*]], label [[END:%.*]] [ 1497; CHECK-NEXT: i8 7, label [[INTERMEDIATE]] 1498; CHECK-NEXT: i8 3, label [[INTERMEDIATE]] 1499; CHECK-NEXT: i8 2, label [[INTERMEDIATE]] 1500; CHECK-NEXT: i8 1, label [[INTERMEDIATE]] 1501; CHECK-NEXT: i8 0, label [[INTERMEDIATE]] 1502; CHECK-NEXT: ] 1503; CHECK: intermediate: 1504; CHECK-NEXT: [[Z:%.*]] = zext i8 [[X]] to i32 1505; CHECK-NEXT: br label [[WHILE_COND:%.*]] 1506; CHECK: while.cond: 1507; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[Z]], [[INTERMEDIATE]] ], [ [[J:%.*]], [[WHILE_BODY:%.*]] ] 1508; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[I]], 7 1509; CHECK-NEXT: br i1 [[B]], label [[WHILE_BODY]], label [[WHILE_END:%.*]] 1510; CHECK: while.body: 1511; CHECK-NEXT: [[J]] = add i32 [[I]], 1 1512; CHECK-NEXT: br label [[WHILE_COND]] 1513; CHECK: while.end: 1514; CHECK-NEXT: call void @exit(i32 [[Z]]) 1515; CHECK-NEXT: unreachable 1516; CHECK: end: 1517; CHECK-NEXT: ret void 1518; 1519entry: 1520 br i1 %y, label %sw, label %intermediate 1521 1522sw: 1523 switch i8 %x, label %end [ 1524 i8 7, label %intermediate 1525 i8 3, label %intermediate 1526 i8 2, label %intermediate 1527 i8 1, label %intermediate 1528 i8 0, label %intermediate 1529 ] 1530 1531intermediate: 1532 %z = zext i8 %x to i32 1533 br label %while.cond 1534 1535while.cond: 1536 %i = phi i32 [ %z, %intermediate ], [ %j, %while.body ] 1537 %b = icmp ne i32 %i, 7 1538 br i1 %b, label %while.body, label %while.end 1539 1540while.body: 1541 %j = add i32 %i, 1 1542 br label %while.cond 1543 1544while.end: 1545 call void @exit(i32 %z) 1546 unreachable 1547 1548end: 1549 ret void 1550} 1551 1552; Make sure we do not crash due to trying to generate an unguarded 1553; lookup (since i3 can only hold values in the range of explicit 1554; values) and simultaneously trying to generate a branch to deal with 1555; the fact that we have holes in the range. 1556define i32 @covered_switch_with_bit_tests(i3) { 1557; CHECK-LABEL: @covered_switch_with_bit_tests( 1558; CHECK-NEXT: entry: 1559; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TMP0:%.*]], -4 1560; CHECK-NEXT: [[SWITCH_MASKINDEX:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i8 1561; CHECK-NEXT: [[SWITCH_SHIFTED:%.*]] = lshr i8 -61, [[SWITCH_MASKINDEX]] 1562; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = trunc i8 [[SWITCH_SHIFTED]] to i1 1563; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[L6:%.*]] 1564; CHECK: switch.lookup: 1565; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i4 1566; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i32], ptr @switch.table.covered_switch_with_bit_tests, i32 0, i4 [[SWITCH_TABLEIDX_ZEXT]] 1567; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 1568; CHECK-NEXT: br label [[L6]] 1569; CHECK: l6: 1570; CHECK-NEXT: [[R:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ] 1571; CHECK-NEXT: ret i32 [[R]] 1572; 1573entry: 1574 switch i3 %0, label %l6 [ 1575 i3 -3, label %l5 1576 i3 -4, label %l5 1577 i3 3, label %l1 1578 i3 2, label %l1 1579 ] 1580 1581l1: br label %l2 1582 1583l2: 1584 %x = phi i32 [ 1, %l1 ], [ 2, %l5 ] 1585 br label %l6 1586 1587l5: br label %l2 1588 1589l6: 1590 %r = phi i32 [ %x, %l2 ], [ 0, %entry ] 1591 ret i32 %r 1592} 1593 1594; Speculation depth must be limited to avoid a zero-cost instruction cycle. 1595 1596define i32 @PR26308(i1 %B, i64 %load) { 1597; CHECK-LABEL: @PR26308( 1598; CHECK-NEXT: entry: 1599; CHECK-NEXT: br label [[CLEANUP4:%.*]] 1600; CHECK: cleanup4: 1601; CHECK-NEXT: br label [[CLEANUP4]] 1602; 1603entry: 1604 br label %while.body 1605 1606while.body: 1607 br label %cleanup 1608 1609cleanup: 1610 %cleanup.dest.slot.0 = phi i1 [ false, %while.body ] 1611 br i1 %cleanup.dest.slot.0, label %for.cond, label %cleanup4 1612 1613for.cond: 1614 %e.0 = phi ptr [ undef, %cleanup ], [ %incdec.ptr, %for.cond2 ] 1615 %pi = ptrtoint ptr %e.0 to i64 1616 %incdec.ptr = getelementptr inbounds i64, ptr %e.0, i64 1 1617 br label %for.cond2 1618 1619for.cond2: 1620 %storemerge = phi i64 [ %pi, %for.cond ], [ %load, %for.cond2 ] 1621 br i1 %B, label %for.cond2, label %for.cond 1622 1623cleanup4: 1624 br label %while.body 1625} 1626 1627declare void @throw(i1) 1628 1629define void @wineh_test(i64 %val) personality ptr @__CxxFrameHandler3 { 1630; CHECK-LABEL: @wineh_test( 1631; CHECK-NEXT: entry: 1632; CHECK-NEXT: invoke void @throw(i1 false) 1633; CHECK-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[CLEANUP1:%.*]] 1634; CHECK: unreachable: 1635; CHECK-NEXT: unreachable 1636; CHECK: cleanup1: 1637; CHECK-NEXT: [[CLEANUPPAD1:%.*]] = cleanuppad within none [] 1638; CHECK-NEXT: switch i64 [[VAL:%.*]], label [[CLEANUPDONE2:%.*]] [ 1639; CHECK-NEXT: i64 0, label [[CLEANUPDONE1:%.*]] 1640; CHECK-NEXT: i64 1, label [[CLEANUPDONE1]] 1641; CHECK-NEXT: i64 6, label [[CLEANUPDONE1]] 1642; CHECK-NEXT: ] 1643; CHECK: cleanupdone1: 1644; CHECK-NEXT: cleanupret from [[CLEANUPPAD1]] unwind label [[CLEANUP2:%.*]] 1645; CHECK: cleanupdone2: 1646; CHECK-NEXT: cleanupret from [[CLEANUPPAD1]] unwind label [[CLEANUP2]] 1647; CHECK: cleanup2: 1648; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[CLEANUPDONE1]] ], [ false, [[CLEANUPDONE2]] ] 1649; CHECK-NEXT: [[CLEANUPPAD2:%.*]] = cleanuppad within none [] 1650; CHECK-NEXT: call void @throw(i1 [[PHI]]) [ "funclet"(token [[CLEANUPPAD2]]) ] 1651; CHECK-NEXT: unreachable 1652; 1653entry: 1654 invoke void @throw(i1 false) 1655 to label %unreachable unwind label %cleanup1 1656 1657unreachable: 1658 unreachable 1659 1660cleanup1: 1661 %cleanuppad1 = cleanuppad within none [] 1662 switch i64 %val, label %cleanupdone2 [ 1663 i64 0, label %cleanupdone1 1664 i64 1, label %cleanupdone1 1665 i64 6, label %cleanupdone1 1666 ] 1667 1668cleanupdone1: 1669 cleanupret from %cleanuppad1 unwind label %cleanup2 1670 1671cleanupdone2: 1672 cleanupret from %cleanuppad1 unwind label %cleanup2 1673 1674cleanup2: 1675 %phi = phi i1 [ true, %cleanupdone1 ], [ false, %cleanupdone2 ] 1676 %cleanuppad2 = cleanuppad within none [] 1677 call void @throw(i1 %phi) [ "funclet"(token %cleanuppad2) ] 1678 unreachable 1679} 1680 1681declare i32 @__CxxFrameHandler3(...) 1682 1683define i1 @use_x_as_index(i32 %x) { 1684; CHECK-LABEL: @use_x_as_index( 1685; CHECK-NEXT: entry: 1686; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 9 1687; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[X]] to i9 1688; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i9 [[SWITCH_CAST]], 1 1689; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i9 -234, [[SWITCH_SHIFTAMT]] 1690; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i9 [[SWITCH_DOWNSHIFT]] to i1 1691; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 false 1692; CHECK-NEXT: ret i1 [[STOREMERGE]] 1693; 1694entry: 1695 switch i32 %x, label %sw.default [ 1696 i32 1, label %sw.bb 1697 i32 2, label %sw.bb 1698 i32 4, label %sw.bb 1699 i32 8, label %sw.bb 1700 ] 1701 1702sw.bb: 1703 br label %return 1704 1705sw.default: 1706 br label %return 1707 1708return: 1709 %storemerge = phi i1 [ true, %sw.bb ], [ false, %sw.default ] 1710 ret i1 %storemerge 1711} 1712 1713define i32 @signed_overflow1(i8 %n) { 1714; CHECK-LABEL: @signed_overflow1( 1715; CHECK-NEXT: start: 1716; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2 1717; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2 1718; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3 1719; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow1, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]] 1720; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 1721; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 1722; 1723start: 1724 %trunc = trunc i8 %n to i2 1725 switch i2 %trunc, label %bb1 [ 1726 i2 0, label %bb6 1727 i2 1, label %bb3 1728 i2 -2, label %bb4 1729 i2 -1, label %bb5 1730 ] 1731 1732bb1: ; preds = %start 1733 unreachable 1734 1735bb3: ; preds = %start 1736 br label %bb6 1737 1738bb4: ; preds = %start 1739 br label %bb6 1740 1741bb5: ; preds = %start 1742 br label %bb6 1743 1744bb6: ; preds = %start, %bb3, %bb4, %bb5 1745 %.sroa.0.0 = phi i32 [ 4444, %bb5 ], [ 3333, %bb4 ], [ 2222, %bb3 ], [ 1111, %start ] 1746 ret i32 %.sroa.0.0 1747} 1748 1749define i32 @signed_overflow2(i8 %n) { 1750; CHECK-LABEL: @signed_overflow2( 1751; CHECK-NEXT: start: 1752; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2 1753; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2 1754; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3 1755; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow2, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]] 1756; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 1757; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 1758; 1759start: 1760 %trunc = trunc i8 %n to i2 1761 switch i2 %trunc, label %bb1 [ 1762 i2 1, label %bb3 1763 i2 -2, label %bb4 1764 i2 -1, label %bb5 1765 ] 1766 1767bb1: ; preds = %start 1768 unreachable 1769 1770bb3: ; preds = %start 1771 br label %bb6 1772 1773bb4: ; preds = %start 1774 br label %bb6 1775 1776bb5: ; preds = %start 1777 br label %bb6 1778 1779bb6: ; preds = %start, %bb3, %bb4, %bb5 1780 %.sroa.0.0 = phi i32 [ 4444, %bb5 ], [ 3333, %bb4 ], [ 2222, %bb3 ] 1781 ret i32 %.sroa.0.0 1782} 1783 1784; This is the same as @signed_overflow2 except that the default case calls @exit(), so it 1785; isn't treated as unreachable 1786define i32 @signed_overflow3(i8 %n) { 1787; CHECK-LABEL: @signed_overflow3( 1788; CHECK-NEXT: start: 1789; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2 1790; CHECK-NEXT: switch i2 [[TRUNC]], label [[START_UNREACHABLEDEFAULT:%.*]] [ 1791; CHECK-NEXT: i2 1, label [[BB6:%.*]] 1792; CHECK-NEXT: i2 -2, label [[BB4:%.*]] 1793; CHECK-NEXT: i2 -1, label [[BB5:%.*]] 1794; CHECK-NEXT: i2 0, label [[BB1:%.*]] 1795; CHECK-NEXT: ] 1796; CHECK: start.unreachabledefault: 1797; CHECK-NEXT: unreachable 1798; CHECK: bb1: 1799; CHECK-NEXT: call void @exit(i32 1) 1800; CHECK-NEXT: unreachable 1801; CHECK: bb4: 1802; CHECK-NEXT: br label [[BB6]] 1803; CHECK: bb5: 1804; CHECK-NEXT: br label [[BB6]] 1805; CHECK: bb6: 1806; CHECK-NEXT: [[DOTSROA_0_0:%.*]] = phi i32 [ 4444, [[BB5]] ], [ 3333, [[BB4]] ], [ 2222, [[START:%.*]] ] 1807; CHECK-NEXT: ret i32 [[DOTSROA_0_0]] 1808; 1809start: 1810 %trunc = trunc i8 %n to i2 1811 switch i2 %trunc, label %bb1 [ 1812 i2 1, label %bb3 1813 i2 -2, label %bb4 1814 i2 -1, label %bb5 1815 ] 1816 1817bb1: ; preds = %start 1818 call void @exit(i32 1) 1819 unreachable 1820 1821bb3: ; preds = %start 1822 br label %bb6 1823 1824bb4: ; preds = %start 1825 br label %bb6 1826 1827bb5: ; preds = %start 1828 br label %bb6 1829 1830bb6: ; preds = %start, %bb3, %bb4, %bb5 1831 %.sroa.0.0 = phi i32 [ 4444, %bb5 ], [ 3333, %bb4 ], [ 2222, %bb3 ] 1832 ret i32 %.sroa.0.0 1833} 1834 1835define i32 @signed_overflow_negative(i8 %n) { 1836; CHECK-LABEL: @signed_overflow_negative( 1837; CHECK-NEXT: start: 1838; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2 1839; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2 1840; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i32 1841; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[SWITCH_IDX_CAST]], 1111 1842; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1111 1843; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]] 1844; 1845start: 1846 %trunc = trunc i8 %n to i2 1847 switch i2 %trunc, label %bb1 [ 1848 i2 0, label %bb6 1849 i2 1, label %bb3 1850 i2 -2, label %bb4 1851 i2 -1, label %bb5 1852 ] 1853 1854bb1: ; preds = %start 1855 unreachable 1856 1857bb3: ; preds = %start 1858 br label %bb6 1859 1860bb4: ; preds = %start 1861 br label %bb6 1862 1863bb5: ; preds = %start 1864 br label %bb6 1865 1866bb6: ; preds = %start, %bb3, %bb4, %bb5 1867 %.sroa.0.0 = phi i32 [ 2222, %bb5 ], [ 1111, %bb4 ], [ 4444, %bb3 ], [ 3333, %start ] 1868 ret i32 %.sroa.0.0 1869} 1870 1871; can attach nsw because of default's unreachability and case value type size 1872; is big enough to hold max signed value. 1873define i32 @nsw_on_index_sub(i8 %n) { 1874; CHECK-LABEL: @nsw_on_index_sub( 1875; CHECK-NEXT: start: 1876; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i3 1877; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nsw i3 [[TRUNC]], -2 1878; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i32 1879; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[SWITCH_IDX_CAST]], 1111 1880; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1111 1881; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]] 1882; 1883start: 1884 %trunc = trunc i8 %n to i3 1885 ; we can hold max(cases) - min(cases) = 0b001 - 0b110 = 0b011 1886 switch i3 %trunc, label %bb1 [ 1887 i3 0, label %bb6 ; 0b000 1888 i3 1, label %bb3 ; 0b001 1889 i3 -2, label %bb4; 0b110 1890 i3 -1, label %bb5; 0b111 1891 ] 1892 1893bb1: ; preds = %start 1894 unreachable 1895 1896bb3: ; preds = %start 1897 br label %bb6 1898 1899bb4: ; preds = %start 1900 br label %bb6 1901 1902bb5: ; preds = %start 1903 br label %bb6 1904 1905bb6: ; preds = %start, %bb3, %bb4, %bb5 1906 %.sroa.0.0 = phi i32 [ 2222, %bb5 ], [ 1111, %bb4 ], [ 4444, %bb3 ], [ 3333, %start ] 1907 ret i32 %.sroa.0.0 1908} 1909 1910; cannot attach nsw on tableidx subtraction 1911; because maximum index is greater than INT3_MAX = 3 1912define i32 @wrapped_on_index_sub(i8 %n) { 1913; CHECK-LABEL: @wrapped_on_index_sub( 1914; CHECK-NEXT: start: 1915; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i3 1916; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TRUNC]], -2 1917; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i3 [[SWITCH_TABLEIDX]], -3 1918; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i32 1919; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[SWITCH_IDX_CAST]], 1111 1920; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1111 1921; CHECK-NEXT: [[DOTSROA_0_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 1922; CHECK-NEXT: ret i32 [[DOTSROA_0_0]] 1923; 1924start: 1925 %trunc = trunc i8 %n to i3 1926 switch i3 %trunc, label %bb1 [ 1927 i3 0, label %bb6 1928 i3 1, label %bb3 1929 i3 2, label %bb7 1930 i3 -2, label %bb4 1931 i3 -1, label %bb5 1932 ] 1933 1934bb1: ; preds = %start 1935 br label %bb6 1936 1937bb3: ; preds = %start 1938 br label %bb6 1939 1940bb4: ; preds = %start 1941 br label %bb6 1942 1943bb5: ; preds = %start 1944 br label %bb6 1945 1946bb7: ; preds = %start 1947 br label %bb6 1948 1949bb6: ; preds = %start, %bb3, %bb4, %bb5 1950 %.sroa.0.0 = phi i32 [ 0, %bb1 ], [ 2222, %bb5 ], [ 1111, %bb4 ], [ 5555, %bb7 ], [ 4444, %bb3 ], [ 3333, %start ] 1951 ret i32 %.sroa.0.0 1952} 1953 1954 1955; cannot attach nsw on tableidx subtraction 1956; because default reachability shows overflow could happen. 1957define i32 @wrapped_on_index_sub_default(i8 %n) { 1958; CHECK-LABEL: @wrapped_on_index_sub_default( 1959; CHECK-NEXT: start: 1960; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i3 1961; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TRUNC]], -2 1962; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i3 [[SWITCH_TABLEIDX]], -4 1963; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i32 1964; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[SWITCH_IDX_CAST]], 1111 1965; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1111 1966; CHECK-NEXT: [[DOTSROA_0_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 1967; CHECK-NEXT: ret i32 [[DOTSROA_0_0]] 1968; 1969start: 1970 %trunc = trunc i8 %n to i3 1971 switch i3 %trunc, label %bb1 [ 1972 i3 0, label %bb6 1973 i3 1, label %bb3 1974 i3 -2, label %bb4 1975 i3 -1, label %bb5 1976 ] 1977 1978bb1: ; preds = %start 1979 br label %bb6 1980 1981bb3: ; preds = %start 1982 br label %bb6 1983 1984bb4: ; preds = %start 1985 br label %bb6 1986 1987bb5: ; preds = %start 1988 br label %bb6 1989 1990bb6: ; preds = %start, %bb3, %bb4, %bb5 1991 %.sroa.0.0 = phi i32 [ 0, %bb1 ], [ 2222, %bb5 ], [ 1111, %bb4 ], [ 4444, %bb3 ], [ 3333, %start ] 1992 ret i32 %.sroa.0.0 1993} 1994 1995define i8 @linearmap_inc_nsw(i32 %c) { 1996; CHECK-LABEL: @linearmap_inc_nsw( 1997; CHECK-NEXT: entry: 1998; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 1999; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 2000; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 2001; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i8 [[SWITCH_IDX_CAST]], 31 2002; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i8 [[SWITCH_IDX_MULT]], 31 2003; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_OFFSET]], i8 3 2004; CHECK-NEXT: ret i8 [[X]] 2005; 2006entry: 2007 switch i32 %c, label %sw.default [ 2008 i32 10, label %return 2009 i32 11, label %sw.bb1 2010 i32 12, label %sw.bb2 2011 i32 13, label %sw.bb3 2012 ] 2013sw.bb1: br label %return 2014sw.bb2: br label %return 2015sw.bb3: br label %return 2016sw.default: br label %return 2017return: 2018 %x = phi i8 [ 3, %sw.default ], [ 124, %sw.bb3 ], [ 93, %sw.bb2 ], [ 62, %sw.bb1 ], [ 31, %entry ] 2019 ret i8 %x 2020} 2021 2022define i8 @linearmap_inc_wrapped(i32 %c) { 2023; CHECK-LABEL: @linearmap_inc_wrapped( 2024; CHECK-NEXT: entry: 2025; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 2026; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 2027; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 2028; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], 32 2029; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i8 [[SWITCH_IDX_MULT]], 32 2030; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_OFFSET]], i8 3 2031; CHECK-NEXT: ret i8 [[X]] 2032; 2033entry: 2034 switch i32 %c, label %sw.default [ 2035 i32 10, label %return 2036 i32 11, label %sw.bb1 2037 i32 12, label %sw.bb2 2038 i32 13, label %sw.bb3 2039 ] 2040sw.bb1: br label %return 2041sw.bb2: br label %return 2042sw.bb3: br label %return 2043sw.default: br label %return 2044return: 2045 %x = phi i8 [ 3, %sw.default ], [ -128, %sw.bb3 ], [ 96, %sw.bb2 ], [ 64, %sw.bb1 ], [ 32, %entry ] 2046 ret i8 %x 2047} 2048 2049define i8 @linearmap_dec_nsw(i32 %c) { 2050; CHECK-LABEL: @linearmap_dec_nsw( 2051; CHECK-NEXT: entry: 2052; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 2053; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 2054; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 2055; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i8 [[SWITCH_IDX_CAST]], -32 2056; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i8 [[SWITCH_IDX_MULT]], -32 2057; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_OFFSET]], i8 3 2058; CHECK-NEXT: ret i8 [[X]] 2059; 2060entry: 2061 switch i32 %c, label %sw.default [ 2062 i32 10, label %return 2063 i32 11, label %sw.bb1 2064 i32 12, label %sw.bb2 2065 i32 13, label %sw.bb3 2066 ] 2067sw.bb1: br label %return 2068sw.bb2: br label %return 2069sw.bb3: br label %return 2070sw.default: br label %return 2071return: 2072 %x = phi i8 [ 3, %sw.default ], [ -128, %sw.bb3 ], [ -96, %sw.bb2 ], [ -64, %sw.bb1 ], [ -32, %entry ] 2073 ret i8 %x 2074} 2075 2076define i8 @linearmap_dec_wrapped(i32 %c) { 2077; CHECK-LABEL: @linearmap_dec_wrapped( 2078; CHECK-NEXT: entry: 2079; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 2080; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 2081; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 2082; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], -33 2083; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i8 [[SWITCH_IDX_MULT]], -33 2084; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_OFFSET]], i8 3 2085; CHECK-NEXT: ret i8 [[X]] 2086; 2087entry: 2088 switch i32 %c, label %sw.default [ 2089 i32 10, label %return 2090 i32 11, label %sw.bb1 2091 i32 12, label %sw.bb2 2092 i32 13, label %sw.bb3 2093 ] 2094sw.bb1: br label %return 2095sw.bb2: br label %return 2096sw.bb3: br label %return 2097sw.default: br label %return 2098return: 2099 %x = phi i8 [ 3, %sw.default ], [ 124, %sw.bb3 ], [ -99, %sw.bb2 ], [ -66, %sw.bb1 ], [ -33, %entry ] 2100 ret i8 %x 2101} 2102 2103define i8 @linearmap_dec_wrapped_mon(i3 %0) { 2104; CHECK-LABEL: @linearmap_dec_wrapped_mon( 2105; CHECK-NEXT: entry: 2106; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TMP0:%.*]], -2 2107; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i3 [[SWITCH_TABLEIDX]], -4 2108; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i3 [[SWITCH_TABLEIDX]], 2 2109; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i3 [[SWITCH_IDX_MULT]], -4 2110; CHECK-NEXT: [[COND:%.*]] = select i1 [[TMP1]], i3 [[SWITCH_OFFSET]], i3 2 2111; CHECK-NEXT: [[CONV:%.*]] = sext i3 [[COND]] to i8 2112; CHECK-NEXT: ret i8 [[CONV]] 2113; 2114entry: 2115 switch i3 %0, label %cond.end [ 2116 i3 -1, label %cond.false 2117 i3 -2, label %cond.false 2118 i3 1, label %cond.false 2119 i3 0, label %cond.false 2120 ] 2121 2122cond.false: ; preds = %entry, %entry, %entry, %entry 2123 %mul = shl nsw i3 %0, 1 2124 br label %cond.end 2125 2126cond.end: ; preds = %entry, %cond.false 2127 %cond = phi i3 [ %mul, %cond.false ], [ 2, %entry ] 2128 %conv = sext i3 %cond to i8 2129 ret i8 %conv 2130} 2131 2132define i1 @linearmap_trunc_smaller_table_size(i8 %arg) { 2133; CHECK-LABEL: @linearmap_trunc_smaller_table_size( 2134; CHECK-NEXT: entry: 2135; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[ARG:%.*]], 10 2136; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i8 [[ARG]] to i1 2137; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_IDX_CAST]], i1 false 2138; CHECK-NEXT: ret i1 [[SPEC_SELECT]] 2139; 2140entry: 2141 switch i8 %arg, label %exit [ 2142 i8 1, label %sw 2143 i8 3, label %sw 2144 i8 5, label %sw 2145 i8 7, label %sw 2146 i8 9, label %sw 2147 ] 2148 2149sw: 2150 br label %exit 2151 2152exit: 2153 %phi = phi i1 [ true, %sw ], [ false, %entry ] 2154 ret i1 %phi 2155} 2156 2157; Don't create a table with an unknown type 2158define { i8, i8 } @test_unknown_result_type(i8 %n) { 2159; CHECK-LABEL: @test_unknown_result_type( 2160; CHECK-NEXT: entry: 2161; CHECK-NEXT: switch i8 [[N:%.*]], label [[SW_DEFAULT:%.*]] [ 2162; CHECK-NEXT: i8 0, label [[RETURN:%.*]] 2163; CHECK-NEXT: i8 1, label [[RETURN]] 2164; CHECK-NEXT: i8 2, label [[RETURN]] 2165; CHECK-NEXT: ] 2166; CHECK: sw.default: 2167; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i8, i8 } undef, i8 0, 0 2168; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i8, i8 } [[TMP0]], i8 1, 1 2169; CHECK-NEXT: br label [[RETURN]] 2170; CHECK: return: 2171; CHECK-NEXT: [[RETVAL_0:%.*]] = phi { i8, i8 } [ undef, [[ENTRY:%.*]] ], [ undef, [[ENTRY]] ], [ undef, [[ENTRY]] ], [ [[TMP1]], [[SW_DEFAULT]] ] 2172; CHECK-NEXT: ret { i8, i8 } [[RETVAL_0]] 2173; 2174entry: 2175 switch i8 %n, label %sw.default [ 2176 i8 0, label %return 2177 i8 1, label %return 2178 i8 2, label %return 2179 ] 2180 2181sw.default: ; preds = %entry 2182 %0 = insertvalue { i8, i8 } undef, i8 0, 0 2183 %1 = insertvalue { i8, i8 } %0, i8 1, 1 2184 br label %return 2185 2186return: ; preds = %sw.default, %entry, %entry, %entry 2187 %retval.0 = phi { i8, i8 } [ undef, %entry ], [ undef, %entry ], [ undef, %entry ], [ %1, %sw.default ] 2188 ret { i8, i8 } %retval.0 2189} 2190 2191; The switch has a hole which falls through to an unreachable default case, but it can still be optimized into a constant load because 2192; the poison value used for the hole is ignored. 2193define i32 @constant_hole_unreachable_default(i32 %x) { 2194; CHECK-LABEL: @constant_hole_unreachable_default( 2195; CHECK-NEXT: entry: 2196; CHECK-NEXT: ret i32 1 2197; 2198entry: 2199 switch i32 %x, label %sw.default [ 2200 i32 0, label %bb0 2201 i32 2, label %bb0 2202 i32 3, label %bb0 2203 i32 4, label %bb0 2204 ] 2205 2206sw.default: unreachable 2207bb0: br label %return 2208 2209return: 2210 %res = phi i32 [ 1, %bb0 ] 2211 ret i32 %res 2212} 2213 2214; The switch has a hole which falls through to an unreachable default case and the first case explicitly returns undef, yet it cannot be optimized into a simple 2215; constant because we actually treat undef as a unique value rather than ignoring it. 2216define i32 @constant_hole_unreachable_default_firstundef(i32 %x) { 2217; CHECK-LABEL: @constant_hole_unreachable_default_firstundef( 2218; CHECK-NEXT: entry: 2219; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr @switch.table.constant_hole_unreachable_default_firstundef, i32 0, i32 [[X:%.*]] 2220; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 2221; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 2222; 2223entry: 2224 switch i32 %x, label %sw.default [ 2225 i32 0, label %bb.undef 2226 i32 2, label %bb0 2227 i32 3, label %bb0 2228 i32 4, label %bb0 2229 ] 2230 2231sw.default: unreachable 2232bb.undef: br label %return 2233bb0: br label %return 2234 2235return: 2236 %res = phi i32 [ undef, %bb.undef ], [ 1, %bb0 ] 2237 ret i32 %res 2238} 2239 2240; The switch has a hole which falls through to an unreachable default case and the last case explicitly returns undef, yet it cannot be optimized into a simple 2241; constant because we actually treat undef as a unique value rather than ignoring it. 2242define i32 @constant_hole_unreachable_default_lastundef(i32 %x) { 2243; CHECK-LABEL: @constant_hole_unreachable_default_lastundef( 2244; CHECK-NEXT: entry: 2245; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr @switch.table.constant_hole_unreachable_default_lastundef, i32 0, i32 [[X:%.*]] 2246; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 2247; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 2248; 2249entry: 2250 switch i32 %x, label %sw.default [ 2251 i32 0, label %bb0 2252 i32 2, label %bb0 2253 i32 3, label %bb0 2254 i32 4, label %bb.undef 2255 ] 2256 2257sw.default: unreachable 2258bb.undef: br label %return 2259bb0: br label %return 2260 2261return: 2262 %res = phi i32 [ undef, %bb.undef ], [ 1, %bb0 ] 2263 ret i32 %res 2264} 2265 2266; The switch has a hole which falls through to an unreachable default case and the first case explicitly returns poison, but it can still 2267; be optimized into a constant load because the poison values are ignored. 2268define i32 @constant_hole_unreachable_default_firstpoison(i32 %x) { 2269; CHECK-LABEL: @constant_hole_unreachable_default_firstpoison( 2270; CHECK-NEXT: entry: 2271; CHECK-NEXT: ret i32 1 2272; 2273entry: 2274 switch i32 %x, label %sw.default [ 2275 i32 0, label %bb.poison 2276 i32 2, label %bb0 2277 i32 3, label %bb0 2278 i32 4, label %bb0 2279 ] 2280 2281sw.default: unreachable 2282bb.poison: br label %return 2283bb0: br label %return 2284 2285return: 2286 %res = phi i32 [ poison, %bb.poison ], [ 1, %bb0 ] 2287 ret i32 %res 2288} 2289 2290; The switch has a hole which falls through to an unreachable default case and the first case explicitly returns poison, but it can still 2291; be optimized into a constant load because the poison values are ignored. 2292define i32 @constant_hole_unreachable_default_lastpoison(i32 %x) { 2293; CHECK-LABEL: @constant_hole_unreachable_default_lastpoison( 2294; CHECK-NEXT: entry: 2295; CHECK-NEXT: ret i32 1 2296; 2297entry: 2298 switch i32 %x, label %sw.default [ 2299 i32 0, label %bb0 2300 i32 2, label %bb0 2301 i32 3, label %bb0 2302 i32 4, label %bb.poison 2303 ] 2304 2305sw.default: unreachable 2306bb.poison: br label %return 2307bb0: br label %return 2308 2309return: 2310 %res = phi i32 [ poison, %bb.poison ], [ 1, %bb0 ] 2311 ret i32 %res 2312} 2313 2314define i32 @constant_hole_unreachable_default_undef_poison(i32 %x) { 2315; CHECK-LABEL: @constant_hole_unreachable_default_undef_poison( 2316; CHECK-NEXT: entry: 2317; CHECK-NEXT: ret i32 undef 2318; 2319entry: 2320 switch i32 %x, label %sw.default [ 2321 i32 0, label %bb.undef 2322 i32 2, label %bb.poison 2323 i32 3, label %bb.poison 2324 i32 4, label %bb.poison 2325 ] 2326 2327sw.default: unreachable 2328bb.undef: br label %return 2329bb.poison: br label %return 2330 2331return: 2332 %res = phi i32 [ undef, %bb.undef ], [ poison, %bb.poison ] 2333 ret i32 %res 2334} 2335 2336define i32 @constant_hole_unreachable_default_poison_undef(i32 %x) { 2337; CHECK-LABEL: @constant_hole_unreachable_default_poison_undef( 2338; CHECK-NEXT: entry: 2339; CHECK-NEXT: ret i32 undef 2340; 2341entry: 2342 switch i32 %x, label %sw.default [ 2343 i32 0, label %bb.poison 2344 i32 2, label %bb.poison 2345 i32 3, label %bb.poison 2346 i32 4, label %bb.undef 2347 ] 2348 2349sw.default: unreachable 2350bb.undef: br label %return 2351bb.poison: br label %return 2352 2353return: 2354 %res = phi i32 [ undef, %bb.undef ], [ poison, %bb.poison ] 2355 ret i32 %res 2356} 2357 2358; The switch has a hole which falls through to an unreachable default case, which prevents it from being optimized into a linear mapping 2*x+1. 2359; TODO: We should add support for this, at least in certain cases. 2360define i32 @linearmap_hole_unreachable_default(i32 %x) { 2361; CHECK-LABEL: @linearmap_hole_unreachable_default( 2362; CHECK-NEXT: entry: 2363; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr @switch.table.linearmap_hole_unreachable_default, i32 0, i32 [[X:%.*]] 2364; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 2365; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] 2366; 2367entry: 2368 switch i32 %x, label %sw.default [ 2369 i32 0, label %bb0 2370 i32 2, label %bb2 2371 i32 3, label %bb3 2372 i32 4, label %bb4 2373 ] 2374 2375sw.default: unreachable 2376bb0: br label %return 2377bb2: br label %return 2378bb3: br label %return 2379bb4: br label %return 2380 2381return: 2382 %res = phi i32 [ 1, %bb0 ], [ 5, %bb2 ], [ 7, %bb3 ], [ 9, %bb4 ] 2383 ret i32 %res 2384} 2385 2386; The switch has a hole which falls through to an unreachable default case, but it can still be optimized into a bitmask extraction because 2387; the poison value used for the hole is simply replaced with zero. 2388define i1 @bitset_hole_unreachable_default(i32 %x) { 2389; CHECK-LABEL: @bitset_hole_unreachable_default( 2390; CHECK-NEXT: entry: 2391; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[X:%.*]] to i5 2392; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i5 [[SWITCH_CAST]], 1 2393; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i5 8, [[SWITCH_SHIFTAMT]] 2394; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i5 [[SWITCH_DOWNSHIFT]] to i1 2395; CHECK-NEXT: ret i1 [[SWITCH_MASKED]] 2396; 2397entry: 2398 switch i32 %x, label %sw.default [ 2399 i32 0, label %bb0 2400 i32 2, label %bb0 2401 i32 3, label %bb1 2402 i32 4, label %bb0 2403 ] 2404 2405sw.default: unreachable 2406bb0: br label %return 2407bb1: br label %return 2408 2409return: 2410 %res = phi i1 [ 0, %bb0 ], [ 1, %bb1 ] 2411 ret i1 %res 2412} 2413