When hard frame pointer isn't needed, the register for hard frame pointer may be reused. This patch clears alignment on hard frame pointer if hard frame pointer isn't needed. OK for trunk after bootstrap and test on Linux/x86-64?
Thanks. H.J. -- gcc/ PR rtl-optimization/64905 * ira.c (ira_setup_eliminable_regset): Clear hard frame pointer alignment if it isn't needed. gcc/testsuite/ PR rtl-optimization/64905 * gcc.target/i386/pr64905.c: New file. --- gcc/ira.c | 2 ++ gcc/testsuite/gcc.target/i386/pr64905.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr64905.c diff --git a/gcc/ira.c b/gcc/ira.c index ea2b69f..a7cf476 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -2313,6 +2313,8 @@ ira_setup_eliminable_regset (void) if (frame_pointer_needed) df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM, true); + else + REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0; COPY_HARD_REG_SET (ira_no_alloc_regs, no_unit_alloc_regs); CLEAR_HARD_REG_SET (eliminable_regset); diff --git a/gcc/testsuite/gcc.target/i386/pr64905.c b/gcc/testsuite/gcc.target/i386/pr64905.c new file mode 100644 index 0000000..bc87d85 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr64905.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-Os -ffixed-rax -ffixed-rbx -ffixed-rcx -ffixed-rdx -ffixed-rdi -ffixed-rsi -ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 -ffixed-r13 -ffixed-r14 -ffixed-r15" } */ +/* { dg-final { scan-assembler-not "movl\[ \t\]0\\(%.*\\), %.*" } } */ + +typedef unsigned short uint16_t; +uint16_t a_global; + +void __attribute__ ((noinline)) +function (uint16_t **a_p) +{ + // unaligned access by address in %rbp: mov 0x0(%rbp),%ebp + a_global = **a_p; +} + +int main(int argc, char **argv) +{ + uint16_t array [4] = { 1, 2, 3, 4 }; + uint16_t *array_elem_p = &array [3]; + + function (&array_elem_p); + return 0; +} -- 1.9.3