Trying again, hopefully formatted correctly this time, and now including a test case. Test case fails with original code, passes with patch. Command to execute test case: make check-c RUNTESTFLAGS="--target-board='arm-sim/-march=armv5t' arm.exp=pr117366.c" gcc/ChangeLog: * arm.cc: fix thumb1 size-optimized function prolog violates -ffixed-rX diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index bde06f3fa86..65a161a64ff 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -26746,8 +26746,8 @@ thumb1_extra_regs_pushed (arm_stack_offsets *offsets, bool for_prologue) live_regs_mask >>= reg_base; } - while (reg_base + n_free < 8 && !(live_regs_mask & 1) - && (for_prologue || call_used_or_fixed_reg_p (reg_base + n_free))) + while (reg_base + n_free <= LAST_LO_REGNUM && !(live_regs_mask & 1) + && (for_prologue || (call_used_or_fixed_reg_p (reg_base + n_free) && !fixed_regs[reg_base + n_free]))) { live_regs_mask >>= 1; n_free++; diff --git a/gcc/testsuite/gcc.target/arm/pr117366.c b/gcc/testsuite/gcc.target/arm/pr117366.c new file mode 100644 index 00000000000..89ecd950b7a --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr117366.c @@ -0,0 +1,14 @@ + +/* { dg-do compile } */ +/* { dg-options "-Os -ffixed-r4 -ffixed-r5 -ffixed-r6 -ffixed-r7" } */ +/* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-additional-options "-march=armv5t -mthumb" {target arm_arch_v5t_ok} } */ +void func(void *, void *, void *, int, int); + +int bad_func(void) { + int a, b, c; + func(&a, &b, &c, 1, 2); + return b; +} + +/* { dg-final { scan-assembler-not "pop.*r\[4567\]" } } */