This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/80617] New: [missed optimization] Storing constant in two possibly-aliased locations


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80617

            Bug ID: 80617
           Summary: [missed optimization] Storing constant in two
                    possibly-aliased locations
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: herring at lanl dot gov
  Target Milestone: ---

Swapping (by move-construction/assignment) two instances of

struct A {                       // vaguely unique_ptr-like
  void *p;
  A(A &&a) : p(a.release()) {}
  ~A() {if(p) std::free(p);}     // not that you can't free(nullptr)
  void* release() {return std::exchange(p,nullptr);}
  void swap(A &a) {std::swap(p,a.p);}
  // Make temporary to guarantee destroying replaced p before returning:
  A& operator=(A &&a) {A(std::move(a)).swap(*this); return *this;}
};

can never result in a call to free (not even free(nullptr)), since all the
temporaries being destroyed have been moved-from.  However, due presumably to a
fear of aliasing (i.e., "A a={0}; std::swap(a,a);"), the optimizer does not
remove the conditionals:

        movq    (%rdi), %rbp
        movq    $0, (%rdi)     ; store #1
        movq    (%rsi), %rdx
        movq    $0, (%rsi)     ; this store could clobber #1
        movq    (%rdi), %rax   ; but this reads 0 regardless
        movq    %rdx, (%rdi)
        testq   %rax, %rax     ; testq 0, 0
        je      .L2            ; will always be taken
        ; call free, check the other object, call free again...

Thus std::swap<A> is several times as large and slow as the member swap:

        movq    (%rdi), %rax
        movq    (%rsi), %rdx
        movq    %rdx, (%rdi)
        movq    %rax, (%rsi)
        ret

Full example (including a hack to show the assembly from HEAD) at
https://wandbox.org/permlink/PZ7d7MwSVAlvrUA2

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]