https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89567
Bug ID: 89567
Summary: [missed-optimization] Should not be initializing
unused struct parameter members
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: eyalroz at technion dot ac.il
Target Milestone: ---
The issue is captured in the example here:
https://gcc.godbolt.org/z/_U4X80
The issue was first described in this StackOverflow question:
https://stackoverflow.com/q/54964323/1593077
Consider the following code:
__attribute__((noinline)) int foo1(int x, int y)
{
return x;
}
int bar1(int* a)
{
int b = foo1(a[5], a[10]);
return b * b;
}
GCC (with -O3) optimizes-out the initialization of the y parameter with the
a[10] argument, saving one of the two memory reads. This is good.
Now suppose we put those two int parameters into a struct:
struct two_ints { int x, y; };
__attribute__((noinline)) int foo2(struct two_ints s)
{
return s.x;
}
int bar2(int* a)
{
struct two_ints ti = { a[5], a[10] };
int b = foo2(ti);
return b * b;
}
There shouldn't be any difference, right? The parameters (certainly as far as
the assembly, which recognizes no such thing as "structs", is concerned) are
two integers; and the second one is not used. So I would expect to see the same
assembly code. Yet... I don't. Both integers are initialized and two `mov
eax, DWORD PTR [rdx+something]` instructions are executed.
This behavior also occurs also with "GCC trunk" on GodBolt, i.e. GCC version
9.0.1.