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

            Bug ID: 78869
           Summary: Strange __builtin_memcpy optimisations
           Product: gcc
           Version: 6.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tvrtko.ursulin at linux dot intel.com
  Target Milestone: ---

Created attachment 40375
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40375&action=edit
Intermediate file as requested.

Hi,

I have observed a strange code being generated from simple usage of
__builtin_memcpy. Test case is simply this:

void memcpy_test(char *ptr)
{
        char temp[64];

        __builtin_memcpy(temp, ptr + 64, 64);
        __builtin_memcpy(ptr, temp, 64);
}

void memcpy_test2(void *ptr)
{
        char temp[64];

        __builtin_memcpy(&temp[0], ptr + 64, 64);
        __builtin_memcpy(ptr, &temp[0], 64);
}

When I compile this with -O2 memcpy_test generates a byte-per-byte unrolled
copy for memcpy_test, while memcpy_test2 correctly generates a qword-by-qword
unrolled copy.

If I change the optimisation level to -O3 then the memcpy_test becomes XMM
optimised, so 128-bit moves, while memcpy_test2 remains qword-by-qword.

First question obviously is that how come it chooses to do byte-per-byte copy
and secondly why is there a difference in the code generated between the two
functions?

Thanks!



[tursulin@t460p ~]$ gcc -v -save-temps -c -O2 memcpy-test.c 
Using built-in specs.
COLLECT_GCC=gcc
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr
--mandir=/usr/share/man --infodir=/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-linker-hash-style=gnu --enable-plugin --enable-initfini-array
--disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function
--with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 6.2.1 20160916 (Red Hat 6.2.1-2) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-mtune=generic'
'-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/6.2.1/cc1 -E -quiet -v memcpy-test.c
-mtune=generic -march=x86-64 -O2 -fpch-preprocess -o memcpy-test.i
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-redhat-linux/6.2.1/include-fixed"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-redhat-linux/6.2.1/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-redhat-linux/6.2.1/include
 /usr/local/include
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-mtune=generic'
'-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/6.2.1/cc1 -fpreprocessed memcpy-test.i
-quiet -dumpbase memcpy-test.c -mtune=generic -march=x86-64 -auxbase
memcpy-test -O2 -version -o memcpy-test.s
GNU C11 (GCC) version 6.2.1 20160916 (Red Hat 6.2.1-2) (x86_64-redhat-linux)
        compiled by GNU C version 6.2.1 20160916 (Red Hat 6.2.1-2), GMP version
6.1.1, MPFR version 3.1.4, MPC version 1.0.2, isl version 0.14 or 0.13
warning: MPFR header version 3.1.4 differs from library version 3.1.5.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C11 (GCC) version 6.2.1 20160916 (Red Hat 6.2.1-2) (x86_64-redhat-linux)
        compiled by GNU C version 6.2.1 20160916 (Red Hat 6.2.1-2), GMP version
6.1.1, MPFR version 3.1.4, MPC version 1.0.2, isl version 0.14 or 0.13
warning: MPFR header version 3.1.4 differs from library version 3.1.5.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c310f7e29a18a5e3f0310939bf78ca27
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-mtune=generic'
'-march=x86-64'
 as -v --64 -o memcpy-test.o memcpy-test.s
GNU assembler version 2.26.1 (x86_64-redhat-linux) using BFD version version
2.26.1-1.fc24
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/6.2.1/:/usr/libexec/gcc/x86_64-redhat-linux/6.2.1/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/6.2.1/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/6.2.1/:/usr/lib/gcc/x86_64-redhat-linux/6.2.1/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/6.2.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-mtune=generic'
'-march=x86-64'

Reply via email to