[llvm] [BOLT] Correctly handle entry point at FDE boundaries (PR #176173)

Elvina Yakubova via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 28 09:47:15 PST 2026


================
@@ -0,0 +1,97 @@
+## Test that BOLT correctly handles entry points at exact FDE boundaries.
+##
+## This test simulates a real-world scenario where:
+## 1. A large function (big_func) contains an FDE with no symbol
+## 2. The FDE covers a sub-function within big_func [fde_start, fde_end)
+## 3. Inlined code follows immediately after the FDE (no symbol, no FDE)
+## 4. .init branches to exactly the FDE end address via section relocation
+##
+## Without the fix, getOrCreateLocalLabel() would return getFunctionEndLabel()
+## when offset == FDE size. The fix ensures a proper entry point label is created.
+##
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags %t.o -pie -Wl,-q -Wl,--init=_init -o %t.exe
+# RUN: llvm-bolt %t.exe -o %t.bolt --print-disasm -v=1 2>&1 | FileCheck %s
+
+## The FDE-only function should get an entry point for the inlined code
+# CHECK: BOLT-WARNING: FDE {{.*}} has no corresponding symbol table entry
+# CHECK: Binary Function "{{.*}}__BOLT_FDE_FUNC{{.*}}" after disassembly
+# CHECK: Size        : 0x1c
+# CHECK: MaxSize     : 0x30
+# CHECK: IsMultiEntry: 1
+
+## _init function in .init section
+	.section .init,"ax", at progbits
+	.globl	_init
+	.type	_init, %function
+_init:
+	.cfi_startproc
+	stp	x29, x30, [sp, #-16]!
+	mov	x29, sp
+	## Branch to inlined code that's right after FDE end
+	## Linker converts this to: R_AARCH64_CALL26 .text + offset
+	bl	.Linlined_code
+	ldp	x29, x30, [sp], #16
+	ret
+	.cfi_endproc
+	.size	_init, .-_init
+
+## Main code in .text section
+	.text
+
+## Large function that contains the FDE and inlined code
+	.globl	big_func
+	.type	big_func, %function
+big_func:
+	.cfi_startproc
+	stp	x29, x30, [sp, #-16]!
+	mov	x29, sp
+	mov	w0, #1
+	add	w0, w0, #1
+	ldp	x29, x30, [sp], #16
+	ret
+	.cfi_endproc
+	.size	big_func, .-big_func
+
+## FDE-covered code WITHOUT a symbol - simulates sub-function within big_func
+## This has its own FDE but no symbol in the symbol table
+.Lfde_start:
+	.cfi_startproc
+	stp	x29, x30, [sp, #-16]!
+	mov	x29, sp
+	adrp	x0, .Lsome_data
+	add	x0, x0, :lo12:.Lsome_data
+	ldr	x0, [x0]
+	ldp	x29, x30, [sp], #16
+	ret
+	.cfi_endproc
+## FDE ends here - inlined code follows immediately
+
+## Inlined code at exactly FDE end (offset == FDE size)
+## _init branches here - this is what triggers the bug without the fix
+.Linlined_code:
+	adrp	x0, .Lsome_data
+	ldr	x0, [x0, :lo12:.Lsome_data]
+	cbz	x0, .Linlined_ret
+	mov	w0, #1
+.Linlined_ret:
+	ret
----------------
ElvinaYakubova wrote:

Thanks Pascalis, you're right, we can remove that, I just tried to make the test closer to the original case, but that part is not essential.

https://github.com/llvm/llvm-project/pull/176173


More information about the llvm-commits mailing list