Index: lib/Transforms/IPO/PartialInlining.cpp =================================================================== --- lib/Transforms/IPO/PartialInlining.cpp +++ lib/Transforms/IPO/PartialInlining.cpp @@ -834,42 +834,41 @@ int PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB) { int InlineCost = 0; const DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - if (isa(I)) - continue; - - switch (I->getOpcode()) { + for (Instruction &I : BB->instructionsWithoutDebug()) { + // Skip free instructions. + switch (I.getOpcode()) { case Instruction::BitCast: case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::Alloca: + case Instruction::PHI: continue; case Instruction::GetElementPtr: - if (cast(I)->hasAllZeroIndices()) + if (cast(&I)->hasAllZeroIndices()) continue; break; default: break; } - IntrinsicInst *IntrInst = dyn_cast(I); + IntrinsicInst *IntrInst = dyn_cast(&I); if (IntrInst) { if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start || IntrInst->getIntrinsicID() == Intrinsic::lifetime_end) continue; } - if (CallInst *CI = dyn_cast(I)) { + if (CallInst *CI = dyn_cast(&I)) { InlineCost += getCallsiteCost(CallSite(CI), DL); continue; } - if (InvokeInst *II = dyn_cast(I)) { + if (InvokeInst *II = dyn_cast(&I)) { InlineCost += getCallsiteCost(CallSite(II), DL); continue; } - if (SwitchInst *SI = dyn_cast(I)) { + if (SwitchInst *SI = dyn_cast(&I)) { InlineCost += (SI->getNumCases() + 1) * InlineConstants::InstrCost; continue; } Index: test/Transforms/CodeExtractor/PartialInlineEntryPHICost.ll =================================================================== --- /dev/null +++ test/Transforms/CodeExtractor/PartialInlineEntryPHICost.ll @@ -0,0 +1,40 @@ +; RUN: opt < %s -partial-inliner -S | FileCheck %s +; RUN: opt < %s -passes=partial-inliner -S | FileCheck %s + +; Check that we do not overcompute the outlined region cost, where the PHIs in +; the outlined region entry (BB4) are moved outside the region by CodeExtractor. + +define i32 @bar(i32 %arg) { +bb: + %tmp = icmp slt i32 %arg, 0 + br i1 %tmp, label %bb1, label %bb2 + +bb1: + br i1 undef, label %bb4, label %bb2 + +bb2: ; preds = %bb, %bb1 + br i1 undef, label %bb4, label %bb5 + +bb4: ; preds = %bb1, %bb2 + %xx1 = phi i32 [ 1, %bb1 ], [ 9, %bb2 ] + %xx2 = phi i32 [ 1, %bb1 ], [ 9, %bb2 ] + %xx3 = phi i32 [ 1, %bb1 ], [ 9, %bb2 ] + tail call void (...) @foo() #2 + br label %bb5 + +bb5: ; preds = %bb4, %bb2 + %tmp6 = phi i32 [ 1, %bb2 ], [ 9, %bb4 ] + ret i32 %tmp6 +} + +declare void @foo(...) + +define i32 @dummy_caller(i32 %arg) { +bb: +; CHECK-LABEL: @dummy_caller +; CHECK: br i1 +; CHECK: br i1 +; CHECK: call void @bar.1. + %tmp = tail call i32 @bar(i32 %arg) + ret i32 %tmp +}