Index: lib/CodeGen/BranchFolding.cpp =================================================================== --- lib/CodeGen/BranchFolding.cpp +++ lib/CodeGen/BranchFolding.cpp @@ -31,6 +31,7 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TailDuplicator.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Function.h" #include "llvm/Support/CommandLine.h" @@ -701,8 +702,19 @@ CurMPIter != B && CurMPIter->getHash() == CurHash; --CurMPIter) { for (MPIterator I = std::prev(CurMPIter); I->getHash() == CurHash; --I) { unsigned CommonTailLen; + unsigned MinCommonTailLengthInside = MinCommonTailLength; + // Prefer to leave indirect branches duplicated after placement. + if (AfterBlockPlacement) { + MachineBasicBlock &Block1 = *CurMPIter->getBlock(); + if (Block1.empty()) + // Look for indirect local branches, and try to avoid merging them + // when merging during layout. Having multiple copies of these + // branches allows for better branch prediction. + if (Block1.back().isIndirectBranch() && Block1.succ_size() != 0) + MinCommonTailLengthInside = TailDupIndirectBranchSize + 1; + } if (ProfitableToMerge(CurMPIter->getBlock(), I->getBlock(), - MinCommonTailLength, + MinCommonTailLengthInside, CommonTailLen, TrialBBI1, TrialBBI2, SuccBB, PredBB, FuncletMembership, Index: lib/CodeGen/TailDuplicator.cpp =================================================================== --- lib/CodeGen/TailDuplicator.cpp +++ lib/CodeGen/TailDuplicator.cpp @@ -560,11 +560,16 @@ // to allow undoing the effects of tail merging and other optimizations // that rearrange the predecessors of the indirect branch. - bool HasIndirectbr = false; - if (!TailBB.empty()) - HasIndirectbr = TailBB.back().isIndirectBranch(); + bool HasLocalIndirectbr = false; + if (!TailBB.empty()) { + MachineInstr &back = TailBB.back(); + // On some platforms return instructions are marked as indirect branches and + // not as return instructions. What we're actually looking for is indirect + // branches that occur within a function, so we check for local successors. + HasLocalIndirectbr = back.isIndirectBranch() && TailBB.succ_size() != 0; + } - if (HasIndirectbr && PreRegAlloc) + if (HasLocalIndirectbr && (PreRegAlloc || LayoutMode)) MaxDuplicateCount = TailDupIndirectBranchSize; // Check the instructions in the block to determine whether tail-duplication @@ -620,7 +625,7 @@ } } - if (HasIndirectbr && PreRegAlloc) + if (HasLocalIndirectbr && PreRegAlloc) return true; if (IsSimple)