vppinfra: fix masks in AVX512 clib_count_equal_* 88/34488/2
authorDmitry Valter <d-valter@yandex-team.ru>
Sun, 14 Nov 2021 17:05:44 +0000 (17:05 +0000)
committerDamjan Marion <dmarion@me.com>
Mon, 15 Nov 2021 12:57:26 +0000 (12:57 +0000)
Mask result of uAxB_is_equal_mask when buffer is masked. Otherwise it
return vector length B as a result for zeroed words.
This bug caused crashes in error_drop in tests on Ice Lake.

Type: fix
Fixes: 7459be1b3626b608e60df574343a1432a068ebce
Change-Id: I56183e77f8a8ab6c530e79b465067958de84dceb
Signed-off-by: Dmitry Valter <d-valter@yandex-team.ru>
src/vppinfra/vector/count_equal.h
src/vppinfra/vector/test/count_equal.c

index a2aeecd..ca2fbb7 100644 (file)
@@ -85,7 +85,8 @@ clib_count_equal_u32 (u32 *data, uword max_count)
     {
       u32 mask = pow2_mask (max_count - count);
       u32 bmp =
-       u32x16_is_equal_mask (u32x16_mask_load_zero (data, mask), splat);
+       u32x16_is_equal_mask (u32x16_mask_load_zero (data, mask), splat) &
+       mask;
       return count + count_trailing_zeros (~bmp);
     }
 #elif defined(CLIB_HAVE_VEC256)
@@ -108,11 +109,12 @@ clib_count_equal_u32 (u32 *data, uword max_count)
     }
   if (count == max_count)
     return count;
-#if defined(CxLIB_HAVE_VEC256_MASK_LOAD_STORE)
+#if defined(CLIB_HAVE_VEC256_MASK_LOAD_STORE)
   else
     {
       u32 mask = pow2_mask (max_count - count);
-      u32 bmp = u32x8_is_equal_mask (u32x8_mask_load_zero (data, mask), splat);
+      u32 bmp =
+       u32x8_is_equal_mask (u32x8_mask_load_zero (data, mask), splat) & mask;
       return count + count_trailing_zeros (~bmp);
     }
 #endif
@@ -243,7 +245,8 @@ clib_count_equal_u8 (u8 *data, uword max_count)
   else
     {
       u64 mask = pow2_mask (max_count - count);
-      u64 bmp = u8x64_is_equal_mask (u8x64_mask_load_zero (data, mask), splat);
+      u64 bmp =
+       u8x64_is_equal_mask (u8x64_mask_load_zero (data, mask), splat) & mask;
       return count + count_trailing_zeros (~bmp);
     }
 #endif
@@ -265,7 +268,8 @@ clib_count_equal_u8 (u8 *data, uword max_count)
   else
     {
       u32 mask = pow2_mask (max_count - count);
-      u64 bmp = u8x32_msb_mask (u8x32_mask_load_zero (data, mask) == splat);
+      u64 bmp =
+       u8x32_msb_mask (u8x32_mask_load_zero (data, mask) == splat) & mask;
       return count + count_trailing_zeros (~bmp);
     }
 #endif
index cd1c8a5..1ca9735 100644 (file)
                                                                               \
     mprotect (data, 1ULL < ps, PROT_NONE);                                    \
                                                                               \
-    for (int i = 1; i <= (1 << ps) / sizeof (data[0]); i++)                   \
-      data[-i] = 7;                                                           \
-                                                                              \
-    for (int i = 0; i < ARRAY_LEN (lengths); i++)                             \
+    for (u8 d = 0; d < 255; d++)                                              \
       {                                                                       \
-       uword rv, len = lengths[i];                                           \
-                                                                              \
-       if ((rv = wfn_##type (data - len, len)) != len)                       \
+       for (int i = 1; i <= (1 << ps) / sizeof (data[0]); i++)               \
+         data[-i] = d;                                                       \
+       for (int i = 0; i < ARRAY_LEN (lengths); i++)                         \
          {                                                                   \
-           err = clib_error_return (                                         \
-             err, "testcase 1 failed for len %u (rv %u)", len, rv);          \
-           goto done;                                                        \
-         }                                                                   \
+           uword rv, len = lengths[i];                                       \
                                                                               \
-       data[-1] = 8;                                                         \
-       if (len > 1 && ((rv = wfn_##type (data - len, len)) != len - 1))      \
-         {                                                                   \
-           err = clib_error_return (                                         \
-             err, "testcase 2 failed for len %u (rv %u)", len, rv);          \
-           goto done;                                                        \
-         }                                                                   \
-       data[-1] = 7;                                                         \
+           if ((rv = wfn_##type (data - len, len)) != len)                   \
+             {                                                               \
+               err = clib_error_return (                                     \
+                 err, "testcase 1 failed for len %u data %u(rv %u)", len, d, \
+                 rv);                                                        \
+               goto done;                                                    \
+             }                                                               \
                                                                               \
-       data[-2] = 8;                                                         \
-       if (len > 2 && ((rv = wfn_##type (data - len, len)) != len - 2))      \
-         {                                                                   \
-           err = clib_error_return (                                         \
-             err, "testcase 3 failed for len %u (rv %u)", len, rv);          \
-           goto done;                                                        \
+           data[-1] = d + 1;                                                 \
+           if (len > 1 && ((rv = wfn_##type (data - len, len)) != len - 1))  \
+             {                                                               \
+               err = clib_error_return (                                     \
+                 err, "testcase 2 failed for len %u data %u (rv %u)", len,   \
+                 d, rv);                                                     \
+               goto done;                                                    \
+             }                                                               \
+           data[-1] = d;                                                     \
+                                                                              \
+           data[-2] = d + 1;                                                 \
+           if (len > 2 && ((rv = wfn_##type (data - len, len)) != len - 2))  \
+             {                                                               \
+               err = clib_error_return (                                     \
+                 err, "testcase 3 failed for len %u data %u (rv %u)", len,   \
+                 d, rv);                                                     \
+               goto done;                                                    \
+             }                                                               \
+           data[-2] = d;                                                     \
          }                                                                   \
-       data[-2] = 7;                                                         \
       }                                                                       \
                                                                               \
   done:                                                                       \