Skip to content

Commit 5cc0170

Browse files
committed
[SimplifyCFG] Precommit tests for truncated integer lookup tables
1 parent f8d2704 commit 5cc0170

File tree

2 files changed

+112
-26
lines changed

2 files changed

+112
-26
lines changed

llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ target triple = "x86_64-unknown-linux-gnu"
3939
; CHECK: @switch.table.covered_switch_with_bit_tests = private unnamed_addr constant [8 x i32] [i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 1], align 4
4040
; CHECK: @switch.table.signed_overflow1 = private unnamed_addr constant [4 x i32] [i32 3333, i32 4444, i32 1111, i32 2222], align 4
4141
; CHECK: @switch.table.signed_overflow2 = private unnamed_addr constant [4 x i32] [i32 3333, i32 4444, i32 2222, i32 2222], align 4
42+
; CHECK: @switch.table.truncatedint_shift_mask = private unnamed_addr constant [4 x i32] [i32 33578, i32 33594, i32 33658, i32 33626], align 4
43+
; CHECK: @switch.table.truncatedint_shift_nsw = private unnamed_addr constant [5 x i32] [i32 8483, i32 12579, i32 28963, i32 33059, i32 37155], align 4
44+
; CHECK: @switch.table.truncatedint_shift_not_nsw = private unnamed_addr constant [5 x i16] [i16 8483, i16 12579, i16 28963, i16 -32477, i16 -28381], align 2
4245
;.
4346
define i32 @f(i32 %c) {
4447
; CHECK-LABEL: @f(
@@ -219,13 +222,13 @@ define i32 @earlyreturncrash(i32 %x) {
219222
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]]
220223
; CHECK: switch.lookup:
221224
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.earlyreturncrash, i32 0, i32 [[X]]
222-
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
225+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
223226
; CHECK-NEXT: [[SWITCH_GEP1:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.earlyreturncrash.1, i32 0, i32 [[X]]
224-
; CHECK-NEXT: [[SWITCH_LOAD2:%.*]] = load i32, ptr [[SWITCH_GEP1]], align 4
227+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST4:%.*]] = load i32, ptr [[SWITCH_GEP1]], align 4
225228
; CHECK-NEXT: br label [[SW_EPILOG]]
226229
; CHECK: sw.epilog:
227-
; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ]
228-
; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ [[SWITCH_LOAD2]], [[SWITCH_LOOKUP]] ], [ 10, [[ENTRY]] ]
230+
; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ [[SWITCH_TRUNCATEDINT_CAST]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ]
231+
; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ [[SWITCH_TRUNCATEDINT_CAST4]], [[SWITCH_LOOKUP]] ], [ 10, [[ENTRY]] ]
229232
; CHECK-NEXT: ret i32 [[A_0]]
230233
;
231234
entry:
@@ -402,10 +405,10 @@ define i32 @large(i32 %x) {
402405
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
403406
; CHECK: switch.lookup:
404407
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [199 x i32], ptr @switch.table.large, i32 0, i32 [[SWITCH_TABLEIDX]]
405-
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
408+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
406409
; CHECK-NEXT: br label [[RETURN]]
407410
; CHECK: return:
408-
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ]
411+
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SWITCH_TRUNCATEDINT_CAST]], [[SWITCH_LOOKUP]] ]
409412
; CHECK-NEXT: ret i32 [[RETVAL_0]]
410413
;
411414
entry:
@@ -918,8 +921,8 @@ define i32 @unreachable_default(i32 %x) {
918921
; CHECK-LABEL: @unreachable_default(
919922
; CHECK-NEXT: entry:
920923
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.unreachable_default, i32 0, i32 [[X:%.*]]
921-
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
922-
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
924+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
925+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_CAST]]
923926
;
924927
entry:
925928
switch i32 %x, label %default [
@@ -1714,8 +1717,8 @@ define i32 @signed_overflow1(i8 %n) {
17141717
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2
17151718
; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3
17161719
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow1, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]]
1717-
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
1718-
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
1720+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
1721+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_CAST]]
17191722
;
17201723
start:
17211724
%trunc = trunc i8 %n to i2
@@ -1750,8 +1753,8 @@ define i32 @signed_overflow2(i8 %n) {
17501753
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2
17511754
; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3
17521755
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow2, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]]
1753-
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
1754-
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
1756+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
1757+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_CAST]]
17551758
;
17561759
start:
17571760
%trunc = trunc i8 %n to i2
@@ -2184,3 +2187,86 @@ return: ; preds = %sw.default, %entry,
21842187
%retval.0 = phi { i8, i8 } [ undef, %entry ], [ undef, %entry ], [ undef, %entry ], [ %1, %sw.default ]
21852188
ret { i8, i8 } %retval.0
21862189
}
2190+
2191+
define i32 @truncatedint_shift_mask(i32 %c) {
2192+
; CHECK-LABEL: @truncatedint_shift_mask(
2193+
; CHECK-NEXT: entry:
2194+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.truncatedint_shift_mask, i32 0, i32 [[C:%.*]]
2195+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_MASK:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
2196+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_MASK]]
2197+
;
2198+
entry:
2199+
switch i32 %c, label %sw.default [
2200+
i32 0, label %bb0
2201+
i32 1, label %bb1
2202+
i32 2, label %bb2
2203+
i32 3, label %bb3
2204+
]
2205+
2206+
sw.default: unreachable
2207+
bb0: br label %return
2208+
bb1: br label %return
2209+
bb2: br label %return
2210+
bb3: br label %return
2211+
2212+
return:
2213+
%x = phi i32 [ u0x832A, %bb0 ], [ u0x833A, %bb1 ], [ u0x837A, %bb2 ], [ u0x835A, %bb3 ]
2214+
ret i32 %x
2215+
}
2216+
2217+
define i32 @truncatedint_shift_nsw(i32 %c) {
2218+
; CHECK-LABEL: @truncatedint_shift_nsw(
2219+
; CHECK-NEXT: entry:
2220+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr @switch.table.truncatedint_shift_nsw, i32 0, i32 [[C:%.*]]
2221+
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
2222+
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
2223+
;
2224+
entry:
2225+
switch i32 %c, label %sw.default [
2226+
i32 0, label %bb0
2227+
i32 1, label %bb1
2228+
i32 2, label %bb2
2229+
i32 3, label %bb3
2230+
i32 4, label %bb4
2231+
]
2232+
2233+
sw.default: unreachable
2234+
bb0: br label %return
2235+
bb1: br label %return
2236+
bb2: br label %return
2237+
bb3: br label %return
2238+
bb4: br label %return
2239+
2240+
return:
2241+
%x = phi i32 [ u0x2123, %bb0 ], [ u0x3123, %bb1 ], [ u0x7123, %bb2 ], [ u0x8123, %bb3 ], [ u0x9123, %bb4 ]
2242+
ret i32 %x
2243+
}
2244+
2245+
; Same as @truncatedint_shift_nsw, but the return type is i16 so the NSW flag shouldn't be set on shl
2246+
define i16 @truncatedint_shift_not_nsw(i32 %c) {
2247+
; CHECK-LABEL: @truncatedint_shift_not_nsw(
2248+
; CHECK-NEXT: entry:
2249+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i16], ptr @switch.table.truncatedint_shift_not_nsw, i32 0, i32 [[C:%.*]]
2250+
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i16, ptr [[SWITCH_GEP]], align 2
2251+
; CHECK-NEXT: ret i16 [[SWITCH_LOAD]]
2252+
;
2253+
entry:
2254+
switch i32 %c, label %sw.default [
2255+
i32 0, label %bb0
2256+
i32 1, label %bb1
2257+
i32 2, label %bb2
2258+
i32 3, label %bb3
2259+
i32 4, label %bb4
2260+
]
2261+
2262+
sw.default: unreachable
2263+
bb0: br label %return
2264+
bb1: br label %return
2265+
bb2: br label %return
2266+
bb3: br label %return
2267+
bb4: br label %return
2268+
2269+
return:
2270+
%x = phi i16 [ u0x2123, %bb0 ], [ u0x3123, %bb1 ], [ u0x7123, %bb2 ], [ u0x8123, %bb3 ], [ u0x9123, %bb4 ]
2271+
ret i16 %x
2272+
}

llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table_big.ll

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ define i32 @reachable_default_dense_0to31(i32 %x, i32 %y) {
2020
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
2121
; CHECK: switch.lookup:
2222
; 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
23+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
2424
; CHECK-NEXT: br label [[RETURN]]
2525
; CHECK: return:
26-
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
26+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_TRUNCATEDINT_CAST]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
2727
; CHECK-NEXT: ret i32 [[RES]]
2828
;
2929
entry:
@@ -83,8 +83,8 @@ define i32 @unreachable_default_dense_0to31(i32 %x, i32 %y) {
8383
; CHECK-LABEL: @unreachable_default_dense_0to31(
8484
; CHECK-NEXT: entry:
8585
; 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]]
86+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
87+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_CAST]]
8888
;
8989
entry:
9090
switch i32 %x, label %sw.default [
@@ -150,10 +150,10 @@ define i32 @reachable_default_holes_0to31(i32 %x, i32 %y) {
150150
; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN]]
151151
; CHECK: switch.lookup:
152152
; 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
153+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
154154
; CHECK-NEXT: br label [[RETURN]]
155155
; CHECK: return:
156-
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[SWITCH_HOLE_CHECK]] ], [ [[Y]], [[ENTRY:%.*]] ]
156+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_TRUNCATEDINT_CAST]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[SWITCH_HOLE_CHECK]] ], [ [[Y]], [[ENTRY:%.*]] ]
157157
; CHECK-NEXT: ret i32 [[RES]]
158158
;
159159
entry:
@@ -207,8 +207,8 @@ define i32 @unreachable_default_holes_0to31(i32 %x, i32 %y) {
207207
; CHECK-LABEL: @unreachable_default_holes_0to31(
208208
; CHECK-NEXT: entry:
209209
; 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]]
210+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
211+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_CAST]]
212212
;
213213
entry:
214214
switch i32 %x, label %sw.default [
@@ -264,10 +264,10 @@ define i32 @reachable_default_dense_0to32(i32 %x, i32 %y) {
264264
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
265265
; CHECK: switch.lookup:
266266
; 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
267+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
268268
; CHECK-NEXT: br label [[RETURN]]
269269
; CHECK: return:
270-
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
270+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_TRUNCATEDINT_CAST]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
271271
; CHECK-NEXT: ret i32 [[RES]]
272272
;
273273
entry:
@@ -328,8 +328,8 @@ define i32 @unreachable_default_dense_0to32(i32 %x, i32 %y) {
328328
; CHECK-LABEL: @unreachable_default_dense_0to32(
329329
; CHECK-NEXT: entry:
330330
; 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]]
331+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
332+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_CAST]]
333333
;
334334
entry:
335335
switch i32 %x, label %sw.default [
@@ -491,8 +491,8 @@ define i32 @unreachable_default_holes_0to32(i32 %x, i32 %y) {
491491
; CHECK-LABEL: @unreachable_default_holes_0to32(
492492
; CHECK-NEXT: entry:
493493
; 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]]
494+
; CHECK-NEXT: [[SWITCH_TRUNCATEDINT_CAST:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
495+
; CHECK-NEXT: ret i32 [[SWITCH_TRUNCATEDINT_CAST]]
496496
;
497497
entry:
498498
switch i32 %x, label %sw.default [

0 commit comments

Comments
 (0)