[llvm] [BOLT] Preserve branches past function boundaries (PR #218400)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 06:00:28 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Adam Bzowski (adam-bzowski-arm)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/218400.diff
3 Files Affected:
- (modified) bolt/lib/Core/BinaryFunction.cpp (+5-9)
- (modified) bolt/test/AArch64/invalid-code-padding.s (+2-2)
- (added) bolt/test/AArch64/jump-past-end.s (+43)
``````````diff
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index a81fa2f45c206..6daef15949d65 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1452,16 +1452,13 @@ Error BinaryFunction::disassemble() {
TargetAddress < getAddress() + getMaxSize() &&
!(BC.isAArch64() &&
BC.handleAArch64Veneer(TargetAddress, /*MatchOnly*/ true))) {
- // Result of __builtin_unreachable().
+ // This may be an effect of source-level undefined behavior, such
+ // as __builtin_unreachable(). It may also be valid code at a
+ // temporary label omitted from the symbol table by the assembler.
+ // Since BOLT cannot distinguish these cases, preserve the branch.
errs() << "BOLT-WARNING: jump past end detected at 0x"
<< Twine::utohexstr(AbsoluteInstrAddr) << " in function "
- << *this << " : replacing with nop.\n";
- BC.MIB->createNoop(Instruction);
- if (IsCondBranch) {
- // Register branch offset for profile validation.
- IgnoredBranches.emplace_back(Offset, Offset + Size);
- }
- goto add_instruction;
+ << *this << ".\n";
}
// May update Instruction and IsCall
TargetSymbol = handleExternalReference(Instruction, Size, Offset,
@@ -1539,7 +1536,6 @@ Error BinaryFunction::disassemble() {
}
}
-add_instruction:
if (!getDWARFUnits().empty()) {
SmallVector<DebugLineTableRowRef, 1> Rows;
for (const auto &[_, Unit] : getDWARFUnits()) {
diff --git a/bolt/test/AArch64/invalid-code-padding.s b/bolt/test/AArch64/invalid-code-padding.s
index 4706e600621ab..2b2b53427d2ff 100644
--- a/bolt/test/AArch64/invalid-code-padding.s
+++ b/bolt/test/AArch64/invalid-code-padding.s
@@ -9,12 +9,12 @@
.type foo, %function
foo:
cmp x0, x1
- b.eq .Ltmp1
+ b.eq .Ltmp2
adrp x1, jmptbl
add x1, x1, :lo12:jmptbl
ldrsw x2, [x1, x2, lsl #2]
br x2
- b .Ltmp1
+ b .Ltmp2
.Ltmp2:
add x0, x0, x1
ret
diff --git a/bolt/test/AArch64/jump-past-end.s b/bolt/test/AArch64/jump-past-end.s
new file mode 100644
index 0000000000000..fe9cdc6330c3b
--- /dev/null
+++ b/bolt/test/AArch64/jump-past-end.s
@@ -0,0 +1,43 @@
+## Check that BOLT preserves a branch to code immediately past the size of a
+## function. Such code can result from a temporary assembler symbol that is
+## not retained in the linked binary.
+
+# REQUIRES: system-linux, target=aarch64{{.*}}
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-linux %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.exe -nostdlib -Wl,-q,-e,_start
+# RUN: llvm-bolt %t.exe -o %t.bolt --relocs=1 --lite=0 2>&1 \
+# RUN: | FileCheck %s --check-prefix=WARNING
+# RUN: llvm-objdump -d --no-show-raw-insn -j .text %t.bolt \
+# RUN: | FileCheck %s --check-prefix=DISASM
+
+# WARNING: BOLT-WARNING: jump past end detected
+
+# DISASM: <f>:
+# DISASM-NEXT: {{.*}}cbnz x0,
+# DISASM-NEXT: {{.*}}ret
+
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ b f
+ .size _start, .-_start
+
+ .global f
+ .type f, %function
+f:
+ cbnz x0, .Lf_helper
+ ret
+ .size f, .-f
+
+ .type .Lf_helper, %function
+.Lf_helper:
+ mov x1, #42
+ ret
+ .size .Lf_helper, .-.Lf_helper
+
+ .type next, %function
+next:
+ ret
+ .size next, .-next
``````````
</details>
https://github.com/llvm/llvm-project/pull/218400
More information about the llvm-commits
mailing list