varargs functions appear to force the va_list variable to the stack unnecessarily. This appears to be a consequence of declaring __builtin_va_start and __builtin_va_end to take a reference to va_list. This is a regression from 3.4.
Compile this test case for i686-pc-linux-gnu with -O2: int foo (int a, ...) { __builtin_va_list va; int c, i; __builtin_va_start(va,a); c = 0; while ((i = __builtin_va_arg(va,int)) != 0) c += i; __builtin_va_end(va); return c; } I get this: foo: pushl %ebp xorl %eax, %eax movl %esp, %ebp subl $16, %esp movl 12(%ebp), %edx leal 16(%ebp), %ecx movl %ecx, -4(%ebp) testl %edx, %edx je .L4 .p2align 4,,15 .L5: addl $4, %ecx addl %edx, %eax movl -4(%ecx), %edx testl %edx, %edx jne .L5 movl %ecx, -4(%ebp) .L4: leave ret Note the two stores to -4(%ebp). They are useless. Note that this causes the function to unnecessarily have a stack frame. With gcc 3.4.3 I get pushl %ebp movl %esp, %ebp xorl %ecx, %ecx leal 16(%ebp), %edx movl 12(%ebp), %eax jmp .L7 .p2align 2,,3 .L9: addl %eax, %ecx movl %edx, %eax movl (%eax), %eax addl $4, %edx .L7: testl %eax, %eax jne .L9 movl %ecx, %eax leave ret This code is better. -- Summary: [4.0 regression] varargs functions force va_list variable to stack unnecessarily Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: ian at airs dot com CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20984