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.

Reply via email to