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

            Bug ID: 90345
           Summary: too pessimistic check whether pointer may alias local
                    variable
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vanyacpp at gmail dot com
  Target Milestone: ---

Consider the following example (reduced from a real program):

#include <cstdlib>
#include <cstdint>

struct big_integer
{
    void push_back(uint32_t const&);
    size_t size;
    uint32_t* digits;
};

big_integer& operator*=(big_integer& a, uint32_t b)
{
    uint64_t const BASE = 1ull << 32;

    uint32_t carry = 0;
    for (size_t i = 0; i != a.size; i++)
    {
        uint64_t sum = 1ull * a.digits[i] * b + carry;
        carry = static_cast<uint32_t>(sum / BASE);
        a.digits[i] = static_cast<uint32_t>(sum % BASE);
    }

    if (carry)
    {
        a.push_back(carry);
        //a.push_back(uint32_t(carry));
    }

    return a;
}

GCC 9.1 compiles the inner loop to this:
.L9:
        mov     esi, DWORD PTR [rsp+12]      ; load carry
.L5:
        mov     edx, DWORD PTR [rcx]
        add     rcx, 4
        imul    rdx, r8
        add     rdx, rsi
        mov     rsi, rdx
        shr     rsi, 32
        mov     DWORD PTR [rsp+12], esi      ; store carry
        mov     DWORD PTR [rcx-4], edx
        cmp     r9, rcx
        jne     .L9

As one can see carry is spilled to stack and it is loaded and stored at each
iteration of the loop. Loading and storing carry at each iteration is not
needed: it is a local variable and its address is not taken.

My guess is that GCC believes that it escapes because of the push_back after
the loop. At least if I make a copy of carry before push_back'ing it (as shown
in the comment) the problem goes away.

I think that alias analysis can be improved here: carry may not alias
a.digits[i] because it escapes only after the loop.

Reply via email to