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 -S | FileCheck %s
3 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
4 target triple = "i386-pc-linux-gnu"
6 ; A dense switch with a reachable default case should be optimized into a lookup table with a bounds check
8 ; CHECK: @switch.table.reachable_default_dense_0to31 = private unnamed_addr constant [32 x i32] [i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1], align 4
9 ; CHECK: @switch.table.unreachable_default_dense_0to31 = private unnamed_addr constant [32 x i32] [i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1], align 4
10 ; CHECK: @switch.table.reachable_default_holes_0to31 = private unnamed_addr constant [32 x i32] [i32 0, i32 7, i32 6, i32 poison, i32 4, i32 3, i32 2, i32 1, i32 poison, i32 7, i32 6, i32 5, i32 4, i32 poison, i32 2, i32 1, i32 0, i32 7, i32 poison, i32 5, i32 4, i32 3, i32 2, i32 poison, i32 0, i32 7, i32 6, i32 5, i32 poison, i32 3, i32 2, i32 1], align 4
11 ; CHECK: @switch.table.unreachable_default_holes_0to31 = private unnamed_addr constant [32 x i32] [i32 0, i32 7, i32 6, i32 poison, i32 4, i32 3, i32 2, i32 1, i32 poison, i32 7, i32 6, i32 5, i32 4, i32 poison, i32 2, i32 1, i32 0, i32 7, i32 poison, i32 5, i32 4, i32 3, i32 2, i32 poison, i32 0, i32 7, i32 6, i32 5, i32 poison, i32 3, i32 2, i32 1], align 4
12 ; CHECK: @switch.table.reachable_default_dense_0to32 = private unnamed_addr constant [33 x i32] [i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0], align 4
13 ; CHECK: @switch.table.unreachable_default_dense_0to32 = private unnamed_addr constant [33 x i32] [i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0], align 4
14 ; CHECK: @switch.table.unreachable_default_holes_0to32 = private unnamed_addr constant [33 x i32] [i32 0, i32 7, i32 6, i32 poison, i32 4, i32 3, i32 2, i32 1, i32 poison, i32 7, i32 6, i32 5, i32 4, i32 poison, i32 2, i32 1, i32 0, i32 7, i32 poison, i32 5, i32 4, i32 3, i32 2, i32 poison, i32 0, i32 7, i32 6, i32 5, i32 poison, i32 3, i32 2, i32 1, i32 0], align 4
16 define i32 @reachable_default_dense_0to31(i32 %x, i32 %y) {
17 ; CHECK-LABEL: @reachable_default_dense_0to31(
19 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 32
20 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
21 ; CHECK: switch.lookup:
22 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.reachable_default_dense_0to31, i32 0, i32 [[X]]
23 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
24 ; CHECK-NEXT: br label [[RETURN]]
26 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
27 ; CHECK-NEXT: ret i32 [[RES]]
30 switch i32 %x, label %sw.default [
65 sw.default: br label %return
76 %res = phi i32 [ %y, %sw.default ], [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]
81 ; A dense switch with an unreachable default case should be optimized into a lookup table without bounds checks
82 define i32 @unreachable_default_dense_0to31(i32 %x, i32 %y) {
83 ; CHECK-LABEL: @unreachable_default_dense_0to31(
85 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.unreachable_default_dense_0to31, i32 0, i32 [[X:%.*]]
86 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
87 ; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
90 switch i32 %x, label %sw.default [
125 sw.default: unreachable
126 bb0: br label %return
127 bb1: br label %return
128 bb2: br label %return
129 bb3: br label %return
130 bb4: br label %return
131 bb5: br label %return
132 bb6: br label %return
133 bb7: br label %return
136 %res = phi i32 [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]
141 ; A sparse switch with a reachable default case should be optimized into a lookup table with a bounds check and a mask
142 define i32 @reachable_default_holes_0to31(i32 %x, i32 %y) {
143 ; CHECK-LABEL: @reachable_default_holes_0to31(
145 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 32
146 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_HOLE_CHECK:%.*]], label [[RETURN:%.*]]
147 ; CHECK: switch.hole_check:
148 ; CHECK-NEXT: [[SWITCH_SHIFTED:%.*]] = lshr i32 -277094665, [[X]]
149 ; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = trunc i32 [[SWITCH_SHIFTED]] to i1
150 ; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN]]
151 ; CHECK: switch.lookup:
152 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.reachable_default_holes_0to31, i32 0, i32 [[X]]
153 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
154 ; CHECK-NEXT: br label [[RETURN]]
156 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[SWITCH_HOLE_CHECK]] ], [ [[Y]], [[ENTRY:%.*]] ]
157 ; CHECK-NEXT: ret i32 [[RES]]
160 switch i32 %x, label %sw.default [
189 sw.default: br label %return
190 bb0: br label %return
191 bb1: br label %return
192 bb2: br label %return
193 bb3: br label %return
194 bb4: br label %return
195 bb5: br label %return
196 bb6: br label %return
197 bb7: br label %return
200 %res = phi i32 [ %y, %sw.default ], [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]
205 ; A sparse switch with an unreachable default case should be optimized into a lookup table without bounds checks
206 define i32 @unreachable_default_holes_0to31(i32 %x, i32 %y) {
207 ; CHECK-LABEL: @unreachable_default_holes_0to31(
209 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.unreachable_default_holes_0to31, i32 0, i32 [[X:%.*]]
210 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
211 ; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
214 switch i32 %x, label %sw.default [
243 sw.default: unreachable
244 bb0: br label %return
245 bb1: br label %return
246 bb2: br label %return
247 bb3: br label %return
248 bb4: br label %return
249 bb5: br label %return
250 bb6: br label %return
251 bb7: br label %return
254 %res = phi i32 [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]
259 ; A dense switch with a reachable default case should be optimized into a lookup table with a bounds check
260 define i32 @reachable_default_dense_0to32(i32 %x, i32 %y) {
261 ; CHECK-LABEL: @reachable_default_dense_0to32(
263 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 33
264 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
265 ; CHECK: switch.lookup:
266 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i32], ptr @switch.table.reachable_default_dense_0to32, i32 0, i32 [[X]]
267 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
268 ; CHECK-NEXT: br label [[RETURN]]
270 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
271 ; CHECK-NEXT: ret i32 [[RES]]
274 switch i32 %x, label %sw.default [
310 sw.default: br label %return
311 bb0: br label %return
312 bb1: br label %return
313 bb2: br label %return
314 bb3: br label %return
315 bb4: br label %return
316 bb5: br label %return
317 bb6: br label %return
318 bb7: br label %return
321 %res = phi i32 [ %y, %sw.default ], [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]
326 ; A dense switch with an unreachable default case should be optimized into a lookup table without bounds checks
327 define i32 @unreachable_default_dense_0to32(i32 %x, i32 %y) {
328 ; CHECK-LABEL: @unreachable_default_dense_0to32(
330 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i32], ptr @switch.table.unreachable_default_dense_0to32, i32 0, i32 [[X:%.*]]
331 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
332 ; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
335 switch i32 %x, label %sw.default [
371 sw.default: unreachable
372 bb0: br label %return
373 bb1: br label %return
374 bb2: br label %return
375 bb3: br label %return
376 bb4: br label %return
377 bb5: br label %return
378 bb6: br label %return
379 bb7: br label %return
382 %res = phi i32 [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]
387 ; A sparse switch with a reachable default case which would be optimized into a lookup table with a bounds check and a mask, but doesn't because
388 ; it would require a 33-bit mask
389 define i32 @reachable_default_holes_0to32(i32 %x, i32 %y) {
390 ; CHECK-LABEL: @reachable_default_holes_0to32(
392 ; CHECK-NEXT: switch i32 [[X:%.*]], label [[RETURN:%.*]] [
393 ; CHECK-NEXT: i32 0, label [[BB0:%.*]]
394 ; CHECK-NEXT: i32 1, label [[BB7:%.*]]
395 ; CHECK-NEXT: i32 2, label [[BB6:%.*]]
396 ; CHECK-NEXT: i32 4, label [[BB4:%.*]]
397 ; CHECK-NEXT: i32 5, label [[BB3:%.*]]
398 ; CHECK-NEXT: i32 6, label [[BB2:%.*]]
399 ; CHECK-NEXT: i32 7, label [[BB1:%.*]]
400 ; CHECK-NEXT: i32 9, label [[BB7]]
401 ; CHECK-NEXT: i32 10, label [[BB6]]
402 ; CHECK-NEXT: i32 11, label [[BB5:%.*]]
403 ; CHECK-NEXT: i32 12, label [[BB4]]
404 ; CHECK-NEXT: i32 14, label [[BB2]]
405 ; CHECK-NEXT: i32 15, label [[BB1]]
406 ; CHECK-NEXT: i32 16, label [[BB0]]
407 ; CHECK-NEXT: i32 17, label [[BB7]]
408 ; CHECK-NEXT: i32 19, label [[BB5]]
409 ; CHECK-NEXT: i32 20, label [[BB4]]
410 ; CHECK-NEXT: i32 21, label [[BB3]]
411 ; CHECK-NEXT: i32 22, label [[BB2]]
412 ; CHECK-NEXT: i32 24, label [[BB0]]
413 ; CHECK-NEXT: i32 25, label [[BB7]]
414 ; CHECK-NEXT: i32 26, label [[BB6]]
415 ; CHECK-NEXT: i32 27, label [[BB5]]
416 ; CHECK-NEXT: i32 29, label [[BB3]]
417 ; CHECK-NEXT: i32 30, label [[BB2]]
418 ; CHECK-NEXT: i32 31, label [[BB1]]
419 ; CHECK-NEXT: i32 32, label [[BB0]]
422 ; CHECK-NEXT: br label [[RETURN]]
424 ; CHECK-NEXT: br label [[RETURN]]
426 ; CHECK-NEXT: br label [[RETURN]]
428 ; CHECK-NEXT: br label [[RETURN]]
430 ; CHECK-NEXT: br label [[RETURN]]
432 ; CHECK-NEXT: br label [[RETURN]]
434 ; CHECK-NEXT: br label [[RETURN]]
436 ; CHECK-NEXT: br label [[RETURN]]
438 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[BB0]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ], [ 5, [[BB5]] ], [ 6, [[BB6]] ], [ 7, [[BB7]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
439 ; CHECK-NEXT: ret i32 [[RES]]
442 switch i32 %x, label %sw.default [
472 sw.default: br label %return
473 bb0: br label %return
474 bb1: br label %return
475 bb2: br label %return
476 bb3: br label %return
477 bb4: br label %return
478 bb5: br label %return
479 bb6: br label %return
480 bb7: br label %return
483 %res = phi i32 [ %y, %sw.default ], [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]
488 ; A sparse switch with an unreachable default case which can be optimized into a lookup table without bounds checks. Because the default case is
489 ; unreachable, the fact that a 33-bit mask would be required doesn't prevent lookup table optimization.
490 define i32 @unreachable_default_holes_0to32(i32 %x, i32 %y) {
491 ; CHECK-LABEL: @unreachable_default_holes_0to32(
493 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i32], ptr @switch.table.unreachable_default_holes_0to32, i32 0, i32 [[X:%.*]]
494 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
495 ; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
498 switch i32 %x, label %sw.default [
528 sw.default: unreachable
529 bb0: br label %return
530 bb1: br label %return
531 bb2: br label %return
532 bb3: br label %return
533 bb4: br label %return
534 bb5: br label %return
535 bb6: br label %return
536 bb7: br label %return
539 %res = phi i32 [ 0, %bb0 ], [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %bb3 ], [ 4, %bb4 ], [ 5, %bb5 ], [ 6, %bb6 ], [ 7, %bb7 ]