Message ID | Zfh4EvFIEYe+Ym5W@tucnak |
---|---|
State | New |
Headers | show |
Series | rs6000: Fix up setup_incoming_varargs [PR114175] | expand |
Hi Jakub, on 2024/3/19 01:21, Jakub Jelinek wrote: > Hi! > > The c23-stdarg-8.c test (as well as the new test below added to cover even > more cases) FAIL on powerpc64le-linux and presumably other powerpc* targets > as well. > Like in the r14-9503-g218d174961 change on x86-64 we need to advance > next_cum after the hidden return pointer argument even in case where > there are no user arguments before ... in C23. > The following patch does that. > > There is another TYPE_NO_NAMED_ARGS_STDARG_P use later on: > if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)) > && targetm.calls.must_pass_in_stack (arg)) > first_reg_offset += rs6000_arg_size (TYPE_MODE (arg.type), arg.type); > but I believe it was added there in r13-3549-g4fe34cdc unnecessarily, > when there is no hidden return pointer argument, arg.type is NULL and > must_pass_in_stack_var_size as well as must_pass_in_stack_var_size_or_pad > return false in that case, and for the TYPE_NO_NAMED_ARGS_STDARG_P > case with hidden return pointer argument that argument should have pointer > type and it is the first argument, so must_pass_in_stack shouldn't be true > for it either. > > Bootstrapped/regtested on powerpc64le-linux, bootstrap/regtest on > powerpc64-linux running, ok for trunk? Okay for trunk (I guess all testings should go well), thanks for taking care of this! FWIW, I also tested c23-stdarg-* test cases on aix with this patch, all of them worked well. BR, Kewen > > 2024-03-18 Jakub Jelinek <jakub@redhat.com> > > PR target/114175 > * config/rs6000/rs6000-call.cc (setup_incoming_varargs): Only skip > rs6000_function_arg_advance_1 for TYPE_NO_NAMED_ARGS_STDARG_P functions > if arg.type is NULL. > > * gcc.dg/c23-stdarg-9.c: New test. > > --- gcc/config/rs6000/rs6000-call.cc.jj 2024-01-03 12:01:19.645532834 +0100 > +++ gcc/config/rs6000/rs6000-call.cc 2024-03-18 11:36:02.376846802 +0100 > @@ -2253,7 +2253,8 @@ setup_incoming_varargs (cumulative_args_ > > /* Skip the last named argument. */ > next_cum = *get_cumulative_args (cum); > - if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))) > + if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)) > + || arg.type != NULL_TREE) > rs6000_function_arg_advance_1 (&next_cum, arg.mode, arg.type, arg.named, > 0); > > --- gcc/testsuite/gcc.dg/c23-stdarg-9.c.jj 2024-03-18 11:46:17.281200214 +0100 > +++ gcc/testsuite/gcc.dg/c23-stdarg-9.c 2024-03-18 11:46:26.826065998 +0100 > @@ -0,0 +1,284 @@ > +/* Test C23 variadic functions with no named parameters, or last named > + parameter with a declaration not allowed in C17. Execution tests. */ > +/* { dg-do run } */ > +/* { dg-options "-O2 -std=c23 -pedantic-errors" } */ > + > +#include <stdarg.h> > + > +struct S { int a[1024]; }; > + > +int > +f1 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +int > +f2 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +int > +f3 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +int > +f4 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +int > +f5 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +int > +f6 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +int > +f7 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +int > +f8 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + return r; > +} > + > +struct S > +s1 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +struct S > +s2 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +struct S > +s3 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +struct S > +s4 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +struct S > +s5 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +struct S > +s6 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +struct S > +s7 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +struct S > +s8 (...) > +{ > + int r = 0; > + va_list ap; > + va_start (ap); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + r += va_arg (ap, int); > + va_end (ap); > + struct S s = {}; > + s.a[0] = r; > + return s; > +} > + > +int > +b1 (void) > +{ > + return f8 (1, 2, 3, 4, 5, 6, 7, 8); > +} > + > +int > +b2 (void) > +{ > + return s8 (1, 2, 3, 4, 5, 6, 7, 8).a[0]; > +} > + > +int > +main () > +{ > + if (f1 (1) != 1 || f2 (1, 2) != 3 || f3 (1, 2, 3) != 6 > + || f4 (1, 2, 3, 4) != 10 || f5 (1, 2, 3, 4, 5) != 15 > + || f6 (1, 2, 3, 4, 5, 6) != 21 || f7 (1, 2, 3, 4, 5, 6, 7) != 28 > + || f8 (1, 2, 3, 4, 5, 6, 7, 8) != 36) > + __builtin_abort (); > + if (s1 (1).a[0] != 1 || s2 (1, 2).a[0] != 3 || s3 (1, 2, 3).a[0] != 6 > + || s4 (1, 2, 3, 4).a[0] != 10 || s5 (1, 2, 3, 4, 5).a[0] != 15 > + || s6 (1, 2, 3, 4, 5, 6).a[0] != 21 > + || s7 (1, 2, 3, 4, 5, 6, 7).a[0] != 28 > + || s8 (1, 2, 3, 4, 5, 6, 7, 8).a[0] != 36) > + __builtin_abort (); > +} > > Jakub >
--- gcc/config/rs6000/rs6000-call.cc.jj 2024-01-03 12:01:19.645532834 +0100 +++ gcc/config/rs6000/rs6000-call.cc 2024-03-18 11:36:02.376846802 +0100 @@ -2253,7 +2253,8 @@ setup_incoming_varargs (cumulative_args_ /* Skip the last named argument. */ next_cum = *get_cumulative_args (cum); - if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))) + if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)) + || arg.type != NULL_TREE) rs6000_function_arg_advance_1 (&next_cum, arg.mode, arg.type, arg.named, 0); --- gcc/testsuite/gcc.dg/c23-stdarg-9.c.jj 2024-03-18 11:46:17.281200214 +0100 +++ gcc/testsuite/gcc.dg/c23-stdarg-9.c 2024-03-18 11:46:26.826065998 +0100 @@ -0,0 +1,284 @@ +/* Test C23 variadic functions with no named parameters, or last named + parameter with a declaration not allowed in C17. Execution tests. */ +/* { dg-do run } */ +/* { dg-options "-O2 -std=c23 -pedantic-errors" } */ + +#include <stdarg.h> + +struct S { int a[1024]; }; + +int +f1 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +int +f2 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +int +f3 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +int +f4 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +int +f5 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +int +f6 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +int +f7 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +int +f8 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + return r; +} + +struct S +s1 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +struct S +s2 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +struct S +s3 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +struct S +s4 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +struct S +s5 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +struct S +s6 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +struct S +s7 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +struct S +s8 (...) +{ + int r = 0; + va_list ap; + va_start (ap); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + r += va_arg (ap, int); + va_end (ap); + struct S s = {}; + s.a[0] = r; + return s; +} + +int +b1 (void) +{ + return f8 (1, 2, 3, 4, 5, 6, 7, 8); +} + +int +b2 (void) +{ + return s8 (1, 2, 3, 4, 5, 6, 7, 8).a[0]; +} + +int +main () +{ + if (f1 (1) != 1 || f2 (1, 2) != 3 || f3 (1, 2, 3) != 6 + || f4 (1, 2, 3, 4) != 10 || f5 (1, 2, 3, 4, 5) != 15 + || f6 (1, 2, 3, 4, 5, 6) != 21 || f7 (1, 2, 3, 4, 5, 6, 7) != 28 + || f8 (1, 2, 3, 4, 5, 6, 7, 8) != 36) + __builtin_abort (); + if (s1 (1).a[0] != 1 || s2 (1, 2).a[0] != 3 || s3 (1, 2, 3).a[0] != 6 + || s4 (1, 2, 3, 4).a[0] != 10 || s5 (1, 2, 3, 4, 5).a[0] != 15 + || s6 (1, 2, 3, 4, 5, 6).a[0] != 21 + || s7 (1, 2, 3, 4, 5, 6, 7).a[0] != 28 + || s8 (1, 2, 3, 4, 5, 6, 7, 8).a[0] != 36) + __builtin_abort (); +}