diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index fe36fd84e0439..f3994b6cc39fe 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -5414,13 +5414,11 @@ static bool CasesAreContiguous(SmallVectorImpl &Cases) { } static void createUnreachableSwitchDefault(SwitchInst *Switch, - DomTreeUpdater *DTU, - bool RemoveOrigDefaultBlock = true) { + DomTreeUpdater *DTU) { LLVM_DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n"); auto *BB = Switch->getParent(); auto *OrigDefaultBlock = Switch->getDefaultDest(); - if (RemoveOrigDefaultBlock) - OrigDefaultBlock->removePredecessor(BB); + OrigDefaultBlock->removePredecessor(BB); BasicBlock *NewDefaultBlock = BasicBlock::Create( BB->getContext(), BB->getName() + ".unreachabledefault", BB->getParent(), OrigDefaultBlock); @@ -5429,8 +5427,7 @@ static void createUnreachableSwitchDefault(SwitchInst *Switch, if (DTU) { SmallVector Updates; Updates.push_back({DominatorTree::Insert, BB, &*NewDefaultBlock}); - if (RemoveOrigDefaultBlock && - !is_contained(successors(BB), OrigDefaultBlock)) + if (!is_contained(successors(BB), OrigDefaultBlock)) Updates.push_back({DominatorTree::Delete, BB, &*OrigDefaultBlock}); DTU->applyUpdates(Updates); } @@ -5612,33 +5609,10 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU, Known.getBitWidth() - (Known.Zero | Known.One).popcount(); assert(NumUnknownBits <= Known.getBitWidth()); if (HasDefault && DeadCases.empty() && - NumUnknownBits < 64 /* avoid overflow */) { - uint64_t AllNumCases = 1ULL << NumUnknownBits; - if (SI->getNumCases() == AllNumCases) { - createUnreachableSwitchDefault(SI, DTU); - return true; - } - // When only one case value is missing, replace default with that case. - // Eliminating the default branch will provide more opportunities for - // optimization, such as lookup tables. - if (SI->getNumCases() == AllNumCases - 1) { - assert(NumUnknownBits > 1 && "Should be canonicalized to a branch"); - IntegerType *CondTy = cast(Cond->getType()); - if (CondTy->getIntegerBitWidth() > 64 || - !DL.fitsInLegalInteger(CondTy->getIntegerBitWidth())) - return false; - - uint64_t MissingCaseVal = 0; - for (const auto &Case : SI->cases()) - MissingCaseVal ^= Case.getCaseValue()->getValue().getLimitedValue(); - auto *MissingCase = - cast(ConstantInt::get(Cond->getType(), MissingCaseVal)); - SwitchInstProfUpdateWrapper SIW(*SI); - SIW.addCase(MissingCase, SI->getDefaultDest(), SIW.getSuccessorWeight(0)); - createUnreachableSwitchDefault(SI, DTU, /*RemoveOrigDefaultBlock*/ false); - SIW.setSuccessorWeight(0, 0); - return true; - } + NumUnknownBits < 64 /* avoid overflow */ && + SI->getNumCases() == (1ULL << NumUnknownBits)) { + createUnreachableSwitchDefault(SI, DTU); + return true; } if (DeadCases.empty()) diff --git a/llvm/test/Transforms/SimplifyCFG/switch-dead-default-lookup-table.ll b/llvm/test/Transforms/SimplifyCFG/switch-dead-default-lookup-table.ll deleted file mode 100644 index bead0dc4c567a..0000000000000 --- a/llvm/test/Transforms/SimplifyCFG/switch-dead-default-lookup-table.ll +++ /dev/null @@ -1,61 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 -; RUN: opt %s -S -passes='simplifycfg' -simplifycfg-require-and-preserve-domtree=1 -switch-range-to-icmp | FileCheck %s - -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" - -define i64 @test_1(i64 %0) { -; CHECK-LABEL: define i64 @test_1( -; 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, i32 0, i64 [[TMP1]] -; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8 -; CHECK-NEXT: ret i64 [[SWITCH_LOAD]] -; - %2 = urem i64 %0, 4 - switch i64 %2, label %5 [ - i64 1, label %3 - i64 2, label %3 - i64 3, label %4 - ] - -3: - br label %5 - -4: - br label %5 - -5: - %.0 = phi i64 [ 2, %4 ], [ 1, %3 ], [ 0, %1 ] - ret i64 %.0 -} - - -define i64 @test_2(i64 %0) { -; CHECK-LABEL: define i64 @test_2( -; CHECK-SAME: i64 [[TMP0:%.*]]) { -; CHECK-NEXT: switch.lookup: -; CHECK-NEXT: [[TMP1:%.*]] = urem i64 [[TMP0]], 4 -; CHECK-NEXT: ret i64 [[TMP1]] -; - %2 = urem i64 %0, 4 - switch i64 %2, label %6 [ - i64 1, label %3 - i64 2, label %4 - i64 3, label %5 - ] - -3: - br label %6 - -4: - br label %6 - -5: - br label %6 - -6: - %.0 = phi i64 [ 0, %1 ], [ 1, %3 ], [ 2, %4 ], [ 3, %5 ] - ret i64 %.0 -} - diff --git a/llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll b/llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll index 4a457cc177e85..7c0d5e4f2b653 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll @@ -79,15 +79,15 @@ default: ret void } -; We can replace the default branch with case 3 since it is the only case that is missing. +; This one is a negative test - we know the value of the default, +; but that's about it define void @test3(i2 %a) { ; CHECK-LABEL: define void @test3( ; CHECK-SAME: i2 [[A:%.*]]) { -; CHECK-NEXT: switch i2 [[A]], label [[DOTUNREACHABLEDEFAULT:%.*]] [ +; CHECK-NEXT: switch i2 [[A]], label [[DEFAULT:%.*]] [ ; CHECK-NEXT: i2 0, label [[CASE0:%.*]] ; CHECK-NEXT: i2 1, label [[CASE1:%.*]] ; CHECK-NEXT: i2 -2, label [[CASE2:%.*]] -; CHECK-NEXT: i2 -1, label [[DEFAULT:%.*]] ; CHECK-NEXT: ] ; CHECK: common.ret: ; CHECK-NEXT: ret void @@ -100,8 +100,6 @@ define void @test3(i2 %a) { ; CHECK: case2: ; CHECK-NEXT: call void @foo(i32 2) ; CHECK-NEXT: br label [[COMMON_RET]] -; CHECK: .unreachabledefault: -; CHECK-NEXT: unreachable ; CHECK: default: ; CHECK-NEXT: call void @foo(i32 3) ; CHECK-NEXT: br label [[COMMON_RET]] @@ -124,50 +122,6 @@ default: ret void } -define void @test3_prof(i2 %a) { -; CHECK-LABEL: define void @test3_prof( -; CHECK-SAME: i2 [[A:%.*]]) { -; CHECK-NEXT: switch i2 [[A]], label [[DOTUNREACHABLEDEFAULT:%.*]] [ -; CHECK-NEXT: i2 0, label [[CASE0:%.*]] -; CHECK-NEXT: i2 1, label [[CASE1:%.*]] -; CHECK-NEXT: i2 -2, label [[CASE2:%.*]] -; CHECK-NEXT: i2 -1, label [[DEFAULT:%.*]] -; CHECK-NEXT: ], !prof [[PROF0:![0-9]+]] -; CHECK: common.ret: -; CHECK-NEXT: ret void -; CHECK: case0: -; CHECK-NEXT: call void @foo(i32 0) -; CHECK-NEXT: br label [[COMMON_RET:%.*]] -; CHECK: case1: -; CHECK-NEXT: call void @foo(i32 1) -; CHECK-NEXT: br label [[COMMON_RET]] -; CHECK: case2: -; CHECK-NEXT: call void @foo(i32 2) -; CHECK-NEXT: br label [[COMMON_RET]] -; CHECK: .unreachabledefault: -; CHECK-NEXT: unreachable -; CHECK: default: -; CHECK-NEXT: call void @foo(i32 3) -; CHECK-NEXT: br label [[COMMON_RET]] -; - switch i2 %a, label %default [i2 0, label %case0 - i2 1, label %case1 - i2 2, label %case2], !prof !0 - -case0: - call void @foo(i32 0) - ret void -case1: - call void @foo(i32 1) - ret void -case2: - call void @foo(i32 2) - ret void -default: - call void @foo(i32 3) - ret void -} - ; Negative test - check for possible overflow when computing ; number of possible cases. define void @test4(i128 %a) { @@ -313,40 +267,3 @@ default: declare void @llvm.assume(i1) -define zeroext i1 @test8(i128 %a) { -; We should not transform conditions wider than 64 bit. -; CHECK-LABEL: define zeroext i1 @test8( -; CHECK-SAME: i128 [[A:%.*]]) { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = and i128 [[A]], 3894222643901120721397872246915072 -; CHECK-NEXT: switch i128 [[TMP0]], label [[LOR_RHS:%.*]] [ -; CHECK-NEXT: i128 1298074214633706907132624082305024, label [[LOR_END:%.*]] -; CHECK-NEXT: i128 2596148429267413814265248164610048, label [[LOR_END]] -; CHECK-NEXT: i128 3894222643901120721397872246915072, label [[LOR_END]] -; CHECK-NEXT: ] -; CHECK: lor.rhs: -; CHECK-NEXT: br label [[LOR_END]] -; CHECK: lor.end: -; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ] -; CHECK-NEXT: ret i1 [[TMP1]] -; -entry: - %0 = and i128 %a, 3894222643901120721397872246915072 - switch i128 %0, label %lor.rhs [ - i128 1298074214633706907132624082305024, label %lor.end - i128 2596148429267413814265248164610048, label %lor.end - i128 3894222643901120721397872246915072, label %lor.end - ] - -lor.rhs: ; preds = %entry - br label %lor.end - -lor.end: ; preds = %entry, %entry, %entry, %lor.rhs - %1 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ] - ret i1 %1 -} - -!0 = !{!"branch_weights", i32 8, i32 4, i32 2, i32 1} -;. -; CHECK: [[PROF0]] = !{!"branch_weights", i32 0, i32 4, i32 2, i32 1, i32 8} -;.