diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 142f157c3c8..2591dbf7262 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -898,18 +898,21 @@ bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(TerminatorInst *TI, Weights[0] *= SuccWeights[0]; } } else { - // FIXME: preserve branch weight metadata, similarly to the 'then' - // above. For now, drop it. - PredHasWeights = false; - SuccHasWeights = false; - // If this is not the default destination from PSI, only the edges // in SI that occur in PSI with a destination of BB will be // activated. std::set PTIHandled; + std::map WeightsForHandled; for (unsigned i = 0, e = PredCases.size(); i != e; ++i) if (PredCases[i].Dest == BB) { PTIHandled.insert(PredCases[i].Value); + + if (PredHasWeights || SuccHasWeights) { + WeightsForHandled[PredCases[i].Value] = Weights[i+1]; + std::swap(Weights[i+1], Weights.back()); + Weights.pop_back(); + } + std::swap(PredCases[i], PredCases.back()); PredCases.pop_back(); --i; --e; @@ -920,6 +923,8 @@ bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(TerminatorInst *TI, for (unsigned i = 0, e = BBCases.size(); i != e; ++i) if (PTIHandled.count(BBCases[i].Value)) { // If this is one we are capable of getting... + if (PredHasWeights || SuccHasWeights) + Weights.push_back(WeightsForHandled[BBCases[i].Value]); PredCases.push_back(BBCases[i]); NewSuccessors.push_back(BBCases[i].Dest); PTIHandled.erase(BBCases[i].Value);// This constant is taken care of @@ -930,6 +935,8 @@ bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(TerminatorInst *TI, for (std::set::iterator I = PTIHandled.begin(), E = PTIHandled.end(); I != E; ++I) { + if (PredHasWeights || SuccHasWeights) + Weights.push_back(WeightsForHandled[*I]); PredCases.push_back(ValueEqualityComparisonCase(*I, BBDefault)); NewSuccessors.push_back(BBDefault); } diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll b/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll index 75f5f06daa7..941f5ad9d5b 100644 --- a/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll +++ b/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll @@ -84,9 +84,57 @@ sw.epilog: ret void } +;; test3 - Merge two switches where PredDefault != BB. +define void @test3(i32 %M, i32 %N) nounwind uwtable { +entry: + %cmp = icmp sgt i32 %M, 2 + br i1 %cmp, label %sw1, label %sw2 + +sw1: + switch i32 %N, label %sw.bb [ + i32 2, label %sw2 + i32 3, label %sw2 + i32 1, label %sw.bb1 + ], !prof !4 +; CHECK: test3 +; CHECK: switch i32 %N, label %sw.bb +; CHECK: i32 1, label %sw.bb1 +; CHECK: i32 3, label %sw.bb4 +; CHECK: i32 2, label %sw.epilog +; CHECK: ], !prof !3 + +sw.bb: + call void @func2(i32 %N) nounwind + br label %sw.epilog + +sw.bb1: + call void @func4(i32 %N) nounwind + br label %sw.epilog + +sw2: + switch i32 %N, label %sw.epilog [ + i32 3, label %sw.bb4 + i32 4, label %sw.bb5 + ], !prof !5 + +sw.bb4: + call void @func6(i32 %N) nounwind + br label %sw.epilog + +sw.bb5: + call void @func8(i32 %N) nounwind + br label %sw.epilog + +sw.epilog: + ret void +} + !0 = metadata !{metadata !"branch_weights", i32 64, i32 4} !1 = metadata !{metadata !"branch_weights", i32 4, i32 64} ; CHECK: !0 = metadata !{metadata !"branch_weights", i32 256, i32 4352, i32 16} !2 = metadata !{metadata !"branch_weights", i32 4, i32 4, i32 8} !3 = metadata !{metadata !"branch_weights", i32 8, i32 8, i32 4} ; CHECK: !1 = metadata !{metadata !"branch_weights", i32 32, i32 48, i32 96, i32 16} +!4 = metadata !{metadata !"branch_weights", i32 7, i32 6, i32 4, i32 3} +!5 = metadata !{metadata !"branch_weights", i32 17, i32 13, i32 9} +; CHECK: !3 = metadata !{metadata !"branch_weights", i32 7, i32 3, i32 4, i32 6}