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.