Index: lib/Target/PowerPC/PPCBranchSelector.cpp =================================================================== --- lib/Target/PowerPC/PPCBranchSelector.cpp +++ lib/Target/PowerPC/PPCBranchSelector.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetMachine.h" +#include using namespace llvm; #define DEBUG_TYPE "ppc-branch-select" @@ -189,10 +190,39 @@ } else { // Otherwise, add the size of the blocks between this block and the // dest to the number of bytes left in this block. - BranchSize = -MBBStartOffset; + unsigned StartBlock = MBB.getNumber(); + BranchSize = BlockSizes[StartBlock].first - MBBStartOffset; - for (unsigned i = MBB.getNumber(), e = Dest->getNumber(); i != e; ++i) + unsigned MaxAlign = 2; + MaxAlign = std::max(MaxAlign, Dest->getAlignment()); + for (unsigned i = StartBlock+1, e = Dest->getNumber(); i != e; ++i) { BranchSize += BlockSizes[i].first; + MaxAlign = std::max(MaxAlign, + Fn.getBlockNumbered(i)->getAlignment()); + } + + // We tend to over estimate code size due to large alignment and + // inline assembly. Usually it causes larger computed branch offset. + // But sometimes it may also causes smaller computed branch offset + // than actual branch offset. If the offset is close to the limit of + // encoding, it may cause problem at run time. + // Following is a simplified example. + // + // actual estimated + // address address + // ... + // bne Far 100 10c + // .p2align 4 + // Near: 110 110 + // ... + // Far: 8108 8108 + // + // Actual offset: 0x8108 - 0x100 = 0x8008 + // Computed offset: 0x8108 - 0x10c = 0x7ffc + // + // The computed offset is at most ((1 << alignment) - 4) bytes smaller + // than actual offset. So we add this number to the offset for safety. + BranchSize += (1 << MaxAlign) - 4; } // If this branch is in range, ignore it.