diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 7c239cb19b70..60ac271bceb7 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4159,10 +4159,8 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder, if (!DefaultIsReachable || GeneratingCoveredLookupTable) { Builder.CreateBr(LookupBB); - // We cached PHINodes in PHIs, to avoid accessing deleted PHINodes later, - // do not delete PHINodes here. - SI->getDefaultDest()->removePredecessor(SI->getParent(), - /*DontDeleteUselessPHIs=*/true); + // Note: We call removeProdecessor later since we need to be able to get the + // PHI value for the default case in case we're using a bit mask. } else { Value *Cmp = Builder.CreateICmpULT(TableIndex, ConstantInt::get( MinCaseVal->getType(), TableSize)); @@ -4214,6 +4212,13 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder, AddPredecessorToBlock(SI->getDefaultDest(), MaskBB, SI->getParent()); } + if (!DefaultIsReachable || GeneratingCoveredLookupTable) { + // We cached PHINodes in PHIs, to avoid accessing deleted PHINodes later, + // do not delete PHINodes here. + SI->getDefaultDest()->removePredecessor(SI->getParent(), + /*DontDeleteUselessPHIs=*/true); + } + bool ReturnedEarly = false; for (size_t I = 0, E = PHIs.size(); I != E; ++I) { PHINode *PHI = PHIs[I]; 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 cdc0488991a4..732e7cafe5ee 100644 --- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -1273,3 +1273,32 @@ end: ; CHECK-LABEL: @pr20210 ; CHECK: switch i8 %x } + +; Make sure we do not crash due to trying to generate an unguarded +; lookup (since i3 can only hold values in the range of explicit +; values) and simultaneously trying to generate a branch to deal with +; the fact that we have holes in the range. +define i32 @covered_switch_with_bit_tests(i3) { +entry: + switch i3 %0, label %l6 [ + i3 -3, label %l5 + i3 -4, label %l5 + i3 3, label %l1 + i3 2, label %l1 + ] + +l1: br label %l2 + +l2: + %x = phi i32 [ 1, %l1 ], [ 2, %l5 ] + br label %l6 + +l5: br label %l2 + +l6: + %r = phi i32 [ %x, %l2 ], [ 0, %entry ] + ret i32 %r +; CHECK-LABEL: @covered_switch_with_bit_tests +; CHECK: entry +; CHECK-NEXT: switch +}