From 65df808f6254617b9eee931d00e95d900610b660 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 30 Nov 2012 02:02:42 +0000 Subject: [PATCH] Fix logic to determine whether to turn a switch into a lookup table. When the tables cannot fit in registers (i.e. bitmap), do not emit the table if it's using an illegal type. rdar://12779436 llvm-svn: 168970 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 19 +++++++++++----- .../SimplifyCFG/X86/switch_to_lookup_table.ll | 26 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 6c34eed..611e466 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3511,22 +3511,29 @@ bool SwitchLookupTable::WouldFitInRegister(const DataLayout *TD, static bool ShouldBuildLookupTable(SwitchInst *SI, uint64_t TableSize, const DataLayout *TD, + const TargetTransformInfo *TTI, const SmallDenseMap& ResultTypes) { // The table density should be at least 40%. This is the same criterion as for // jump tables, see SelectionDAGBuilder::handleJTSwitchCase. // FIXME: Find the best cut-off. if (SI->getNumCases() > TableSize || TableSize >= UINT64_MAX / 10) return false; // TableSize overflowed, or mul below might overflow. - if (SI->getNumCases() * 10 >= TableSize * 4) - return true; // If each table would fit in a register, we should build it anyway. + bool AllFit = true; + bool HasIllegalType = false; for (SmallDenseMap::const_iterator I = ResultTypes.begin(), E = ResultTypes.end(); I != E; ++I) { - if (!SwitchLookupTable::WouldFitInRegister(TD, TableSize, I->second)) - return false; + Type *Ty = I->second; + if (!TTI->getScalarTargetTransformInfo()->isTypeLegal(Ty)) + HasIllegalType = true; + if (!SwitchLookupTable::WouldFitInRegister(TD, TableSize, Ty)) { + AllFit = false; + break; + } } - return true; + + return AllFit || (!HasIllegalType && (SI->getNumCases() * 10 >= TableSize * 4)); } /// SwitchToLookupTable - If the switch is only used to initialize one or more @@ -3607,7 +3614,7 @@ static bool SwitchToLookupTable(SwitchInst *SI, APInt RangeSpread = MaxCaseVal->getValue() - MinCaseVal->getValue(); uint64_t TableSize = RangeSpread.getLimitedValue() + 1; - if (!ShouldBuildLookupTable(SI, TableSize, TD, ResultTypes)) + if (!ShouldBuildLookupTable(SI, TableSize, TD, TTI, ResultTypes)) return false; // Create the BB that does the lookups. 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 8a59992..5f70465 100644 --- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -777,3 +777,29 @@ return: ; CHECK: switch.lookup: ; CHECK: getelementptr inbounds [5 x i32]* @switch.table6, i32 0, i32 %switch.tableidx } + +; Don't create a table with illegal type +; rdar://12779436 +define i96 @illegaltype(i32 %c) { +entry: + switch i32 %c, label %sw.default [ + i32 42, label %return + i32 43, label %sw.bb1 + i32 44, label %sw.bb2 + i32 45, label %sw.bb3 + i32 46, label %sw.bb4 + ] + +sw.bb1: br label %return +sw.bb2: br label %return +sw.bb3: br label %return +sw.bb4: br label %return +sw.default: br label %return +return: + %retval.0 = phi i96 [ 15, %sw.default ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] + ret i96 %retval.0 + +; CHECK: @illegaltype +; CHECK-NOT: @switch.table +; CHECK: switch i32 %c +} -- 2.7.4