Uploaded image for project: 'vpp'
  1. vpp
  2. VPP-698

Effect of clib_memcpy optimized out when copying 8-15 bytes

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Open
    • Icon: Medium Medium
    • 17.10
    • None
    • VPPInfra
    • None

      While testing the memif plugin (src/plugins/memif) we discovered that one of the calls to clib_memcpy looses its effect in the release build. Specifically, the issue occurs in src/plugins/memif/memif.c, line 371:

                 else if (cmsg->cmsg_level == SOL_SOCKET
                          && cmsg->cmsg_type == SCM_RIGHTS)
                   {
                     clib_memcpy (fd_array, CMSG_DATA (cmsg), sizeof (fd_array));
                   }
      

      Here clib_memcpy has no effect when the plugin is build with the second level of optimizations.

      Relevant parameters of my system:

      $ uname -a
      Linux milan-Ubuntu 4.4.0-72-generic #93-Ubuntu SMP Fri Mar 31 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
      $ gcc --version
      gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
      

      You can tell if the issue is reproducible on your system using the following simple program called clib_memcpy.c:

      #include <stdio.h>
      
      #include <vppinfra/types.h>
      #if __AVX__
      #include <vppinfra/memcpy_avx.h>
      #elif __SSSE3__
      #include <vppinfra/memcpy_sse3.h>
      #endif
      
      #define COUNT  2  // misbehaves for two and three integers; on my system sizeof(int) == 4
      
      // Problematic part (from memcpy_sse3.h):
      //   217       if (n & 0x08)
      //   218         {
      //   219           *(u64 *) dstu = *(const u64 *) srcu;
      //   220         }
      
      int main() {
        int src[COUNT] = { 0 }, dst[COUNT] = { 0 };
        src[0] = 1;
      #if COUNT > 1
        src[1] = 5;
      #endif
      
        clib_memcpy(dst, src, sizeof src);
      
        printf("sizeof(src) = %d, dst = { %d, %d }\n", sizeof(src), dst[0], dst[1]);
        return 0;
      }
      

      In my case the output is:

      $ gcc  clib_memcpy.c -w -mavx2  -o clib_memcpy
      $ ./clib_memcpy 
      sizeof(src) = 8, dst = { 1, 5 }
      $ gcc -O2  clib_memcpy.c -w -mavx2  -o clib_memcpy
      $ ./clib_memcpy 
      sizeof(src) = 8, dst = { 0, 0 }
      $ gcc  clib_memcpy.c -w -mssse3  -o clib_memcpy
      $ ./clib_memcpy 
      sizeof(src) = 8, dst = { 1, 5 }
      $ gcc -O2  clib_memcpy.c -w -mssse3  -o clib_memcpy
      $ ./clib_memcpy 
      sizeof(src) = 8, dst = { 0, 0 }
      

      The problem occurs when copying data of size between 8 and 15 bytes.

            dmarion Damjan Marion
            milanlenco Milan Lenco
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: