https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345
Branko Drevensek changed:
What|Removed |Added
CC||branko.drevensek at gmail dot
com
Mark Rutland changed:
What|Removed |Added
CC||mark at kernel dot org
--- Comment #8 from Branko Drevensek ---
Size optimization turning function alignment off assumes function alignment is
an optimization only, while for some architectures it might be requirement for
certain functions, such as interrupt handlers on risc-v.
This makes it impossible to have those functions aligned using this
switch/attribute regardless of optimization level selected as -Os will cause
alignment setting to be ignored.
--- Comment #9 from Mark Rutland ---
This appears to be one case of several where GCC drops the alignment specified
by `-falign-functions=N`. I'm commenting with the other cases here rather than
creating new tickets on the assumption that's preferable.
Dropping the alignment specified by `-falign-functions=N` is a functional issue
for the arm64 Linux kernel port affecting our 'ftrace' tracing mechanism. I see
this with GCC 12.1.0 (and have no tested other versions), and LLVM seems to
always respect the alignment specified by `-falign-functions=N`
The arm64 Linux kernel port needs to use `-falign-functions=8` along with
`-fpatchable-function-entry=N,2` to place a naturally-aligned 8-byte literal at
the start of functions. There's some detail of that at:
https://lore.kernel.org/lkml/20230109135828.879136-1-mark.rutl...@arm.com/
As noted earlier in this ticket, GCC does not seem to respect
`-falign-functions=N` when using `-Os`. For my use-case we cvan work around the
issue by not passing `-Os`, and I have one patch to do so, but this is not
ideal:
https://lore.kernel.org/lkml/20230109135828.879136-3-mark.rutl...@arm.com/
In addition, GCC seems to drop alignment for cold functions, whether those are
marked as cold explicitly or when determined by some interprocedural analysis.
I've noted this on LKML at:
https://lore.kernel.org/lkml/Y77%2FqVgvaJidFpYt@FVFF77S0Q05N/
... the below summary is a copy-paste of that:
For example:
| [mark@lakrids:/mnt/data/tests/gcc-alignment]% cat test-cold.c
| #define __cold \
| __attribute__((cold))
|
| #define EXPORT_FUNC_PTR(func) \
| typeof((func)) *__ptr_##func = (func)
|
| __cold
| void cold_func_a(void) { }
|
| __cold
| void cold_func_b(void) { }
|
| __cold
| void cold_func_c(void) { }
|
| static __cold
| void static_cold_func_a(void) { }
| EXPORT_FUNC_PTR(static_cold_func_a);
|
| static __cold
| void static_cold_func_b(void) { }
| EXPORT_FUNC_PTR(static_cold_func_b);
|
| static __cold
| void static_cold_func_c(void) { }
| EXPORT_FUNC_PTR(static_cold_func_c);
| [mark@lakrids:/mnt/data/tests/gcc-alignment]% usekorg 12.1.0
aarch64-linux-gcc -falign-functions=16 -c test-cold.c -O1
| [mark@lakrids:/mnt/data/tests/gcc-alignment]% usekorg 12.1.0
aarch64-linux-objdump -d test-cold.o
|
| test-cold.o: file format elf64-littleaarch64
|
|
| Disassembly of section .text:
|
| :
|0: d65f03c0ret
|
| 0004 :
|4: d65f03c0ret
|
| 0008 :
|8: d65f03c0ret
|
| 000c :
|c: d65f03c0ret
|
| 0010 :
| 10: d65f03c0ret
|
| 0014 :
| 14: d65f03c0ret
| [mark@lakrids:/mnt/data/tests/gcc-alignment]% usekorg 12.1.0
aarch64-linux-objdump -h test-cold.o
|
| test-cold.o: file format elf64-littleaarch64
|
| Sections:
| Idx Name Size VMA LMA File off
Algn
| 0 .text 0018 0040
2**2
| CONTENTS, ALLOC, LOAD, READONLY, CODE
| 1 .data 0018 0058
2**3
| CONTENTS, ALLOC, LOAD, RELOC, DATA
| 2 .bss 0070
2**0
| ALLOC
| 3 .comment 0013 0070
2**0
| CONTENTS, READONLY
| 4 .note.GNU-stack 0083
2**0
| CONTENTS, READONLY
| 5 .eh_frame 0090 0088
2**3
| CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
In simple cases, alignment *can* be restored if an explicit function attribute
is used. For example:
| [mark@lakrids:/mnt/data/tests/gcc-alignment]% cat test-aligned-cold.c
| #define __aligned(n) \
| __attribute__((aligned(n)))
|
| #define __cold \
|