This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/84085] New: Array element is unnecessary loaded twice
- From: "bugzilla at poradnik-webmastera dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sun, 28 Jan 2018 20:50:47 +0000
- Subject: [Bug c/84085] New: Array element is unnecessary loaded twice
- Auto-submitted: auto-generated
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: bugzilla@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.