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

            Bug ID: 95669
           Summary: -O3 generates more complicated code to return 8-byte
                    struct of zeros, sometimes
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jzwinck at gmail dot com
  Target Milestone: ---

Consider this C++ code:

    struct res
    {
        int val;
        bool ok;
        bool dummy;
    };

    res fun(int a, int b)
    {
        if (a < b)
            return {0, false};
        return {a * b, true};
    }

10.1 (or 8.x) with -O2 or -O3 on x86_64 looks good:

        cmp     edi, esi ; a < b
        jge     .L2
        xor     eax, eax ; {0, false}
        ret
    .L2:
        imul    edi, esi ; a * b
        mov     rax, rdi
        bts     rax, 32  ; ok = true
        ret

But if you remove "dummy" and compile with -O3, it looks worse:

        cmp     edi, esi ; a < b
        jl      .L3
        imul    edi, esi ; a * b
        mov     esi, 1   ; ok = true
        sal     rsi, 32
        mov     eax, edi
        or      rax, rsi
        ret
    .L3:
        xor     esi, esi
        xor     edi, edi
        mov     eax, edi
        sal     rsi, 32
        or      rax, rsi
        ret

Both branch cases are longer, but especially strange is how .L3 uses five
instructions instead of "xor eax, eax".

Similar happens in every version I tried except for 4.5 and 4.6.

Live demo: https://godbolt.org/z/4Lisy6

Reply via email to