The Arm prologue of a variadic function pushes the anonymous argument
registers, up to 16 bytes for r0-r3, and releases them on exit, so that
area is part of the frame.  Both prologue expanders however reported the
static stack size as offsets->outgoing_args - offsets->saved_args, and
arm_get_frame_offsets sets offsets->saved_args to
crtl->args.pretend_args_size, so the subtraction discarded exactly the
save area.  Report offsets->outgoing_args instead.  aarch64 already
counts its varargs save area in frame.frame_size.

The local "size" is left alone: it also drives the stack-checking probe
sequence, which must continue to exclude the pretend area.  Non-variadic
functions have pretend_args_size == 0 and are unaffected.

  int vf (int a, ...) { char buf[100]; ... }

  -O2 -fstack-usage:  vf 120 static  ->  vf 136 static

current_function_static_stack_size has one consumer outside the back
ends, toplev.cc:output_stack_usage_1, so this cannot change code
generation.

Bootstrapped on x86_64-pc-linux-gnu, and tested on arm-none-eabi with a
cross compiler: no regressions in gcc.target/arm, gcc.target/arm/mve,
gcc.target/arm/simd or gcc.dg/tree-ssa against the same tree without the
patch.

Assisted-by: Claude Opus 5 (Anthropic)

gcc/ChangeLog:

        PR target/106554
        * config/arm/arm.cc (arm_expand_prologue): Report
        offsets->outgoing_args as the static stack size, so that the
        anonymous argument save area is included.
        (thumb1_expand_prologue): Likewise.

gcc/testsuite/ChangeLog:

        PR target/106554
        * gcc.target/arm/pr106554.c: New test.

Signed-off-by: Dominic P <[email protected]>
---
Changes in v2: the test limit is -Wstack-usage=124 instead of 128.  With
fewer callee-saved registers pushed, vf can use exactly 128 bytes and
the expected warning is lost; 124 leaves 4 bytes either side on the
configurations tried.  The code change is unchanged.

OK for trunk?

 gcc/config/arm/arm.cc                   |  4 ++--
 gcc/testsuite/gcc.target/arm/pr106554.c | 31 +++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pr106554.c

diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 33b64995442..c02b34c0fae 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -24186,7 +24186,7 @@ arm_expand_prologue (void)
 
   size = offsets->outgoing_args - offsets->saved_args;
   if (flag_stack_usage_info)
-    current_function_static_stack_size = size;
+    current_function_static_stack_size = offsets->outgoing_args;
 
   /* If this isn't an interrupt service routine and we have a frame, then do
      stack checking.  We use IP as the first scratch register, except for the
@@ -27674,7 +27674,7 @@ thumb1_expand_prologue (void)
 
   size = offsets->outgoing_args - offsets->saved_args;
   if (flag_stack_usage_info)
-    current_function_static_stack_size = size;
+    current_function_static_stack_size = offsets->outgoing_args;
 
   /* If we have a frame, then do stack checking.  FIXME: not implemented.  */
   if ((flag_stack_check == STATIC_BUILTIN_STACK_CHECK
diff --git a/gcc/testsuite/gcc.target/arm/pr106554.c 
b/gcc/testsuite/gcc.target/arm/pr106554.c
new file mode 100644
index 00000000000..2d88996bb13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr106554.c
@@ -0,0 +1,31 @@
+/* PR target/106554: -fstack-usage and -Wstack-usage= must account for
+   the anonymous argument save area that the prologue of a variadic
+   function pushes.  Only vf, whose frame includes the 16-byte save area,
+   exceeds the limit.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstack-usage=124" } */
+
+extern void sink (char *, int);
+
+int
+nf (int a)     /* { dg-bogus "stack usage" } */
+{
+  char buf[100];
+  sink (buf, a);
+  return buf[0] + a;
+}
+
+int
+vf (int a, ...)        /* { dg-warning "stack usage is \[0-9\]* bytes" } */
+{
+  char buf[100];
+  __builtin_va_list ap;
+  int r;
+
+  __builtin_va_start (ap, a);
+  r = __builtin_va_arg (ap, int);
+  __builtin_va_end (ap);
+  sink (buf, r);
+  return buf[0] + a + r;
+}
-- 
2.55.0

Reply via email to