diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -181,6 +181,16 @@ /// \returns The number of Functions created. unsigned doOutline(Module &M); + /// Check whether an OutlinableRegion is incompatible with code already + /// outlined. OutlinableRegions are incomptaible when there are overlapping + /// instructions, or code that has not been recorded has been added to the + /// instructions. + /// + /// \param [in] Region - The OutlinableRegion to check for conflicts with + /// already outlined code. + /// \returns whether the region can safely be outlined. + bool isCompatibleWithAlreadyOutlinedCode(const OutlinableRegion &Region); + /// Remove all the IRSimilarityCandidates from \p CandidateVec that have /// instructions contained in a previously outlined region and put the /// remaining regions in \p CurrentGroup. diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -274,8 +274,9 @@ // division instruction for targets that have a native division instruction. // To be overly conservative, we only add 1 to the number of instructions for // each division instruction. - for (Instruction &I : *StartBB) { - switch (I.getOpcode()) { + for (IRInstructionData &ID : *Candidate) { + Instruction *I = ID.Inst; + switch (I->getOpcode()) { case Instruction::FDiv: case Instruction::FRem: case Instruction::SDiv: @@ -285,7 +286,7 @@ Benefit += 1; break; default: - Benefit += TTI.getInstructionCost(&I, TargetTransformInfo::TCK_CodeSize); + Benefit += TTI.getInstructionCost(I, TargetTransformInfo::TCK_CodeSize); break; } } @@ -1341,6 +1342,51 @@ OutlinedFunctionNum++; } +bool IROutliner::isCompatibleWithAlreadyOutlinedCode( + const OutlinableRegion &Region) { + IRSimilarityCandidate *IRSC = Region.Candidate; + unsigned StartIdx = IRSC->getStartIdx(); + unsigned EndIdx = IRSC->getEndIdx(); + + // A check to make sure that we are not about to attempt to outline something + // that has already been outlined. + for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++) + if (Outlined.contains(Idx)) + return false; + + // We check if the recorded instruction matches the actual next instruction, + // if it does not, we fix it in the InstructionDataList. + Instruction *RealEndInstruction = + Region.Candidate->backInstruction()->getNextNonDebugInstruction(); + + assert(RealEndInstruction && "Next instruction is a nullptr?"); + if (Region.Candidate->end()->Inst != RealEndInstruction) { + IRInstructionDataList *IDL = Region.Candidate->front()->IDL; + Instruction *NewEndInst = RealEndInstruction; + IRInstructionData *NewEndIRID = new (InstDataAllocator.Allocate()) + IRInstructionData(*NewEndInst, InstructionClassifier.visit(*NewEndInst), + *IDL); + + // Insert the first IRInstructionData of the new region after the + // last IRInstructionData of the IRSimilarityCandidate. + IDL->insert(Region.Candidate->end(), *NewEndIRID); + } + + return none_of(*IRSC, [this](IRInstructionData &ID) { + // We check if there is a discrepancy between the InstructionDataList + // and the actual next instruction in the module. If there is, it means + // that an extra instruction was added, likely by the CodeExtractor. + + // Since we do not have any similarity data about this particular + // instruction, we cannot confidently outline it, and must discard this + // candidate. + if (std::next(ID.getIterator())->Inst != + ID.Inst->getNextNonDebugInstruction()) + return true; + return !InstructionClassifier.visit(ID.Inst); + }); +} + void IROutliner::pruneIncompatibleRegions( std::vector &CandidateVec, OutlinableGroup &CurrentGroup) { @@ -1664,12 +1710,17 @@ return LHS[0].getLength() * LHS.size() > RHS[0].getLength() * RHS.size(); }); + // Creating OutlinableGroups for each SimilarityCandidate to be used in + // each of the following for loops to avoid making an allocator. + std::vector PotentialGroups(SimilarityCandidates.size()); DenseSet NotSame; - std::vector FuncsToRemove; + std::vector NegativeCostGroups; + std::vector OutlinedRegions; // Iterate over the possible sets of similarity. + unsigned PotentialGroupIdx = 0; for (SimilarityGroup &CandidateVec : SimilarityCandidates) { - OutlinableGroup CurrentGroup; + OutlinableGroup &CurrentGroup = PotentialGroups[PotentialGroupIdx++]; // Remove entries that were previously outlined pruneIncompatibleRegions(CandidateVec, CurrentGroup); @@ -1691,7 +1742,7 @@ // Create a CodeExtractor for each outlinable region. Identify inputs and // outputs for each section using the code extractor and create the argument // types for the Aggregate Outlining Function. - std::vector OutlinedRegions; + OutlinedRegions.clear(); for (OutlinableRegion *OS : CurrentGroup.Regions) { // Break the outlinable region out of its parent BasicBlock into its own // BasicBlocks (see function implementation). @@ -1710,8 +1761,10 @@ findAddInputsOutputs(M, *OS, NotSame); if (!OS->IgnoreRegion) OutlinedRegions.push_back(OS); - else - OS->reattachCandidate(); + + // We recombine the blocks together now that we have gathered all the + // needed information. + OS->reattachCandidate(); } CurrentGroup.Regions = std::move(OutlinedRegions); @@ -1724,12 +1777,11 @@ if (CostModel) findCostBenefit(M, CurrentGroup); - // If we are adhering to the cost model, reattach all the candidates + // If we are adhering to the cost model, skip those groups where the cost + // outweighs the benefits. if (CurrentGroup.Cost >= CurrentGroup.Benefit && CostModel) { - for (OutlinableRegion *OS : CurrentGroup.Regions) - OS->reattachCandidate(); - OptimizationRemarkEmitter &ORE = getORE( - *CurrentGroup.Regions[0]->Candidate->getFunction()); + OptimizationRemarkEmitter &ORE = + getORE(*CurrentGroup.Regions[0]->Candidate->getFunction()); ORE.emit([&]() { IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate; OptimizationRemarkMissed R(DEBUG_TYPE, "WouldNotDecreaseSize", @@ -1753,12 +1805,68 @@ continue; } + NegativeCostGroups.push_back(&CurrentGroup); + } + + ExtractorAllocator.DestroyAll(); + + if (NegativeCostGroups.size() > 1) + stable_sort(NegativeCostGroups, + [](const OutlinableGroup *LHS, const OutlinableGroup *RHS) { + return LHS->Benefit - LHS->Cost > RHS->Benefit - RHS->Cost; + }); + + std::vector FuncsToRemove; + for (OutlinableGroup *CG : NegativeCostGroups) { + OutlinableGroup &CurrentGroup = *CG; + + OutlinedRegions.clear(); + for (OutlinableRegion *Region : CurrentGroup.Regions) { + // We check whether our region is compatible with what has already been + // outlined, and whether we need to ignore this item. + if (!isCompatibleWithAlreadyOutlinedCode(*Region)) + continue; + OutlinedRegions.push_back(Region); + } + + if (OutlinedRegions.size() < 2) + continue; + + // Reestimate the cost and benefit of the OutlinableGroup. Continue only if + // we are still outlining enough regions to make up for the added cost. + CurrentGroup.Regions = std::move(OutlinedRegions); + if (CostModel) { + CurrentGroup.Benefit = 0; + CurrentGroup.Cost = 0; + findCostBenefit(M, CurrentGroup); + if (CurrentGroup.Cost >= CurrentGroup.Benefit) + continue; + } + OutlinedRegions.clear(); + for (OutlinableRegion *Region : CurrentGroup.Regions) { + Region->splitCandidate(); + if (!Region->CandidateSplit) + continue; + OutlinedRegions.push_back(Region); + } + + CurrentGroup.Regions = std::move(OutlinedRegions); + if (CurrentGroup.Regions.size() < 2) { + for (OutlinableRegion *R : CurrentGroup.Regions) + R->reattachCandidate(); + continue; + } + LLVM_DEBUG(dbgs() << "Outlining regions with cost " << CurrentGroup.Cost << " and benefit " << CurrentGroup.Benefit << "\n"); // Create functions out of all the sections, and mark them as outlined. OutlinedRegions.clear(); for (OutlinableRegion *OS : CurrentGroup.Regions) { + SmallVector BE = {OS->StartBB}; + OS->CE = new (ExtractorAllocator.Allocate()) + CodeExtractor(BE, nullptr, false, nullptr, nullptr, nullptr, false, + false, "outlined"); bool FunctionOutlined = extractSection(*OS); if (FunctionOutlined) { unsigned StartIdx = OS->Candidate->getStartIdx(); diff --git a/llvm/test/Transforms/IROutliner/opt-remarks.ll b/llvm/test/Transforms/IROutliner/opt-remarks.ll --- a/llvm/test/Transforms/IROutliner/opt-remarks.ll +++ b/llvm/test/Transforms/IROutliner/opt-remarks.ll @@ -5,18 +5,28 @@ ; RUN: -pass-remarks-output=%t < %s ; RUN: cat %t | FileCheck -check-prefix=YAML %s -; CHECK: remark: :0:0: did not outline 2 regions due to estimated increase of 12 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 5 instructions at locations -; CHECK-NEXT: remark: :0:0: outlined 2 regions with decrease of 2 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 12 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 14 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 17 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations +; CHECK: remark: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 6 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 0 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 1 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 2 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 12 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 3 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 4 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 14 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 5 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 15 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 6 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 12 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 7 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 8 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 18 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 14 instructions at locations +; CHECK-NEXT: :0:0: did not outline 2 regions due to estimated increase of 9 instructions at locations +; CHECK-NEXT: :0:0: outlined 2 regions with decrease of 1 instructions at locations ; YAML: --- !Missed ; YAML-NEXT: Pass: iroutliner @@ -26,7 +36,7 @@ ; YAML-NEXT: - String: 'did not outline ' ; YAML-NEXT: - String: '2' ; YAML-NEXT: - String: ' regions due to estimated increase of ' -; YAML-NEXT: - InstructionIncrease: '12' +; YAML-NEXT: - InstructionIncrease: '13' ; YAML-NEXT: - String: ' instructions at locations ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: - String: ' ' @@ -40,21 +50,21 @@ ; YAML-NEXT: - String: 'did not outline ' ; YAML-NEXT: - String: '2' ; YAML-NEXT: - String: ' regions due to estimated increase of ' -; YAML-NEXT: - InstructionIncrease: '5' +; YAML-NEXT: - InstructionIncrease: '6' ; YAML-NEXT: - String: ' instructions at locations ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: - String: ' ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: ... -; YAML-NEXT: --- !Passed +; YAML-NEXT: --- !Missed ; YAML-NEXT: Pass: iroutliner -; YAML-NEXT: Name: Outlined -; YAML-NEXT: Function: function3.outlined +; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 ; YAML-NEXT: Args: -; YAML-NEXT: - String: 'outlined ' +; YAML-NEXT: - String: 'did not outline ' ; YAML-NEXT: - String: '2' -; YAML-NEXT: - String: ' regions with decrease of ' -; YAML-NEXT: - Benefit: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '0' ; YAML-NEXT: - String: ' instructions at locations ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: - String: ' ' @@ -63,12 +73,12 @@ ; YAML-NEXT: --- !Missed ; YAML-NEXT: Pass: iroutliner ; YAML-NEXT: Name: WouldNotDecreaseSize -; YAML-NEXT: Function: function1 +; YAML-NEXT: Function: function3 ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'did not outline ' ; YAML-NEXT: - String: '2' ; YAML-NEXT: - String: ' regions due to estimated increase of ' -; YAML-NEXT: - InstructionIncrease: '10' +; YAML-NEXT: - InstructionIncrease: '1' ; YAML-NEXT: - String: ' instructions at locations ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: - String: ' ' @@ -91,6 +101,20 @@ ; YAML-NEXT: --- !Missed ; YAML-NEXT: Pass: iroutliner ; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '2' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize ; YAML-NEXT: Function: function1 ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'did not outline ' @@ -119,6 +143,34 @@ ; YAML-NEXT: --- !Missed ; YAML-NEXT: Pass: iroutliner ; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '3' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '4' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize ; YAML-NEXT: Function: function1 ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'did not outline ' @@ -133,12 +185,40 @@ ; YAML-NEXT: --- !Missed ; YAML-NEXT: Pass: iroutliner ; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '5' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize ; YAML-NEXT: Function: function1 ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'did not outline ' ; YAML-NEXT: - String: '2' ; YAML-NEXT: - String: ' regions due to estimated increase of ' -; YAML-NEXT: - InstructionIncrease: '10' +; YAML-NEXT: - InstructionIncrease: '15' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '6' ; YAML-NEXT: - String: ' instructions at locations ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: - String: ' ' @@ -166,7 +246,35 @@ ; YAML-NEXT: - String: 'did not outline ' ; YAML-NEXT: - String: '2' ; YAML-NEXT: - String: ' regions due to estimated increase of ' -; YAML-NEXT: - InstructionIncrease: '17' +; YAML-NEXT: - InstructionIncrease: '12' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '7' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '8' ; YAML-NEXT: - String: ' instructions at locations ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: - String: ' ' @@ -180,7 +288,49 @@ ; YAML-NEXT: - String: 'did not outline ' ; YAML-NEXT: - String: '2' ; YAML-NEXT: - String: ' regions due to estimated increase of ' -; YAML-NEXT: - InstructionIncrease: '13' +; YAML-NEXT: - InstructionIncrease: '18' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function1 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '14' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Missed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: WouldNotDecreaseSize +; YAML-NEXT: Function: function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - InstructionIncrease: '9' +; YAML-NEXT: - String: ' instructions at locations ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: - String: ' ' +; YAML-NEXT: - DebugLoc: '' +; YAML-NEXT: ... +; YAML-NEXT: --- !Passed +; YAML-NEXT: Pass: iroutliner +; YAML-NEXT: Name: Outlined +; YAML-NEXT: Function: function3.outlined +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'outlined ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions with decrease of ' +; YAML-NEXT: - Benefit: '1' ; YAML-NEXT: - String: ' instructions at locations ' ; YAML-NEXT: - DebugLoc: '' ; YAML-NEXT: - String: ' ' diff --git a/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll b/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll --- a/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll +++ b/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll @@ -100,7 +100,10 @@ ; CHECK-LABEL: @outline_bitcast_base2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[D:%.*]] = alloca i32, align 4 -; CHECK-NEXT: call void @outlined_ir_func_1(i32* [[D]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) +; CHECK-NEXT: [[X:%.*]] = bitcast i32* [[D]] to i8* +; CHECK-NEXT: [[AL:%.*]] = add i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[BL:%.*]] = add i32 [[B]], [[A]] +; CHECK-NEXT: [[CL:%.*]] = add i32 [[B]], [[C:%.*]] ; CHECK-NEXT: [[BUFFER:%.*]] = mul i32 [[A]], [[B]] ; CHECK-NEXT: [[Y:%.*]] = bitcast i32* [[D]] to i8* ; CHECK-NEXT: [[AM:%.*]] = add i32 [[A]], [[B]] @@ -113,7 +116,9 @@ ; CHECK-NEXT: ret void ; ; -; CHECK: @outlined_ir_func_0(i32* [[TMP0:%.*]], i32* [[TMP1:%.*]], i32* [[TMP2:%.*]], i32* [[TMP3:%.*]]) +; CHECK-LABEL: @outlined_ir_func_0( +; CHECK-NEXT: newFuncRoot: +; CHECK-NEXT: br label [[ENTRY_TO_OUTLINE:%.*]] ; CHECK: entry_to_outline: ; CHECK-NEXT: store i32 2, i32* [[TMP0:%.*]], align 4 ; CHECK-NEXT: store i32 3, i32* [[TMP1:%.*]], align 4 @@ -123,13 +128,5 @@ ; CHECK-NEXT: [[BL:%.*]] = load i32, i32* [[TMP1]], align 4 ; CHECK-NEXT: [[CL:%.*]] = load i32, i32* [[TMP2]], align 4 ; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]] -; -; -; CHECK: @outlined_ir_func_1(i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) -; CHECK: entry_to_outline: -; CHECK-NEXT: [[X:%.*]] = bitcast i32* [[TMP0]] to i8* -; CHECK-NEXT: [[AL:%.*]] = add i32 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[BL:%.*]] = add i32 [[TMP2]], [[TMP1]] -; CHECK-NEXT: [[CL:%.*]] = add i32 [[TMP2]], [[TMP3]] -; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]] -; +; CHECK: entry_after_outline.exitStub: +; CHECK-NEXT: ret void