Index: lib/Transforms/IPO/Inliner.cpp =================================================================== --- lib/Transforms/IPO/Inliner.cpp +++ lib/Transforms/IPO/Inliner.cpp @@ -326,7 +326,7 @@ // one is set very low by getInlineCost, in anticipation that Caller will // be removed entirely. We did not account for this above unless there // is only one caller of Caller. - if (callerWillBeRemoved && !Caller->use_empty()) + if (callerWillBeRemoved && !Caller->hasOneUse()) TotalSecondaryCost -= InlineConstants::LastCallToStaticBonus; if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.getCost()) Index: test/Transforms/Inline/last-call-bonus.ll =================================================================== --- /dev/null +++ test/Transforms/Inline/last-call-bonus.ll @@ -0,0 +1,51 @@ +; The goal of this test is checking LastCallToStaticBonus is applied correctly. +; For the test code below, when inliner evaluates the callsite of bar->baz, it +; checks if inlining of bar->baz prevents ininling of foo->bar, even when +; foo->bar inlining is more beneficial than bar->baz inlining. +; As LastCallToStaticBonus has a massive value, and both baz and bar has only +; one caller, the cost of foo->bar inlining and bar->baz inlining should be +; non-trivial for inliner to compute that bar->baz inlining can actaully +; prevent foo->bar inlining. To make the cost of these callsites big enough, +; loop unrolling pass with very high threshold is used to preprocess the test. + +; RUN: opt < %s -loop-unroll -inline -unroll-threshold=15000 -inline-threshold=250 -S | FileCheck %s +; CHECK-LABEL: define internal i32 @bar() + +define internal i32 @baz() { +entry: + br label %bb1 + +bb1: + %ind = phi i32 [ 0, %entry ], [ %inc, %bb1 ] + call void @extern() + %inc = add nsw i32 %ind, 1 + %cmp = icmp sgt i32 %inc, 510 + br i1 %cmp, label %ret, label %bb1 + +ret: + ret i32 0 +} + +define internal i32 @bar() { +entry: + br label %bb1 + +bb1: + %ind = phi i32 [ 0, %entry ], [ %inc, %bb1 ] + call void @extern() + %inc = add nsw i32 %ind, 1 + %cmp = icmp sgt i32 %inc, 510 + br i1 %cmp, label %ret, label %bb1 + +ret: + call i32 @baz() + ret i32 0 +} + +define i32 @foo() { +entry: + call i32 @bar() + ret i32 0 +} + +declare void @extern()