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

            Bug ID: 84085
           Summary: Array element is unnecessary loaded twice
           Product: gcc
           Version: 7.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bugzi...@poradnik-webmastera.com
  Target Milestone: ---

[code]
#define N 9

struct S1
{
    int a1[N][N];
};
struct S2
{
    int a2[N][N];
    int a3[N][N];
};

void test1(S1* s1, S2* s2)
{
    s2->a2[N-1][N-1] = s1->a1[N-1][N-1];
    s2->a3[N-1][N-1] = 1u << s1->a1[N-1][N-1];
}

void test2(S1* s1, S2* s2)
{
    const int n = N*N-1;
    *((&s2->a2[0][0] + n)) = *(&s1->a1[0][0] + n);
    *((&s2->a3[0][0] + n)) = 1u << *(&s1->a1[0][0] + n);
}

void test3(S1* s1, S2* s2)
{
    const int n = N*N-1;
    int x = *(&s1->a1[0][0] + n);
    *((&s2->a2[0][0] + n)) = x;
    *((&s2->a3[0][0] + n)) = 1u << x;
}
[/code]

[out]
test1(S1*, S2*):
  mov ecx, DWORD PTR [rdi+320]
  mov eax, 1
  sal eax, cl
  mov DWORD PTR [rsi+320], ecx
  mov DWORD PTR [rsi+644], eax
  ret
test2(S1*, S2*):
  mov eax, DWORD PTR [rdi+320]
  mov DWORD PTR [rsi+320], eax
  mov ecx, DWORD PTR [rdi+320]
  mov eax, 1
  sal eax, cl
  mov DWORD PTR [rsi+644], eax
  ret
test3(S1*, S2*):
  mov ecx, DWORD PTR [rdi+320]
  mov eax, 1
  sal eax, cl
  mov DWORD PTR [rsi+320], ecx
  mov DWORD PTR [rsi+644], eax
  ret
[/out]

All 3 functions are equivalent. However when 2D array is treated as a 1D one,
gcc for some reason loads array element twice (function test2). Local variable
added in test3 allows to get the same code as for test1. I have found this
during writing code for AARCH64, but x86_64 is also affected.

gcc 8 (trunk) does not have this problem.

Reply via email to