From 2f43ad6a60adb8dd4af9a3c78dfe78597e891c9e Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay <avr@gjlay.de> Date: Thu, 29 Feb 2024 18:08:45 +0100 Subject: [PATCH] AVR: target/114132 - Code sets up a frame pointer without need. The condition CUMULATIVE_ARGS.nregs == 0 in avr_frame_pointer_required_p() means that no more argument registers are left, but that's not the same condition that tells whether an argument pointer is required. PR target/114132 gcc/ * config/avr/avr.h (CUMULATIVE_ARGS) <has_stack_args>: New field. * config/avr/avr.cc (avr_init_cumulative_args): Initialize it. (avr_function_arg): Set it. (avr_frame_pointer_required_p): Use it instead of .nregs. gcc/testsuite/ * gcc.target/avr/pr114132-1.c: New test. * gcc.target/avr/torture/pr114132-2.c: New test. --- gcc/config/avr/avr.cc | 7 +++++- gcc/config/avr/avr.h | 4 ++++ gcc/testsuite/gcc.target/avr/pr114132-1.c | 15 +++++++++++++ .../gcc.target/avr/torture/pr114132-2.c | 22 +++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/avr/pr114132-1.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr114132-2.c diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 655a8e89fdce..478463b237ad 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -3565,6 +3565,7 @@ avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname, { cum->nregs = AVR_TINY ? 6 : 18; cum->regno = FIRST_CUM_REG; + cum->has_stack_args = 0; if (!libname && stdarg_p (fntype)) cum->nregs = 0; @@ -3605,6 +3606,8 @@ avr_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) if (cum->nregs && bytes <= cum->nregs) return gen_rtx_REG (arg.mode, cum->regno - bytes); + cum->has_stack_args = 1; + return NULL_RTX; } @@ -6014,6 +6017,8 @@ out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen) return ""; } + +/* Implement `TARGET_FRAME_POINTER_REQUIRED'. */ /* Return 1 if frame pointer for current function required. */ static bool @@ -6022,7 +6027,7 @@ avr_frame_pointer_required_p (void) return (cfun->calls_alloca || cfun->calls_setjmp || cfun->has_nonlocal_label - || crtl->args.info.nregs == 0 + || crtl->args.info.has_stack_args || get_frame_size () > 0); } diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index ff2738df78c7..56211fa9cd00 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -333,6 +333,10 @@ typedef struct avr_args /* Next available register number */ int regno; + + /* Whether some of the arguments are passed on the stack, + and hence an arg pointer is needed. */ + int has_stack_args; } CUMULATIVE_ARGS; #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ diff --git a/gcc/testsuite/gcc.target/avr/pr114132-1.c b/gcc/testsuite/gcc.target/avr/pr114132-1.c new file mode 100644 index 000000000000..209eca823bd1 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr114132-1.c @@ -0,0 +1,15 @@ +/* { dg-additional-options "-Os -std=c99" } */ + +#ifdef __AVR_TINY__ +int func (int a, int b, char c) +#else +int func (long long a, long long b, char c) +#endif +{ + (void) a; + (void) b; + + return c; +} + +/* { dg-final { scan-assembler-not "push r28" } } */ diff --git a/gcc/testsuite/gcc.target/avr/torture/pr114132-2.c b/gcc/testsuite/gcc.target/avr/torture/pr114132-2.c new file mode 100644 index 000000000000..c2bcbacec370 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr114132-2.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-additional-options "-std=c99" } */ + +__attribute__((noinline,noclone)) +#ifdef __AVR_TINY__ +int func (int a, int b, char c) +#else +int func (long long a, long long b, char c) +#endif +{ + (void) a; + (void) b; + return 10 + c; +} + +int main (void) +{ + if (func (0, 0, 91) != 101) + __builtin_abort(); + return 0; +} + -- GitLab