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

            Bug ID: 109486
           Summary: Optimization regression with pseudodestructors
           Product: gcc
           Version: 11.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pshevchuk at pshevchuk dot com
  Target Milestone: ---

Created attachment 54840
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54840&action=edit
Source file, the same as in the text.

GCC 11 and higher seems to produce a loop when compiling the following code
with O3 (attached):

template <typename T>
class SillyVector final {
    void clear() {
        while (ptr_ > data_) {
            (--ptr_)->~T();
        }
    }

private:
    T *data_, *ptr_;
};

template class SillyVector<long>;

The (abridged) amd64 assembly generated by GCC11 is:

_ZN11SillyVectorIlE5clearEv:
.LFB1:
        .cfi_startproc
        movq    8(%rdi), %rax
        movq    (%rdi), %rdx
        cmpq    %rdx, %rax
        jbe     .L1
        .p2align 4,,10
        .p2align 3
.L3:
        subq    $8, %rax
        movq    %rax, 8(%rdi)
        cmpq    %rdx, %rax
        ja      .L3
.L1:
        ret

GCC10 (and older versions of gcc in general) produce this:

_ZN11SillyVectorIlE5clearEv:
.LFB1:
        .cfi_startproc
        movq    8(%rdi), %rdx
        movq    (%rdi), %rcx
        cmpq    %rcx, %rdx
        jbe     .L1
        leaq    -1(%rdx), %rax
        subq    %rcx, %rax
        notq    %rax
        andq    $-8, %rax
        addq    %rdx, %rax
        movq    %rax, 8(%rdi)
.L1:
        ret


GCC10 version seems superior for the most cases.

Compilers used are
GCC10:
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-10/root/usr
--mandir=/opt/rh/devtoolset-10/root/usr/share/man
--infodir=/opt/rh/devtoolset-10/root/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared
--enable-threads=posix --enable-checking=release --enable-multilib
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-gcc-major-version-only --with-linker-hash-style=gnu
--with-default-libstdcxx-abi=gcc4-compatible --enable-plugin
--enable-initfini-array
--with-isl=/builddir/build/BUILD/gcc-10.2.1-20210130/obj-x86_64-redhat-linux/isl-install
--disable-libmpx --enable-gnu-indirect-function --with-tune=generic
--with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.1 20210130 (Red Hat 10.2.1-11) (GCC) 

GCC11:
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-11/root/usr
--mandir=/opt/rh/devtoolset-11/root/usr/share/man
--infodir=/opt/rh/devtoolset-11/root/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared
--enable-threads=posix --enable-checking=release --enable-multilib
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-gcc-major-version-only --with-linker-hash-style=gnu
--with-default-libstdcxx-abi=gcc4-compatible --enable-plugin
--enable-initfini-array
--with-isl=/builddir/build/BUILD/gcc-11.2.1-20210728/obj-x86_64-redhat-linux/isl-install
--enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64
--build=x86_64-redhat-linux
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.2.1 20210728 (Red Hat 11.2.1-1) (GCC) 

Intermediate file is omitted as no preprocessor is necessary to reproduce.
arm64 versions seem to exhibit the same behavior: loop in gcc11, no loop in gcc
10
Call to pseudo destructor is necessary for the issue to arise, it doesn't
happen if such call is omitted

Reply via email to