From 506cfb7ab745c49841675e969b01ea2ec3707df2 Mon Sep 17 00:00:00 2001 From: Jun Bum Lim Date: Fri, 23 Jun 2017 16:12:37 +0000 Subject: [PATCH] [InlineCost] Do not take INT_MAX when Cost is negative Summary: visitSwitchInst should not take INT_MAX when Cost is negative. Instead of INT_MAX , we also use a valid upperbound cost when overflow occurs in Cost. Reviewers: hans, echristo, dmgreen Reviewed By: dmgreen Subscribers: mcrosier, javed.absar, llvm-commits, eraman Differential Revision: https://reviews.llvm.org/D34436 llvm-svn: 306118 --- llvm/lib/Analysis/InlineCost.cpp | 16 +++++--- llvm/test/Transforms/Inline/AArch64/switch.ll | 37 +++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index 6ff5938a3175..77ad6f1e166f 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -1022,12 +1022,15 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) { // inlining those. It will prevent inlining in cases where the optimization // does not (yet) fire. + // Maximum valid cost increased in this function. + int CostUpperBound = INT_MAX - InlineConstants::InstrCost - 1; + // Exit early for a large switch, assuming one case needs at least one // instruction. // FIXME: This is not true for a bit test, but ignore such case for now to // save compile-time. int64_t CostLowerBound = - std::min((int64_t)INT_MAX, + std::min((int64_t)CostUpperBound, (int64_t)SI.getNumCases() * InlineConstants::InstrCost + Cost); if (CostLowerBound > Threshold) { @@ -1044,7 +1047,8 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) { if (JumpTableSize) { int64_t JTCost = (int64_t)JumpTableSize * InlineConstants::InstrCost + 4 * InlineConstants::InstrCost; - Cost = std::min((int64_t)INT_MAX, JTCost + Cost); + + Cost = std::min((int64_t)CostUpperBound, JTCost + Cost); return false; } @@ -1068,10 +1072,12 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) { Cost += NumCaseCluster * 2 * InlineConstants::InstrCost; return false; } - int64_t ExpectedNumberOfCompare = 3 * (uint64_t)NumCaseCluster / 2 - 1; - uint64_t SwitchCost = + + int64_t ExpectedNumberOfCompare = 3 * (int64_t)NumCaseCluster / 2 - 1; + int64_t SwitchCost = ExpectedNumberOfCompare * 2 * InlineConstants::InstrCost; - Cost = std::min((uint64_t)INT_MAX, SwitchCost + Cost); + + Cost = std::min((int64_t)CostUpperBound, SwitchCost + Cost); return false; } diff --git a/llvm/test/Transforms/Inline/AArch64/switch.ll b/llvm/test/Transforms/Inline/AArch64/switch.ll index a530ba734705..154956e2b758 100644 --- a/llvm/test/Transforms/Inline/AArch64/switch.ll +++ b/llvm/test/Transforms/Inline/AArch64/switch.ll @@ -121,3 +121,40 @@ define i32 @caller_jumptable(i32 %a, i32 %b, i32* %P) { ret i32 %r } + +define internal i32 @callee_negativeCost(i32 %t) { +entry: + switch i32 %t, label %sw.default [ + i32 1, label %sw.bb + i32 0, label %sw.bb1 + i32 42, label %sw.bb2 + i32 43, label %sw.bb3 + ] + +sw.bb: ; preds = %entry + br label %cleanup + +sw.bb1: ; preds = %entry + br label %cleanup + +sw.bb2: ; preds = %entry + br label %cleanup + +sw.bb3: ; preds = %entry + br label %cleanup + +sw.default: ; preds = %entry + br label %cleanup + +cleanup: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb + %retval.0 = phi i32 [ 1, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 0, %sw.bb1 ], [ 0, %sw.bb ] + ret i32 %retval.0 +} + +define i32 @caller_negativeCost(i32 %t) { +; CHECK-LABEL: @caller_negativeCost( +; CHECK-NOT: call i32 @callee_negativeCost +entry: + %call = call i32 @callee_negativeCost(i32 %t) + ret i32 %call +}