From: Jun Bum Lim Date: Fri, 23 Jun 2017 16:12:37 +0000 (+0000) Subject: [InlineCost] Do not take INT_MAX when Cost is negative X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=910c8cc5329ce8c4a8b038c827aef07461996a5f;p=llvm [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306118 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp index 6ff5938a317..77ad6f1e166 100644 --- a/lib/Analysis/InlineCost.cpp +++ b/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/test/Transforms/Inline/AArch64/switch.ll b/test/Transforms/Inline/AArch64/switch.ll index a530ba73470..154956e2b75 100644 --- a/test/Transforms/Inline/AArch64/switch.ll +++ b/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 +}