From 13e46984973a46ee861fff91ec68c2141cb7ca47 Mon Sep 17 00:00:00 2001 From: Allen Date: Mon, 15 Apr 2024 10:19:49 +0800 Subject: [PATCH] [SimplifyCFG] Fix crash when there is unreachable large index (#88616) The large case index out of scope is dead code, but it is still be created for TableContents in SwitchLookupTable::SwitchLookupTable, so make sure the table size after growing should not get smaller. Fix https://github.com/llvm/llvm-project/issues/88607 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 4 ++- .../Transforms/SimplifyCFG/switch_mask.ll | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 55bbffb18879f..da3eb229c041f 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -6783,9 +6783,11 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder, return SwitchLookupTable::WouldFitInRegister( DL, UpperBound, KV.second /* ResultType */); })) { + // There may be some case index larger than the UpperBound (unreachable + // case), so make sure the table size does not get smaller. + TableSize = std::max(UpperBound, TableSize); // The default branch is unreachable after we enlarge the lookup table. // Adjust DefaultIsReachable to reuse code path. - TableSize = UpperBound; DefaultIsReachable = false; } } diff --git a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll index 17f7b583ee840..51c15774d4762 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll @@ -214,3 +214,28 @@ lor.end: ; preds = %default, %for.end, %retval.0.i.i = phi i32 [ 1, %default ], [ 0, %for.end ], [ 0, %for.end ], [ 0, %for.end ] ret void } + +define i1 @pr88607() { +; CHECK-LABEL: @pr88607( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[COND:%.*]] = select i1 false, i32 4, i32 1 +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 false, i32 2, i32 [[COND]] +; CHECK-NEXT: ret i1 false +; +entry: + %cond = select i1 false, i32 4, i32 1 + %spec.select = select i1 false, i32 2, i32 %cond + switch i32 %spec.select, label %lor.rhs [ + i32 0, label %exit + i32 5, label %exit ; unreachable large case index + i32 1, label %exit + ] + +lor.rhs: ; preds = %entry + br label %exit + +exit: ; preds = %lor.rhs, %entry, %entry, %entry, %entry + %res.ph = phi i1 [ false, %entry ], [ false, %lor.rhs ], [ false, %entry ], [ false, %entry ] + ret i1 %res.ph +} +