aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmir Ayupov <aaupov@fb.com>2024-05-19 13:23:04 -0700
committerGitHub <noreply@github.com>2024-05-19 13:23:04 -0700
commit878642954f5178c55b337afe2bff4e6a92a67a5b (patch)
tree02bfaf37fbf3b8e753707071563ce71c0f6f0e87
parent0cd2bf3521a52f255c2b0d466f2f48f15d4a89a9 (diff)
downloadllvm-878642954f5178c55b337afe2bff4e6a92a67a5b.zip
llvm-878642954f5178c55b337afe2bff4e6a92a67a5b.tar.gz
llvm-878642954f5178c55b337afe2bff4e6a92a67a5b.tar.bz2
[BOLT] Fix preserved offset in fixDoubleJumps (#92485)
-rw-r--r--bolt/lib/Passes/BinaryPasses.cpp14
-rw-r--r--bolt/test/X86/bb-with-two-tail-calls.s8
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<uint32_t> 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: