Skip to content

Commit d216a2c

Browse files
committed
[SimplifyCFG] Use indexType from data layout in switch to table conversion.
1 parent 5ea29f7 commit d216a2c

15 files changed

+88
-58
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6347,7 +6347,7 @@ class SwitchLookupTable {
63476347

63486348
/// Build instructions with Builder to retrieve the value at
63496349
/// the position given by Index in the lookup table.
6350-
Value *buildLookup(Value *Index, IRBuilder<> &Builder);
6350+
Value *buildLookup(Value *Index, IRBuilder<> &Builder, const DataLayout &DL);
63516351

63526352
/// Return true if a table with TableSize elements of
63536353
/// type ElementType would fit in a target-legal register.
@@ -6533,7 +6533,8 @@ SwitchLookupTable::SwitchLookupTable(
65336533
Kind = ArrayKind;
65346534
}
65356535

6536-
Value *SwitchLookupTable::buildLookup(Value *Index, IRBuilder<> &Builder) {
6536+
Value *SwitchLookupTable::buildLookup(Value *Index, IRBuilder<> &Builder,
6537+
const DataLayout &DL) {
65376538
switch (Kind) {
65386539
case SingleValueKind:
65396540
return SingleValue;
@@ -6575,16 +6576,12 @@ Value *SwitchLookupTable::buildLookup(Value *Index, IRBuilder<> &Builder) {
65756576
return Builder.CreateTrunc(DownShifted, BitMapElementTy, "switch.masked");
65766577
}
65776578
case ArrayKind: {
6578-
// Make sure the table index will not overflow when treated as signed.
6579-
IntegerType *IT = cast<IntegerType>(Index->getType());
6580-
uint64_t TableSize =
6581-
Array->getInitializer()->getType()->getArrayNumElements();
6582-
if (TableSize > (1ULL << std::min(IT->getBitWidth() - 1, 63u)))
6583-
Index = Builder.CreateZExt(
6584-
Index, IntegerType::get(IT->getContext(), IT->getBitWidth() + 1),
6585-
"switch.tableidx.zext");
6586-
6587-
Value *GEPIndices[] = {Builder.getInt32(0), Index};
6579+
Type *IndexTy = DL.getIndexType(Array->getType());
6580+
6581+
if (Index->getType() != IndexTy)
6582+
Index = Builder.CreateZExtOrTrunc(Index, IndexTy);
6583+
6584+
Value *GEPIndices[] = {ConstantInt::get(IndexTy, 0), Index};
65886585
Value *GEP = Builder.CreateInBoundsGEP(Array->getValueType(), Array,
65896586
GEPIndices, "switch.gep");
65906587
return Builder.CreateLoad(
@@ -7064,7 +7061,7 @@ static bool switchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
70647061
SwitchLookupTable Table(Mod, TableSize, TableIndexOffset, ResultList, DV,
70657062
DL, FuncName);
70667063

7067-
Value *Result = Table.buildLookup(TableIndex, Builder);
7064+
Value *Result = Table.buildLookup(TableIndex, Builder, DL);
70687065

70697066
// Do a small peephole optimization: re-use the switch table compare if
70707067
// possible.

llvm/test/Transforms/SimplifyCFG/RISCV/switch-of-powers-of-two.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ define i32 @switch_of_powers(i32 %x) {
3434
; RV64ZBB-LABEL: @switch_of_powers(
3535
; RV64ZBB-NEXT: entry:
3636
; RV64ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)
37-
; RV64ZBB-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers, i32 0, i32 [[TMP0]]
37+
; RV64ZBB-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
38+
; RV64ZBB-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers, i64 0, i64 [[TMP1]]
3839
; RV64ZBB-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
3940
; RV64ZBB-NEXT: ret i32 [[SWITCH_LOAD]]
4041
;

llvm/test/Transforms/SimplifyCFG/RISCV/switch_to_lookup_table-rv64.ll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ define i32 @f(i32 %c) {
2727
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7
2828
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
2929
; CHECK: switch.lookup:
30-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.f, i32 0, i32 [[SWITCH_TABLEIDX]]
30+
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[SWITCH_TABLEIDX]] to i64
31+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.f, i64 0, i64 [[TMP1]]
3132
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
3233
; CHECK-NEXT: br label [[RETURN]]
3334
; CHECK: return:
@@ -67,7 +68,8 @@ define i8 @char(i32 %c) {
6768
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 9
6869
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
6970
; CHECK: switch.lookup:
70-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i8], ptr @switch.table.char, i32 0, i32 [[SWITCH_TABLEIDX]]
71+
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[SWITCH_TABLEIDX]] to i64
72+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i8], ptr @switch.table.char, i64 0, i64 [[TMP1]]
7173
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
7274
; CHECK-NEXT: br label [[RETURN]]
7375
; CHECK: return:
@@ -114,7 +116,8 @@ define void @h(i32 %x) {
114116
; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i32 [[X]], 8
115117
; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 89655594, [[SWITCH_SHIFTAMT]]
116118
; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8
117-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], ptr @switch.table.h, i32 0, i32 [[X]]
119+
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64
120+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], ptr @switch.table.h, i64 0, i64 [[TMP1]]
118121
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load float, ptr [[SWITCH_GEP]], align 4
119122
; CHECK-NEXT: br label [[SW_EPILOG]]
120123
; CHECK: sw.epilog:
@@ -159,7 +162,8 @@ define ptr @foostring(i32 %x) {
159162
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
160163
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
161164
; CHECK: switch.lookup:
162-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x ptr], ptr @switch.table.foostring, i32 0, i32 [[X]]
165+
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64
166+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x ptr], ptr @switch.table.foostring, i64 0, i64 [[TMP1]]
163167
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load ptr, ptr [[SWITCH_GEP]], align 8
164168
; CHECK-NEXT: br label [[RETURN]]
165169
; CHECK: return:

llvm/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ define i32 @bar(i32 %c) {
5050
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
5151
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
5252
; CHECK: switch.lookup:
53-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.bar, i32 0, i32 [[SWITCH_TABLEIDX]]
53+
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[SWITCH_TABLEIDX]] to i64
54+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.bar, i64 0, i64 [[TMP1]]
5455
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
5556
; CHECK-NEXT: br label [[RETURN]]
5657
; CHECK: return:

llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ define i64 @test(i3 %arg) {
1010
; CHECK-LABEL: @test(
1111
; CHECK-NEXT: entry:
1212
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[ARG:%.*]], -4
13-
; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i4
14-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i64], ptr @switch.table.test, i32 0, i4 [[SWITCH_TABLEIDX_ZEXT]]
13+
; CHECK-NEXT: [[TMP0:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i64
14+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i64], ptr @switch.table.test, i64 0, i64 [[TMP0]]
1515
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8
1616
; CHECK-NEXT: [[V3:%.*]] = add i64 [[SWITCH_LOAD]], 0
1717
; CHECK-NEXT: ret i64 [[V3]]

llvm/test/Transforms/SimplifyCFG/X86/switch-of-powers-of-two.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ define i32 @switch_of_powers_two(i32 %arg) {
88
; CHECK-SAME: i32 [[ARG:%.*]]) {
99
; CHECK-NEXT: [[ENTRY:.*:]]
1010
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 true)
11-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers_two, i32 0, i32 [[TMP0]]
11+
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
12+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers_two, i64 0, i64 [[TMP1]]
1213
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
1314
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
1415
;

llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ define i64 @_TFO6reduce1E5toRawfS0_FT_Si(i2) {
1010
; CHECK-LABEL: @_TFO6reduce1E5toRawfS0_FT_Si(
1111
; CHECK-NEXT: entry:
1212
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TMP0:%.*]], -2
13-
; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3
14-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i64], ptr @switch.table._TFO6reduce1E5toRawfS0_FT_Si, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]]
13+
; CHECK-NEXT: [[TMP1:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i64
14+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i64], ptr @switch.table._TFO6reduce1E5toRawfS0_FT_Si, i64 0, i64 [[TMP1]]
1515
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8
1616
; CHECK-NEXT: ret i64 [[SWITCH_LOAD]]
1717
;

llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-bitcast.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ target triple = "x86_64-unknown-linux-gnu"
99
define { ptr, i64 } @switch_to_lookup_bitcast(i8 %0) unnamed_addr {
1010
; CHECK-LABEL: @switch_to_lookup_bitcast(
1111
; CHECK-NEXT: start:
12-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x ptr], ptr @switch.table.switch_to_lookup_bitcast, i32 0, i8 [[TMP0:%.*]]
12+
; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[TMP0:%.*]] to i64
13+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x ptr], ptr @switch.table.switch_to_lookup_bitcast, i64 0, i64 [[TMP3]]
1314
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load ptr, ptr [[SWITCH_GEP]], align 8
1415
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, i64 } undef, ptr [[SWITCH_LOAD]], 0
1516
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, i64 } [[TMP1]], i64 1, 1

llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-gep.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ target triple = "x86_64-unknown-linux-gnu"
99
define { ptr, i64 } @switch_to_lookup_gep(i8 %0) unnamed_addr {
1010
; CHECK-LABEL: @switch_to_lookup_gep(
1111
; CHECK-NEXT: start:
12-
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x ptr], ptr @switch.table.switch_to_lookup_gep, i32 0, i8 [[TMP0:%.*]]
12+
; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[TMP0:%.*]] to i64
13+
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x ptr], ptr @switch.table.switch_to_lookup_gep, i64 0, i64 [[TMP3]]
1314
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load ptr, ptr [[SWITCH_GEP]], align 8
1415
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, i64 } undef, ptr [[SWITCH_LOAD]], 0
1516
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, i64 } [[TMP1]], i64 1, 1

llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-globals.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ define i1 @zot(i32 %arg) {
1313
; CHECK-NEXT: %0 = icmp ult i32 %arg, 3
1414
; CHECK-NEXT: br i1 %0, label %switch.lookup, label %bb6
1515
; CHECK: switch.lookup:
16-
; CHECK-NEXT: %switch.gep = getelementptr inbounds [3 x ptr], ptr @switch.table.zot, i32 0, i32 %arg
16+
; CHECK-NEXT: %1 = zext i32 %arg to i64
17+
; CHECK-NEXT: %switch.gep = getelementptr inbounds [3 x ptr], ptr @switch.table.zot, i64 0, i64 %1
1718
; CHECK-NEXT: %switch.load = load ptr, ptr %switch.gep, align 8
1819
; CHECK-NEXT: br label %bb6
1920
; CHECK: bb6:

0 commit comments

Comments
 (0)