Skip to content

Commit

Permalink
Fix a crash in the assumption cache when inlining indirect function c…
Browse files Browse the repository at this point in the history
…alls

Summary:
Instances of the AssumptionCache are per function, so we can't re-use
the same AssumptionCache instance when recursing in the CallAnalyzer to
analyze a different function. Instead we have to pass the
AssumptionCacheTracker to the CallAnalyzer so it can get the right
AssumptionCache on demand.

Reviewers: hfinkel

Subscribers: llvm-commits, hans

Differential Revision: http://reviews.llvm.org/D7533

llvm-svn: 228957
  • Loading branch information
dotdash committed Feb 12, 2015
1 parent e8cb17f commit 6f972a1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
12 changes: 6 additions & 6 deletions llvm/lib/Analysis/IPA/InlineCost.cpp
Expand Up @@ -52,7 +52,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
const TargetTransformInfo &TTI;

/// The cache of @llvm.assume intrinsics.
AssumptionCache &AC;
AssumptionCacheTracker *ACT;

// The called function.
Function &F;
Expand Down Expand Up @@ -146,8 +146,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {

public:
CallAnalyzer(const DataLayout *DL, const TargetTransformInfo &TTI,
AssumptionCache &AC, Function &Callee, int Threshold)
: DL(DL), TTI(TTI), AC(AC), F(Callee), Threshold(Threshold), Cost(0),
AssumptionCacheTracker *ACT, Function &Callee, int Threshold)
: DL(DL), TTI(TTI), ACT(ACT), F(Callee), Threshold(Threshold), Cost(0),
IsCallerRecursive(false), IsRecursiveCall(false),
ExposesReturnsTwice(false), HasDynamicAlloca(false),
ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false),
Expand Down Expand Up @@ -789,7 +789,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
// during devirtualization and so we want to give it a hefty bonus for
// inlining, but cap that bonus in the event that inlining wouldn't pan
// out. Pretend to inline the function, with a custom threshold.
CallAnalyzer CA(DL, TTI, AC, *F, InlineConstants::IndirectCallThreshold);
CallAnalyzer CA(DL, TTI, ACT, *F, InlineConstants::IndirectCallThreshold);
if (CA.analyzeCall(CS)) {
// We were able to inline the indirect call! Subtract the cost from the
// bonus we want to apply, but don't go below zero.
Expand Down Expand Up @@ -1135,7 +1135,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
// the ephemeral values multiple times (and they're completely determined by
// the callee, so this is purely duplicate work).
SmallPtrSet<const Value *, 32> EphValues;
CodeMetrics::collectEphemeralValues(&F, &AC, EphValues);
CodeMetrics::collectEphemeralValues(&F, &ACT->getAssumptionCache(F), EphValues);

// The worklist of live basic blocks in the callee *after* inlining. We avoid
// adding basic blocks of the callee which can be proven to be dead for this
Expand Down Expand Up @@ -1335,7 +1335,7 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee,
<< "...\n");

CallAnalyzer CA(Callee->getDataLayout(), TTIWP->getTTI(*Callee),
ACT->getAssumptionCache(*Callee), *Callee, Threshold);
ACT, *Callee, Threshold);
bool ShouldInline = CA.analyzeCall(CS);

DEBUG(CA.dump());
Expand Down
19 changes: 19 additions & 0 deletions llvm/test/Transforms/Inline/inline-indirect.ll
@@ -0,0 +1,19 @@
; RUN: opt < %s -inline -disable-output 2>/dev/null
; This test used to trigger an assertion in the assumption cache when
; inlining the indirect call
declare void @llvm.assume(i1)

define void @foo() {
ret void
}

define void @bar(void ()*) {
call void @llvm.assume(i1 true)
call void %0();
ret void
}

define void @baz() {
call void @bar(void ()* @foo)
ret void
}

0 comments on commit 6f972a1

Please sign in to comment.