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'