Hi, Thanks for the update.
There are still some formatting problems, some of which might be caused by your mailer. I manually applied the patch and manually triggered CI, the new test passed without regression. Here is the version I tested, let's wait for Richard's feedback. Christophe On Thu, 10 Jul 2025 at 01:27, Matt Parks <matt.pa...@go-aps.com> wrote: > > This patch fixes PR117468: > ARM thumb1 compilation using -ffixed-reg with r4-r7, without -Os (which > prohibits use of high registers), produces bad high register restoration > code that clobbers the fixed register. > > gcc/ChangeLog: > PR target/117468 > * arm.cc (thumb1_prologue_unused_call_clobbered_lo_regs): Take fixed > regs into account. > * arm.cc (thumb1_epilogue_unused_call_clobbered_lo_regs): Take fixed > regs into account. > > diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc > index bde06f3fa86..de911981a5c 100644 > --- a/gcc/config/arm/arm.cc > +++ b/gcc/config/arm/arm.cc > @@ -8274,7 +8274,8 @@ thumb1_prologue_unused_call_clobbered_lo_regs (void) > bitmap prologue_live_out = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)); > for (int reg = FIRST_LO_REGNUM; reg <= LAST_LO_REGNUM; reg++) > - if (!callee_saved_reg_p (reg) && !REGNO_REG_SET_P (prologue_live_out, > reg)) > + if (!callee_saved_reg_p (reg) && !REGNO_REG_SET_P (prologue_live_out, > reg) > + && !fixed_regs[reg]) > mask |= 1 << (reg - FIRST_LO_REGNUM); > return mask; > } > @@ -8287,7 +8288,8 @@ thumb1_epilogue_unused_call_clobbered_lo_regs (void) > bitmap epilogue_live_in = df_get_live_in (EXIT_BLOCK_PTR_FOR_FN (cfun)); > for (int reg = FIRST_LO_REGNUM; reg <= LAST_LO_REGNUM; reg++) > - if (!callee_saved_reg_p (reg) && !REGNO_REG_SET_P (epilogue_live_in, > reg)) > + if (!callee_saved_reg_p (reg) && !REGNO_REG_SET_P (epilogue_live_in, reg) > + && !fixed_regs[reg]) > mask |= 1 << (reg - FIRST_LO_REGNUM); > return mask; > } > diff --git a/gcc/testsuite/gcc.target/arm/pr117468.c > b/gcc/testsuite/gcc.target/arm/pr117468.c > new file mode 100644 > index 00000000000..dc2dd9720ec > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/pr117468.c > @@ -0,0 +1,13 @@ > + > +/* { dg-do compile } */ > +/* { dg-options "-O2 -ffixed-r7" } */ > +/* { dg-require-effective-target arm_arch_v5t_thumb_ok } */ > +/* { dg-add-options arm_arch_v5t_thumb } */ > +void ext_func(int e1, int e2, int e3, int e4); > + > +int bad_func(int p1, int p2, int p3, int p4) { > + ext_func(p4, p3, p2, p1); > + return p1 + p2 + p3 + p4; > +} > + > +/* { dg-final { scan-assembler-not "pop.*r7" } } */
From 3f9be30284f633c5028ee201ddabd90c475cfaa0 Mon Sep 17 00:00:00 2001 From: Matt Parks <matt.pa...@go-aps.com> Date: Thu, 10 Jul 2025 11:05:53 +0000 Subject: [PATCH v2] arm: fix thumb1 prologue high reg restore violates -ffixed-rX [PR117468] This patch fixes PR117468: ARM thumb1 compilation using -ffixed-reg with r4-r7, without -Os (which prohibits use of high registers), produces bad high register restoration code that clobbers the fixed register. gcc/ChangeLog: PR target/117468 * config/arm/arm.cc (thumb1_prologue_unused_call_clobbered_lo_regs): Take fixed regs into account. (thumb1_epilogue_unused_call_clobbered_lo_regs): Likewise. gcc/testsuite/ChangeLog: PR target/117468 * gcc.target/arm/pr117468.c: New test. --- gcc/config/arm/arm.cc | 8 ++++++-- gcc/testsuite/gcc.target/arm/pr117468.c | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr117468.c diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index bde06f3fa86..90a3e706b87 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -8274,7 +8274,9 @@ thumb1_prologue_unused_call_clobbered_lo_regs (void) bitmap prologue_live_out = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)); for (int reg = FIRST_LO_REGNUM; reg <= LAST_LO_REGNUM; reg++) - if (!callee_saved_reg_p (reg) && !REGNO_REG_SET_P (prologue_live_out, reg)) + if (!callee_saved_reg_p (reg) + && !REGNO_REG_SET_P (prologue_live_out, reg) + && !fixed_regs[reg]) mask |= 1 << (reg - FIRST_LO_REGNUM); return mask; } @@ -8287,7 +8289,9 @@ thumb1_epilogue_unused_call_clobbered_lo_regs (void) bitmap epilogue_live_in = df_get_live_in (EXIT_BLOCK_PTR_FOR_FN (cfun)); for (int reg = FIRST_LO_REGNUM; reg <= LAST_LO_REGNUM; reg++) - if (!callee_saved_reg_p (reg) && !REGNO_REG_SET_P (epilogue_live_in, reg)) + if (!callee_saved_reg_p (reg) + && !REGNO_REG_SET_P (epilogue_live_in, reg) + && !fixed_regs[reg]) mask |= 1 << (reg - FIRST_LO_REGNUM); return mask; } diff --git a/gcc/testsuite/gcc.target/arm/pr117468.c b/gcc/testsuite/gcc.target/arm/pr117468.c new file mode 100644 index 00000000000..591be4fbb01 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr117468.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffixed-r7" } */ +/* { dg-require-effective-target arm_arch_v5t_thumb_ok } */ +/* { dg-add-options arm_arch_v5t_thumb } */ +void ext_func(int e1, int e2, int e3, int e4); + +int bad_func(int p1, int p2, int p3, int p4) { + ext_func(p4, p3, p2, p1); + return p1 + p2 + p3 + p4; +} + +/* { dg-final { scan-assembler-not "pop.*r7" } } */ -- 2.34.1