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.