https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102096

            Bug ID: 102096
           Summary: Gcc unnecessarily initializes indeterminate variables
                    passed across function boundaries
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pskocik at gmail dot com
  Target Milestone: ---

Compared to clang where:

long ret_unspec(void){ auto long rv; return rv; }

void take6(long,long,long,long,long,long);

void call_take6(void)
{
    //6 unnecessary XORs on GCC
    auto long id0; //indeterminate
    auto long id1; //indeterminate
    auto long id2; //indeterminate
    auto long id3; //indeterminate
    auto long id4; //indeterminate
    auto long id5; //indeterminate
    take6(id0,id1,id2,id3,id4,id5);
}

yields (x86_64):

ret_unspec:                            # @ret_unspec2
        retq
call_take6:                             # @call_take6
        jmp     take6        

(1+5 bytes), GCC compiles the above to
ret_unspec2:
        xorl    %eax, %eax
        ret
call_take6:
        xorl    %r9d, %r9d
        xorl    %r8d, %r8d
        xorl    %ecx, %ecx
        xorl    %edx, %edx
        xorl    %esi, %esi
        xorl    %edi, %edi
        jmp     take6

(3+19 bytes), unnecessarily 0-initializing  the indeterminate
return-value/arguments.

Type casting the called function can often be hackishly used to get the same
assembly but doing so is technically UB and not as generic as supporting the
passing of unspecified arguments/return values, which can be used to omit
argument register initializations not just for arguments at the end of an
argument pack but also in the middle.

TL;DR: Allowing to passing/return indeterminate variables without generating
initializing code for them would be nice. Clang already does it.

Reply via email to