[llvm] [SimplifyCFG] Shrink integer lookup tables (PR #202071)
Alexis Engelke via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 6 11:50:45 PDT 2026
https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/202071
After #200664, we generate lookup tables in more cases, leading to higher memory use and larger binaries. Partially alleviate this by shrinking the lookup tables if all elements are small integers. The underlying idea is that an extra integer extension can typically be folded into a load instruction at no extra cost.
---
This reduces the size of [stage2-clang by 0.13%](https://llvm-compile-time-tracker.com/compare.php?from=0ff9a752b346c1d193a3a654ff474c44b2b4d48e&to=0921675d81a105989b16494c6bf6196e496ce95e&stat=size-text).
I'm still somewhat new to these optimization things -- questions: does this need better legality checking than power of 2? Does this need cost model checking w.r.t. the cost of the zext?
Is this a good place or should we rather to this in something like GlobalOpt (shrinking of general loads from local arrays with small values)?
>From 9f9ab94c88a44ff53329b3f2bd380838dbf8f07e Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Sat, 6 Jun 2026 17:37:55 +0000
Subject: [PATCH] [SimplifyCFG] Shrink integer lookup tables
After #200664, we generate lookup tables in more cases, leading to
higher memory use and larger binaries. Partially alleviate this by
shrinking the lookup tables if all elements are small integers. The
underlying idea is that an extra integer extension can typically be
folded into a load instruction at no extra cost.
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 23 +++++-
.../PhaseOrdering/X86/merge-functions2.ll | 7 +-
.../SimplifyCFG/ARM/switch-to-lookup-table.ll | 2 +-
.../Hexagon/switch-to-lookup-table.ll | 5 +-
.../RISCV/switch-of-powers-of-two.ll | 5 +-
.../X86/debugloc-switch-powers-of-two.ll | 9 ++-
.../SimplifyCFG/X86/switch-covered-bug.ll | 5 +-
.../X86/switch-of-powers-of-two.ll | 26 ++++---
.../SimplifyCFG/X86/switch-table-bug.ll | 5 +-
.../SimplifyCFG/X86/switch_to_lookup_table.ll | 77 +++++++++++--------
.../X86/switch_to_lookup_table_big.ll | 49 +++++++-----
.../switch-dead-default-lookup-table.ll | 5 +-
.../Transforms/SimplifyCFG/switch_mask.ll | 5 +-
13 files changed, 136 insertions(+), 87 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 9182ba6701834..c5b40aa30da14 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6970,8 +6970,23 @@ SwitchReplacement::SwitchReplacement(
return;
}
+ if (auto *IT = dyn_cast<IntegerType>(ValueType)) {
+ ConstantRange Range(IT->getBitWidth(), false);
+ for (Constant *Value : TableContents)
+ if (!isa<UndefValue>(Value))
+ Range = Range.unionWith(cast<ConstantInt>(Value)->getValue());
+ // TODO: handle sign extension as well?
+ unsigned NeededBitWidth =
+ std::max(8u, unsigned(PowerOf2Ceil(Range.getActiveBits())));
+ if (NeededBitWidth < IT->getBitWidth()) {
+ IntegerType *DstTy = IntegerType::get(IT->getContext(), NeededBitWidth);
+ for (Constant *&Value : TableContents)
+ Value = ConstantFoldCastInstruction(Instruction::Trunc, Value, DstTy);
+ }
+ }
+
// Store the table in an array.
- auto *TableTy = ArrayType::get(ValueType, TableSize);
+ auto *TableTy = ArrayType::get(TableContents[0]->getType(), TableSize);
Initializer = ConstantArray::get(TableTy, TableContents);
Kind = LookupTableKind;
@@ -7045,7 +7060,11 @@ Value *SwitchReplacement::replaceSwitch(Value *Index, IRBuilder<> &Builder,
Value *GEPIndices[] = {ConstantInt::get(IndexTy, 0), Index};
Value *GEP =
Builder.CreateInBoundsGEP(ArrayTy, Table, GEPIndices, "switch.gep");
- return Builder.CreateLoad(ArrayTy->getElementType(), GEP, "switch.load");
+ Value *Load =
+ Builder.CreateLoad(ArrayTy->getElementType(), GEP, "switch.load");
+ if (Load->getType() == ValueType)
+ return Load;
+ return Builder.CreateZExt(Load, ValueType, "switch.ext");
}
}
llvm_unreachable("Unknown helper kind!");
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/merge-functions2.ll b/llvm/test/Transforms/PhaseOrdering/X86/merge-functions2.ll
index f90b4dcaa47bd..f9bbdced48bf8 100644
--- a/llvm/test/Transforms/PhaseOrdering/X86/merge-functions2.ll
+++ b/llvm/test/Transforms/PhaseOrdering/X86/merge-functions2.ll
@@ -12,11 +12,12 @@ define i32 @f(i32 noundef %x) {
; CHECK-NEXT: br i1 [[TMP0]], label %[[SWITCH_LOOKUP:.*]], label %[[SW_EPILOG:.*]]
; CHECK: [[SWITCH_LOOKUP]]:
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[X]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds nuw [4 x i8], ptr @switch.table.g, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds nuw i8, ptr @switch.table.g, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_EXT:%.*]] = zext i8 [[SWITCH_LOAD]] to i32
; CHECK-NEXT: br label %[[SW_EPILOG]]
; CHECK: [[SW_EPILOG]]:
-; CHECK-NEXT: [[X_ADDR_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], %[[SWITCH_LOOKUP]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: [[X_ADDR_0:%.*]] = phi i32 [ [[SWITCH_EXT]], %[[SWITCH_LOOKUP]] ], [ 0, %[[ENTRY]] ]
; CHECK-NEXT: ret i32 [[X_ADDR_0]]
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll b/llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll
index a51b816846cdc..79070ad378fb0 100644
--- a/llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll
+++ b/llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll
@@ -10,7 +10,7 @@
; RUN: opt -S -passes='simplifycfg<switch-to-lookup>' -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
; RUN: opt -S -passes='simplifycfg<switch-to-lookup>' -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
-; CHECK: @{{.*}} = private unnamed_addr constant [3 x i32] [i32 1234, i32 5678, i32 15532]
+; CHECK: @{{.*}} = private unnamed_addr constant [3 x i16] [i16 1234, i16 5678, i16 15532]
; ENABLE: @{{.*}} = private unnamed_addr constant [3 x ptr] [ptr @c1, ptr @c2, ptr @c3]
; DISABLE-NOT: @{{.*}} = private unnamed_addr constant [3 x ptr] [ptr @c1, ptr @c2, ptr @c3]
; ENABLE: @{{.*}} = private unnamed_addr constant [3 x ptr] [ptr @g1, ptr @g2, ptr @g3]
diff --git a/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll b/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll
index 88652f4da6180..0c3c66147fc51 100644
--- a/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll
+++ b/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll
@@ -13,8 +13,9 @@ define i32 @foo(i32 %x) section ".tcm_text" {
; ENABLE-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 6
; ENABLE-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; ENABLE: switch.lookup:
-; ENABLE-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds nuw [4 x i8], ptr @switch.table.foo, i32 [[X]]
-; ENABLE-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; ENABLE-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds nuw i8, ptr @switch.table.foo, i32 [[X]]
+; ENABLE-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; ENABLE-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; ENABLE-NEXT: br label [[RETURN]]
; ENABLE: return:
; ENABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 19, [[ENTRY:%.*]] ]
diff --git a/llvm/test/Transforms/SimplifyCFG/RISCV/switch-of-powers-of-two.ll b/llvm/test/Transforms/SimplifyCFG/RISCV/switch-of-powers-of-two.ll
index 42ae6d8fdd360..da83d9c456c17 100644
--- a/llvm/test/Transforms/SimplifyCFG/RISCV/switch-of-powers-of-two.ll
+++ b/llvm/test/Transforms/SimplifyCFG/RISCV/switch-of-powers-of-two.ll
@@ -35,8 +35,9 @@ define i32 @switch_of_powers(i32 %x) {
; RV64ZBB-NEXT: entry:
; RV64ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)
; RV64ZBB-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TMP0]] to i64
-; RV64ZBB-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers, i64 0, i64 [[TMP1]]
-; RV64ZBB-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; RV64ZBB-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i8], ptr @switch.table.switch_of_powers, i64 0, i64 [[TMP1]]
+; RV64ZBB-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; RV64ZBB-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; RV64ZBB-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/debugloc-switch-powers-of-two.ll b/llvm/test/Transforms/SimplifyCFG/X86/debugloc-switch-powers-of-two.ll
index db75e42f0ed22..e44b0aa31bb17 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/debugloc-switch-powers-of-two.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/debugloc-switch-powers-of-two.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --tool ./build/bin/opt --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes='simplifycfg<switch-to-lookup>' -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
;; As we replace the switch statement with a set of instructions that may more
;; efficiently perform the conditional check, the DILocation of the switch
@@ -19,11 +19,12 @@ define i32 @switch_of_powers_two_default_reachable(i32 %arg) !dbg !5 {
; CHECK-NEXT: br i1 [[TMP3]], label %[[SWITCH_LOOKUP:.*]], label %[[RETURN]], !dbg [[DBG8]]
; CHECK: [[SWITCH_LOOKUP]]:
; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[TMP2]] to i64, !dbg [[DBG8]]
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers_two_default_reachable, i64 0, i64 [[TMP4]], !dbg [[DBG8]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4, !dbg [[DBG8]]
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i8], ptr @switch.table.switch_of_powers_two_default_reachable, i64 0, i64 [[TMP4]], !dbg [[DBG8]]
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1, !dbg [[DBG8]]
+; CHECK-NEXT: [[SWITCH_EXT:%.*]] = zext i8 [[SWITCH_LOAD]] to i32, !dbg [[DBG8]]
; CHECK-NEXT: br label %[[RETURN]], !dbg [[DBG8]]
; CHECK: [[RETURN]]:
-; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SWITCH_LOAD]], %[[SWITCH_LOOKUP]] ], [ 5, %[[ENTRY_SPLIT]] ], [ 5, %[[ENTRY]] ]
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SWITCH_EXT]], %[[SWITCH_LOOKUP]] ], [ 5, %[[ENTRY_SPLIT]] ], [ 5, %[[ENTRY]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll
index 3abde486c4e35..da61048ddffab 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll
@@ -11,8 +11,9 @@ define i64 @test(i3 %arg) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[ARG:%.*]], -4
; CHECK-NEXT: [[TMP0:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i64], ptr @switch.table.test, i64 0, i64 [[TMP0]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i8], ptr @switch.table.test, i64 0, i64 [[TMP0]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i64
; CHECK-NEXT: [[V3:%.*]] = add i64 [[SWITCH_LOAD]], 0
; CHECK-NEXT: ret i64 [[V3]]
;
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch-of-powers-of-two.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch-of-powers-of-two.ll
index c737a8a25be3b..ad95af47a286b 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch-of-powers-of-two.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch-of-powers-of-two.ll
@@ -4,9 +4,9 @@
target triple = "x86_64-unknown-linux-gnu"
;.
-; CHECK: @switch.table.switch_of_powers_two = private unnamed_addr constant [7 x i32] [i32 3, i32 poison, i32 poison, i32 2, i32 1, i32 0, i32 42], align 4
-; CHECK: @switch.table.switch_of_powers_two_default_reachable = private unnamed_addr constant [7 x i32] [i32 3, i32 5, i32 5, i32 2, i32 1, i32 0, i32 42], align 4
-; CHECK: @switch.table.switch_of_powers_two_default_reachable_multipreds = private unnamed_addr constant [7 x i32] [i32 3, i32 poison, i32 poison, i32 2, i32 1, i32 0, i32 42], align 4
+; CHECK: @switch.table.switch_of_powers_two = private unnamed_addr constant [7 x i8] [i8 3, i8 poison, i8 poison, i8 2, i8 1, i8 0, i8 42], align 4
+; CHECK: @switch.table.switch_of_powers_two_default_reachable = private unnamed_addr constant [7 x i8] c"\03\05\05\02\01\00*", align 4
+; CHECK: @switch.table.switch_of_powers_two_default_reachable_multipreds = private unnamed_addr constant [7 x i8] [i8 3, i8 poison, i8 poison, i8 2, i8 1, i8 0, i8 42], align 4
;.
define i32 @switch_of_powers_two(i32 %arg) {
; CHECK-LABEL: define i32 @switch_of_powers_two(
@@ -14,8 +14,9 @@ define i32 @switch_of_powers_two(i32 %arg) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 true)
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TMP0]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers_two, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i8], ptr @switch.table.switch_of_powers_two, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
@@ -53,11 +54,12 @@ define i32 @switch_of_powers_two_default_reachable(i32 %arg) !prof !0 {
; CHECK-NEXT: br i1 [[TMP3]], label %[[SWITCH_LOOKUP:.*]], label %[[RETURN]], !prof [[PROF2:![0-9]+]]
; CHECK: [[SWITCH_LOOKUP]]:
; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[TMP2]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers_two_default_reachable, i64 0, i64 [[TMP4]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i8], ptr @switch.table.switch_of_powers_two_default_reachable, i64 0, i64 [[TMP4]]
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_EXT:%.*]] = zext i8 [[SWITCH_LOAD]] to i32
; CHECK-NEXT: br label %[[RETURN]]
; CHECK: [[RETURN]]:
-; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SWITCH_LOAD]], %[[SWITCH_LOOKUP]] ], [ 5, %[[ENTRY_SPLIT]] ], [ 5, %[[ENTRY]] ]
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SWITCH_EXT]], %[[SWITCH_LOOKUP]] ], [ 5, %[[ENTRY_SPLIT]] ], [ 5, %[[ENTRY]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
entry:
@@ -100,11 +102,12 @@ define i32 @switch_of_powers_two_default_reachable_multipreds(i32 %arg, i1 %cond
; CHECK-NEXT: br i1 [[OR_COND]], label %[[SWITCH_LOOKUP:.*]], label %[[RETURN]]
; CHECK: [[SWITCH_LOOKUP]]:
; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[TMP2]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers_two_default_reachable_multipreds, i64 0, i64 [[TMP4]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i8], ptr @switch.table.switch_of_powers_two_default_reachable_multipreds, i64 0, i64 [[TMP4]]
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_EXT:%.*]] = zext i8 [[SWITCH_LOAD]] to i32
; CHECK-NEXT: br label %[[RETURN]]
; CHECK: [[RETURN]]:
-; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SWITCH_LOAD]], %[[SWITCH_LOOKUP]] ], [ 0, %[[ENTRY]] ], [ [[ARG]], %[[SWITCH]] ], [ [[ARG]], %[[SWITCH_SPLIT]] ]
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SWITCH_EXT]], %[[SWITCH_LOOKUP]] ], [ 0, %[[ENTRY]] ], [ [[ARG]], %[[SWITCH]] ], [ [[ARG]], %[[SWITCH_SPLIT]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
entry:
@@ -138,6 +141,7 @@ return:
!1 = !{!"branch_weights", i32 10, i32 5, i32 7, i32 11, i32 13, i32 17}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
;.
; CHECK: [[PROF0]] = !{!"function_entry_count", i32 10}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 58, i32 5}
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll
index 63c16a2f7b84c..dcbdd56711ba5 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll
@@ -11,8 +11,9 @@ define i64 @_TFO6reduce1E5toRawfS0_FT_Si(i2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TMP0:%.*]], -2
; CHECK-NEXT: [[TMP1:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i64], ptr @switch.table._TFO6reduce1E5toRawfS0_FT_Si, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i8], ptr @switch.table._TFO6reduce1E5toRawfS0_FT_Si, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i64
; CHECK-NEXT: ret i64 [[SWITCH_LOAD]]
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
index 9209c355f7585..cce11c12cb53e 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
@@ -27,21 +27,21 @@ target triple = "x86_64-unknown-linux-gnu"
; CHECK: @switch.table.char = private unnamed_addr constant [9 x i8] c"7{\00\FF\1B>\01!T", align 1
; CHECK: @switch.table.h = private unnamed_addr constant [4 x float] [float 3.140000e+00, float 1.234000e+00, float 4.567000e+00, float 2.210000e+00], align 4
; CHECK: @switch.table.foostring = private unnamed_addr constant [4 x ptr] [ptr @.str, ptr @.str1, ptr @.str2, ptr @.str3], align 8
-; CHECK: @switch.table.earlyreturncrash = private unnamed_addr constant [4 x i32] [i32 42, i32 9, i32 88, i32 5], align 4
-; CHECK: @switch.table.earlyreturncrash.1 = private unnamed_addr constant [4 x i32] [i32 3, i32 4, i32 1, i32 5], align 4
-; 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
+; CHECK: @switch.table.earlyreturncrash = private unnamed_addr constant [4 x i8] c"*\09X\05", align 4
+; CHECK: @switch.table.earlyreturncrash.1 = private unnamed_addr constant [4 x i8] c"\03\04\01\05", align 4
+; CHECK: @switch.table.large = private unnamed_addr constant [199 x i16] [i16 1, i16 4, i16 9, i16 16, i16 25, i16 36, i16 49, i16 64, i16 81, i16 100, i16 121, i16 144, i16 169, i16 196, i16 225, i16 256, i16 289, i16 342, i16 361, i16 400, i16 441, i16 484, i16 529, i16 576, i16 625, i16 676, i16 729, i16 784, i16 841, i16 900, i16 961, i16 1024, i16 1089, i16 1156, i16 1260, i16 1296, i16 1369, i16 1444, i16 1521, i16 1600, i16 1681, i16 1764, i16 1849, i16 1980, i16 2025, i16 2116, i16 2209, i16 2304, i16 2401, i16 2500, i16 2601, i16 2704, i16 2809, i16 2970, i16 3025, i16 3136, i16 3249, i16 3364, i16 3481, i16 3600, i16 3721, i16 3844, i16 3969, i16 4096, i16 4225, i16 4356, i16 4489, i16 4624, i16 4761, i16 4900, i16 5112, i16 5184, i16 5329, i16 5476, i16 5625, i16 5776, i16 5929, i16 6084, i16 6241, i16 6400, i16 6561, i16 6724, i16 6889, i16 7056, i16 7225, i16 7396, i16 7569, i16 7744, i16 7921, i16 8100, i16 8281, i16 8464, i16 8649, i16 8836, i16 9025, i16 9216, i16 9409, i16 9604, i16 9801, i16 10000, i16 10201, i16 10404, i16 10609, i16 10816, i16 11025, i16 11236, i16 11449, i16 11664, i16 11881, i16 12100, i16 12321, i16 12544, i16 12769, i16 12996, i16 13225, i16 13456, i16 13689, i16 13924, i16 14161, i16 14400, i16 14641, i16 14884, i16 15129, i16 15376, i16 15625, i16 15876, i16 16129, i16 16384, i16 16641, i16 16900, i16 17161, i16 17424, i16 17689, i16 17956, i16 18225, i16 18496, i16 18769, i16 19044, i16 19321, i16 19600, i16 19881, i16 20164, i16 20449, i16 20736, i16 21025, i16 21316, i16 21609, i16 21904, i16 22201, i16 22500, i16 22801, i16 23104, i16 23409, i16 23716, i16 24025, i16 24336, i16 24649, i16 24964, i16 25281, i16 25600, i16 25921, i16 26244, i16 26569, i16 26896, i16 27225, i16 27556, i16 27889, i16 28224, i16 28561, i16 28900, i16 29241, i16 29584, i16 29929, i16 30276, i16 30625, i16 30976, i16 31329, i16 31684, i16 32041, i16 32400, i16 32761, i16 -32412, i16 -32047, i16 -31680, i16 -31311, i16 -30940, i16 -30567, i16 -30192, i16 -29815, i16 -29436, i16 -29055, i16 -28672, i16 -28287, i16 -27900, i16 -27511, i16 -27120, i16 -26727, i16 -26332, i16 -25935], align 4
; 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
; 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
-; CHECK: @switch.table.unreachable_default = private unnamed_addr constant [4 x i32] [i32 42, i32 52, i32 1, i32 2], align 4
+; CHECK: @switch.table.unreachable_default = private unnamed_addr constant [4 x i8] c"*4\01\02", align 4
; CHECK: @switch.table.nodefaultnoholes = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1], align 4
; 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
-; CHECK: @switch.table.threecases = private unnamed_addr constant [3 x i32] [i32 10, i32 7, i32 5], align 4
-; 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
-; CHECK: @switch.table.signed_overflow1 = private unnamed_addr constant [4 x i32] [i32 3333, i32 4444, i32 1111, i32 2222], align 4
-; CHECK: @switch.table.signed_overflow2 = private unnamed_addr constant [4 x i32] [i32 3333, i32 4444, i32 poison, i32 2222], align 4
-; 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
-; 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
-; 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
+; CHECK: @switch.table.threecases = private unnamed_addr constant [3 x i8] c"\0A\07\05", align 4
+; CHECK: @switch.table.covered_switch_with_bit_tests = private unnamed_addr constant [8 x i8] [i8 2, i8 2, i8 poison, i8 poison, i8 poison, i8 poison, i8 1, i8 1], align 4
+; CHECK: @switch.table.signed_overflow1 = private unnamed_addr constant [4 x i16] [i16 3333, i16 4444, i16 1111, i16 2222], align 4
+; CHECK: @switch.table.signed_overflow2 = private unnamed_addr constant [4 x i16] [i16 3333, i16 4444, i16 poison, i16 2222], align 4
+; CHECK: @switch.table.constant_hole_unreachable_default_firstundef = private unnamed_addr constant [5 x i8] [i8 undef, i8 poison, i8 1, i8 1, i8 1], align 4
+; CHECK: @switch.table.constant_hole_unreachable_default_lastundef = private unnamed_addr constant [5 x i8] [i8 1, i8 poison, i8 1, i8 1, i8 undef], align 4
+; CHECK: @switch.table.linearmap_hole_unreachable_default = private unnamed_addr constant [5 x i8] [i8 1, i8 poison, i8 5, i8 7, i8 9], align 4
;.
define i32 @f(i32 %c) {
; CHECK-LABEL: @f(
@@ -226,11 +226,13 @@ define i32 @earlyreturncrash(i32 %x) {
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[X]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.earlyreturncrash, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i8], ptr @switch.table.earlyreturncrash, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64
-; CHECK-NEXT: [[SWITCH_GEP1:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.earlyreturncrash.1, i64 0, i64 [[TMP2]]
-; CHECK-NEXT: [[SWITCH_LOAD2:%.*]] = load i32, ptr [[SWITCH_GEP1]], align 4
+; CHECK-NEXT: [[SWITCH_GEP1:%.*]] = getelementptr inbounds [4 x i8], ptr @switch.table.earlyreturncrash.1, i64 0, i64 [[TMP2]]
+; CHECK-NEXT: [[SWITCH_LOAD3:%.*]] = load i8, ptr [[SWITCH_GEP1]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD2:%.*]] = zext i8 [[SWITCH_LOAD3]] to i32
; CHECK-NEXT: br label [[SW_EPILOG]]
; CHECK: sw.epilog:
; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ]
@@ -411,8 +413,9 @@ define i32 @large(i32 %x) {
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[SWITCH_TABLEIDX]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [199 x i32], ptr @switch.table.large, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [199 x i16], ptr @switch.table.large, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i16, ptr [[SWITCH_GEP]], align 2
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i16 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 0, [[ENTRY:%.*]] ]
@@ -930,8 +933,9 @@ define i32 @unreachable_default(i32 %x) {
; CHECK-LABEL: @unreachable_default(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[X:%.*]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.unreachable_default, i64 0, i64 [[TMP0]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i8], ptr @switch.table.unreachable_default, i64 0, i64 [[TMP0]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
@@ -1115,8 +1119,9 @@ define i32 @threecases(i32 %c) {
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[C]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32], ptr @switch.table.threecases, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i8], ptr @switch.table.threecases, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 3, [[ENTRY:%.*]] ]
@@ -1575,8 +1580,9 @@ define i32 @covered_switch_with_bit_tests(i3) !prof !0 {
; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[L6:%.*]], !prof [[PROF1:![0-9]+]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[TMP1:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i32], ptr @switch.table.covered_switch_with_bit_tests, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i8], ptr @switch.table.covered_switch_with_bit_tests, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: br label [[L6]]
; CHECK: l6:
; CHECK-NEXT: [[R:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ]
@@ -1728,8 +1734,9 @@ define i32 @signed_overflow1(i8 %n) {
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2
; CHECK-NEXT: [[TMP0:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow1, i64 0, i64 [[TMP0]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i16], ptr @switch.table.signed_overflow1, i64 0, i64 [[TMP0]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i16, ptr [[SWITCH_GEP]], align 2
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i16 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
start:
@@ -1764,8 +1771,9 @@ define i32 @signed_overflow2(i8 %n) {
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2
; CHECK-NEXT: [[TMP0:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow2, i64 0, i64 [[TMP0]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i16], ptr @switch.table.signed_overflow2, i64 0, i64 [[TMP0]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i16, ptr [[SWITCH_GEP]], align 2
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i16 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
start:
@@ -2229,8 +2237,9 @@ define i32 @constant_hole_unreachable_default_firstundef(i32 %x) {
; CHECK-LABEL: @constant_hole_unreachable_default_firstundef(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[X:%.*]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr @switch.table.constant_hole_unreachable_default_firstundef, i64 0, i64 [[TMP0]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i8], ptr @switch.table.constant_hole_unreachable_default_firstundef, i64 0, i64 [[TMP0]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
@@ -2256,8 +2265,9 @@ define i32 @constant_hole_unreachable_default_lastundef(i32 %x) {
; CHECK-LABEL: @constant_hole_unreachable_default_lastundef(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[X:%.*]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr @switch.table.constant_hole_unreachable_default_lastundef, i64 0, i64 [[TMP0]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i8], ptr @switch.table.constant_hole_unreachable_default_lastundef, i64 0, i64 [[TMP0]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
@@ -2375,8 +2385,9 @@ define i32 @linearmap_hole_unreachable_default(i32 %x) {
; CHECK-LABEL: @linearmap_hole_unreachable_default(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[X:%.*]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr @switch.table.linearmap_hole_unreachable_default, i64 0, i64 [[TMP0]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [5 x i8], ptr @switch.table.linearmap_hole_unreachable_default, i64 0, i64 [[TMP0]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table_big.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table_big.ll
index 54c4bac39f4c6..fcf43f6a45cee 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table_big.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table_big.ll
@@ -5,13 +5,13 @@ target triple = "i386-pc-linux-gnu"
; A dense switch with a reachable default case should be optimized into a lookup table with a bounds check
;.
-; 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
-; 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
-; 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
-; 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
-; 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
-; 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
-; 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
+; CHECK: @switch.table.reachable_default_dense_0to31 = private unnamed_addr constant [32 x i8] c"\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01", align 4
+; CHECK: @switch.table.unreachable_default_dense_0to31 = private unnamed_addr constant [32 x i8] c"\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01", align 4
+; CHECK: @switch.table.reachable_default_holes_0to31 = private unnamed_addr constant [32 x i8] [i8 0, i8 7, i8 6, i8 poison, i8 4, i8 3, i8 2, i8 1, i8 poison, i8 7, i8 6, i8 5, i8 4, i8 poison, i8 2, i8 1, i8 0, i8 7, i8 poison, i8 5, i8 4, i8 3, i8 2, i8 poison, i8 0, i8 7, i8 6, i8 5, i8 poison, i8 3, i8 2, i8 1], align 4
+; CHECK: @switch.table.unreachable_default_holes_0to31 = private unnamed_addr constant [32 x i8] [i8 0, i8 7, i8 6, i8 poison, i8 4, i8 3, i8 2, i8 1, i8 poison, i8 7, i8 6, i8 5, i8 4, i8 poison, i8 2, i8 1, i8 0, i8 7, i8 poison, i8 5, i8 4, i8 3, i8 2, i8 poison, i8 0, i8 7, i8 6, i8 5, i8 poison, i8 3, i8 2, i8 1], align 4
+; CHECK: @switch.table.reachable_default_dense_0to32 = private unnamed_addr constant [33 x i8] c"\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00", align 4
+; CHECK: @switch.table.unreachable_default_dense_0to32 = private unnamed_addr constant [33 x i8] c"\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00\07\06\05\04\03\02\01\00", align 4
+; CHECK: @switch.table.unreachable_default_holes_0to32 = private unnamed_addr constant [33 x i8] [i8 0, i8 7, i8 6, i8 poison, i8 4, i8 3, i8 2, i8 1, i8 poison, i8 7, i8 6, i8 5, i8 4, i8 poison, i8 2, i8 1, i8 0, i8 7, i8 poison, i8 5, i8 4, i8 3, i8 2, i8 poison, i8 0, i8 7, i8 6, i8 5, i8 poison, i8 3, i8 2, i8 1, i8 0], align 4
;.
define i32 @reachable_default_dense_0to31(i32 %x, i32 %y) {
; CHECK-LABEL: @reachable_default_dense_0to31(
@@ -19,8 +19,9 @@ define i32 @reachable_default_dense_0to31(i32 %x, i32 %y) {
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 32
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.reachable_default_dense_0to31, i32 0, i32 [[X]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i8], ptr @switch.table.reachable_default_dense_0to31, i32 0, i32 [[X]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
@@ -82,8 +83,9 @@ return:
define i32 @unreachable_default_dense_0to31(i32 %x, i32 %y) {
; CHECK-LABEL: @unreachable_default_dense_0to31(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.unreachable_default_dense_0to31, i32 0, i32 [[X:%.*]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i8], ptr @switch.table.unreachable_default_dense_0to31, i32 0, i32 [[X:%.*]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
@@ -148,8 +150,9 @@ define i32 @reachable_default_holes_0to31(i32 %x, i32 %y) {
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_LOBIT]], i1 false
; CHECK-NEXT: br i1 [[OR_COND]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.reachable_default_holes_0to31, i32 0, i32 [[X]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i8], ptr @switch.table.reachable_default_holes_0to31, i32 0, i32 [[X]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
@@ -205,8 +208,9 @@ return:
define i32 @unreachable_default_holes_0to31(i32 %x, i32 %y) {
; CHECK-LABEL: @unreachable_default_holes_0to31(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i32], ptr @switch.table.unreachable_default_holes_0to31, i32 0, i32 [[X:%.*]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [32 x i8], ptr @switch.table.unreachable_default_holes_0to31, i32 0, i32 [[X:%.*]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
@@ -262,8 +266,9 @@ define i32 @reachable_default_dense_0to32(i32 %x, i32 %y) {
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 33
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i32], ptr @switch.table.reachable_default_dense_0to32, i32 0, i32 [[X]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i8], ptr @switch.table.reachable_default_dense_0to32, i32 0, i32 [[X]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ]
@@ -326,8 +331,9 @@ return:
define i32 @unreachable_default_dense_0to32(i32 %x, i32 %y) {
; CHECK-LABEL: @unreachable_default_dense_0to32(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i32], ptr @switch.table.unreachable_default_dense_0to32, i32 0, i32 [[X:%.*]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i8], ptr @switch.table.unreachable_default_dense_0to32, i32 0, i32 [[X:%.*]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
@@ -489,8 +495,9 @@ return:
define i32 @unreachable_default_holes_0to32(i32 %x, i32 %y) {
; CHECK-LABEL: @unreachable_default_holes_0to32(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i32], ptr @switch.table.unreachable_default_holes_0to32, i32 0, i32 [[X:%.*]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [33 x i8], ptr @switch.table.unreachable_default_holes_0to32, i32 0, i32 [[X:%.*]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-dead-default-lookup-table.ll b/llvm/test/Transforms/SimplifyCFG/switch-dead-default-lookup-table.ll
index 72eea9a064ebd..45dce6c66b661 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-dead-default-lookup-table.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-dead-default-lookup-table.ll
@@ -8,8 +8,9 @@ define i64 @test_1(i64 %0) {
; CHECK-SAME: i64 [[TMP0:%.*]]) {
; CHECK-NEXT: switch.lookup:
; CHECK-NEXT: [[TMP1:%.*]] = urem i64 [[TMP0]], 4
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i64], ptr @switch.table.test_1, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i8], ptr @switch.table.test_1, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i64
; CHECK-NEXT: ret i64 [[SWITCH_LOAD]]
;
%2 = urem i64 %0, 4
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
index 428c18fc18e3d..70191701ed5eb 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
@@ -187,8 +187,9 @@ define void @switch_lookup_with_nonconst_range(i32 %x, i1 %cond) {
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[LOR_END:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[ADD]] to i64
-; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [6 x i32], ptr @switch.table.switch_lookup_with_nonconst_range, i64 0, i64 [[TMP1]]
-; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
+; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [6 x i8], ptr @switch.table.switch_lookup_with_nonconst_range, i64 0, i64 [[TMP1]]
+; CHECK-NEXT: [[SWITCH_LOAD1:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
+; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = zext i8 [[SWITCH_LOAD1]] to i32
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 1, [[FOR_END]] ]
More information about the llvm-commits
mailing list