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

Reply via email to