From 878642954f5178c55b337afe2bff4e6a92a67a5b Mon Sep 17 00:00:00 2001 From: Amir Ayupov Date: Sun, 19 May 2024 13:23:04 -0700 Subject: [BOLT] Fix preserved offset in fixDoubleJumps (#92485) --- bolt/lib/Passes/BinaryPasses.cpp | 14 +++++++++----- bolt/test/X86/bb-with-two-tail-calls.s | 8 ++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp index 867f977..298ba29 100644 --- a/bolt/lib/Passes/BinaryPasses.cpp +++ b/bolt/lib/Passes/BinaryPasses.cpp @@ -674,7 +674,8 @@ static uint64_t fixDoubleJumps(BinaryFunction &Function, bool MarkInvalid) { MCPlusBuilder *MIB = Function.getBinaryContext().MIB.get(); for (BinaryBasicBlock &BB : Function) { auto checkAndPatch = [&](BinaryBasicBlock *Pred, BinaryBasicBlock *Succ, - const MCSymbol *SuccSym) { + const MCSymbol *SuccSym, + std::optional Offset) { // Ignore infinite loop jumps or fallthrough tail jumps. if (Pred == Succ || Succ == &BB) return false; @@ -715,9 +716,11 @@ static uint64_t fixDoubleJumps(BinaryFunction &Function, bool MarkInvalid) { Pred->removeSuccessor(&BB); Pred->eraseInstruction(Pred->findInstruction(Branch)); Pred->addTailCallInstruction(SuccSym); - MCInst *TailCall = Pred->getLastNonPseudoInstr(); - assert(TailCall); - MIB->setOffset(*TailCall, BB.getOffset()); + if (Offset) { + MCInst *TailCall = Pred->getLastNonPseudoInstr(); + assert(TailCall); + MIB->setOffset(*TailCall, *Offset); + } } else { return false; } @@ -760,7 +763,8 @@ static uint64_t fixDoubleJumps(BinaryFunction &Function, bool MarkInvalid) { if (Pred->getSuccessor() == &BB || (Pred->getConditionalSuccessor(true) == &BB && !IsTailCall) || Pred->getConditionalSuccessor(false) == &BB) - if (checkAndPatch(Pred, Succ, SuccSym) && MarkInvalid) + if (checkAndPatch(Pred, Succ, SuccSym, MIB->getOffset(*Inst)) && + MarkInvalid) BB.markValid(BB.pred_size() != 0 || BB.isLandingPad() || BB.isEntryPoint()); } diff --git a/bolt/test/X86/bb-with-two-tail-calls.s b/bolt/test/X86/bb-with-two-tail-calls.s index bb2b0cd..b6703e3 100644 --- a/bolt/test/X86/bb-with-two-tail-calls.s +++ b/bolt/test/X86/bb-with-two-tail-calls.s @@ -1,8 +1,6 @@ # This reproduces a bug with dynostats when trying to compute branch stats # at a block with two tails calls (one conditional and one unconditional). -# REQUIRES: system-linux - # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ # RUN: %s -o %t.o # RUN: link_fdata %s %t.o %t.fdata @@ -13,7 +11,7 @@ # CHECK-NOT: Assertion `BranchInfo.size() == 2 && "could only be called for blocks with 2 successors"' failed. # Two tail calls in the same basic block after SCTC: # CHECK: {{.*}}: ja {{.*}} # TAILCALL # Offset: 7 # CTCTakenCount: 4 -# CHECK-NEXT: {{.*}}: jmp {{.*}} # TAILCALL # Offset: 12 +# CHECK-NEXT: {{.*}}: jmp {{.*}} # TAILCALL # Offset: 13 .globl _start _start: @@ -23,7 +21,9 @@ a: ja b x: ret # FDATA: 1 _start #a# 1 _start #b# 2 4 b: jmp e -c: jmp f +c: + .nops 1 + jmp f .globl e e: -- cgit v1.1