getInlineCost delegates to InlineCostCallAnalyzer::analyze to do the actual analysis. Once the analysis is done getInlineCost tries to reverse engineer the result of the analysis in order to determine whether a detailed cost/threshold or a simple always/never should be returned.
// Check if there was a reason to force inlining or no inlining. if (!ShouldInline.isSuccess() && CA.getCost() < CA.getThreshold()) return InlineCost::getNever(ShouldInline.getFailureReason()); if (ShouldInline.isSuccess() && CA.getCost() >= CA.getThreshold()) return InlineCost::getAlways("empty function"); return llvm::InlineCost::get(CA.getCost(), CA.getThreshold());
This reverse engineering fails when ComputeFullInlineCost is enabled. Specifically, InlineCostCallAnalyzer::analyze can fail due to non-inlinable instruction (e.g. noduplicate call). With ComputeFullInlineCost enabled the cost can be above the threshold. In this case, the old code incorrectly returns a cost/threshold pair instead of never.
We ran across this issue with a downstream user of InlineCost. I found that upstream SampleProfile uses getInlineCost with ComputeFullInlineCost, so I added a test case demonstrating the issue via SampleProfile.
To fix this issue I mimic the approach used by cost-benefit analysis and add an explicit flag to InlineCostCallAnalyzer indicating that the result was decided by cost-threshold analysis.