diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 09f4fb2e139..f924eebb0df 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -2211,17 +2211,28 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) { // If the default value is unreachable, figure out the most popular // destination and make it the default. if (SI->getSuccessor(0) == BB) { - std::map Popularity; - for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) - Popularity[SI->getSuccessor(i)]++; - + std::map > Popularity; + for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) { + std::pair& entry = + Popularity[SI->getSuccessor(i)]; + if (entry.first == 0) { + entry.first = 1; + entry.second = i; + } else { + entry.first++; + } + } + // Find the most popular block. unsigned MaxPop = 0; + unsigned MaxIndex = 0; BasicBlock *MaxBlock = 0; - for (std::map::iterator + for (std::map >::iterator I = Popularity.begin(), E = Popularity.end(); I != E; ++I) { - if (I->second > MaxPop) { - MaxPop = I->second; + if (I->second.first > MaxPop || + (I->second.first == MaxPop && MaxIndex > I->second.second)) { + MaxPop = I->second.first; + MaxIndex = I->second.second; MaxBlock = I->first; } } diff --git a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll index 7133d9875ca..4a692f3622e 100644 --- a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll +++ b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll @@ -1,33 +1,73 @@ -; RUN: opt < %s -simplifycfg -S | not grep unreachable +; RUN: opt < %s -simplifycfg -S | FileCheck %s define void @test1(i1 %C, i1* %BP) { +; CHECK: @test1 +; CHECK: entry: +; CHECK-NEXT: ret void +entry: br i1 %C, label %T, label %F -T: ; preds = %0 +T: store i1 %C, i1* %BP unreachable -F: ; preds = %0 +F: ret void } define void @test2() { +; CHECK: @test2 +; CHECK: entry: +; CHECK-NEXT: call void @test2() +; CHECK-NEXT: ret void +entry: invoke void @test2( ) to label %N unwind label %U -U: ; preds = %0 +U: unreachable -N: ; preds = %0 +N: ret void } define i32 @test3(i32 %v) { +; CHECK: @test3 +; CHECK: entry: +; CHECK-NEXT: [[CMP:%[A-Za-z0-9]+]] = icmp eq i32 %v, 2 +; CHECK-NEXT: select i1 [[CMP]], i32 2, i32 1 +; CHECK-NEXT: ret +entry: switch i32 %v, label %default [ i32 1, label %U i32 2, label %T ] -default: ; preds = %0 +default: ret i32 1 -U: ; preds = %0 +U: unreachable -T: ; preds = %0 +T: ret i32 2 } +; PR9450 +define i32 @test4(i32 %v) { +; CHECK: entry: +; CHECK-NEXT: switch i32 %v, label %T [ +; CHECK-NEXT: i32 3, label %V +; CHECK-NEXT: i32 2, label %U +; CHECK-NEXT: ] + +entry: + br label %SWITCH +V: + ret i32 7 +SWITCH: + switch i32 %v, label %default [ + i32 1, label %T + i32 2, label %U + i32 3, label %V + ] +default: + unreachable +U: + ret i32 1 +T: + ret i32 2 +}