https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77745
Bug ID: 77745
Summary: Inconsistent application of aliasing rules
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: amonakov at gcc dot gnu.org
Target Milestone: ---
For the following C++ testcase:
#include <new>
long foo(char *c1, char *c2)
{
long *p1 = new(c1) long;
*p1 = 100;
long long *p2 = new(c2) long long;
*p2 = 200;
long *p3 = new(c2) long;
*p3 = 200;
return *p1;
}
GCC generates on x86-64:
movq $100, (%rdi)
movl $100, %eax
movq $200, (%rsi)
ret
i.e. the routine returns 100 unconditionally, regardless of whether c1 and c2
point to the same storage. However, changing '*p3 = 200' to e.g. '*p3 = 300'
(another constant), or using a 32-bit target (so the types are no longer same
size) suppresses the optimization.
Since this source code is either well-defined or not regardless of the last
constant value, or "bitness" of the target, there's an internal inconsistency
in GCC: either it performed a misoptimization in the above output, or misses
the same optimization in other circumstances.
I see the propagation happening in fre1 pass. GCC 4.5 didn't perform this
transformation, so if it's invalid, that's a regression.