To summarize the behavior difference
% cat a.ll
define void @foo3(i32 %x) {
ret void
}
define i32 @foo4(i32 %x) {
ret i32 %x
}
% myllc a.ll -function-sections -filetype=obj -o a.o && readelf -W -S a.o
...
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
...
[ 3] .text.foo3 PROGBITS 0000000000000000 000040 000001 00 AX 0 0 1
[ 4] .text.foo4 PROGBITS 0000000000000000 000041 000003 00 AX 0 0 4
# -fno-function-sections is unchanged https://github.com/llvm/llvm-project/pull/155529#issuecomment-3947151340
% myllc a.ll -filetype=obj -o a.o && objdump -dr a.o
...
0000000000000000 <foo3>:
0: c3 ret
1: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
8: 00 00 00
b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000000010 <foo4>:
10: 89 f8 mov %edi,%eax
12: c3 ret