Commit 2f356a13 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r228957:

------------------------------------------------------------------------
r228957 | bsteinbr | 2015-02-12 13:04:22 -0800 (Thu, 12 Feb 2015) | 14 lines

Fix a crash in the assumption cache when inlining indirect function calls

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: 228965
parent 1a8cc869
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -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;
@@ -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),
@@ -783,7 +783,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.
@@ -1110,7 +1110,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
@@ -1310,7 +1310,7 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee,
        << "...\n");

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

  DEBUG(CA.dump());
+19 −0
Original line number Diff line number Diff line
; 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
}