diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2024-02-29 18:08:45 +0100 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2024-02-29 18:46:19 +0100 |
commit | 2f43ad6a60adb8dd4af9a3c78dfe78597e891c9e (patch) | |
tree | c4829705b7dcc1a9c9b5f6d54cc37d9101269770 | |
parent | b83f3cd3ff765fb82344b848b8a128763b7a4233 (diff) | |
download | gcc-2f43ad6a60adb8dd4af9a3c78dfe78597e891c9e.zip gcc-2f43ad6a60adb8dd4af9a3c78dfe78597e891c9e.tar.gz gcc-2f43ad6a60adb8dd4af9a3c78dfe78597e891c9e.tar.bz2 |
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.
-rw-r--r-- | gcc/config/avr/avr.cc | 7 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/pr114132-1.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr114132-2.c | 22 |
4 files changed, 47 insertions, 1 deletions
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 655a8e8..478463b 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 ff2738d..56211fa 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 0000000..209eca8 --- /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 0000000..c2bcbac --- /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; +} + |