Skip to content

MSAN reports false positive with demotion of int32_t vector to int8_t vector on AVX512 #77119

Open
@johnplatts

Description

@johnplatts

Here is a test C program that where MSAN reports false positives when compiled with -O2 -fsanitize=memory -march=skylake-avx512 with Clang 17.0.6:

#include <immintrin.h>
#include <inttypes.h>
#include <stdalign.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>

static inline uint64_t SplitMix64(uint64_t z) {
  z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9);
  z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB);
  return z ^ (z >> 31);
}

static inline void RandomSeed(uint64_t* s0, uint64_t* s1) {
  uint64_t seed =
      SplitMix64((uint64_t)time(NULL) + UINT64_C(0x123456789) +
                 (uint64_t)((uintptr_t)s0) + (uint64_t)((uintptr_t)s1));

  *s0 = seed;
  *s1 = SplitMix64(seed);
}

static inline uint64_t RandomValue(uint64_t* s0, uint64_t* s1) {
  uint64_t next_s1 = *s0;
  const uint64_t next_s0 = *s1;
  const uint64_t bits = next_s0 + next_s1;
  *s0 = next_s0;
  next_s1 ^= next_s1 << 23;
  next_s1 ^= next_s0 ^ (next_s1 >> 18) ^ (next_s0 >> 5);
  *s1 = next_s1;
  return bits;
}

static inline __m128i DemoteM512I32ToI8(__m512i vect) {
  vect = _mm512_packs_epi32(vect, vect);
  vect = _mm512_packs_epi16(vect, vect);
  return _mm512_castsi512_si128(_mm512_permutexvar_epi32(
      _mm512_setr_epi32(0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12),
      vect));
}

static __attribute__((__noinline__)) void PrintInputAndResultValues(
    const int32_t* input_values, const int8_t* result_values) {
  printf("Input values:\n%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32
         ", %" PRId32 ", %" PRId32 ",\n%" PRId32 ", %" PRId32 ", %" PRId32
         ", %" PRId32 ", %" PRId32 ", %" PRId32 ",\n%" PRId32 ", %" PRId32
         ", %" PRId32 ", %" PRId32 "\n",
         input_values[0], input_values[1], input_values[2], input_values[3],
         input_values[4], input_values[5], input_values[6], input_values[7],
         input_values[8], input_values[9], input_values[10], input_values[11],
         input_values[12], input_values[13], input_values[14],
         input_values[15]);
  printf("Result values:\n%" PRId8 ", %" PRId8 ", %" PRId8 ", %" PRId8
         ", %" PRId8 ", %" PRId8 ", %" PRId8 ", %" PRId8 ", %" PRId8 ", %" PRId8
         ", %" PRId8 ", %" PRId8 ", %" PRId8 ",\n%" PRId8 ", %" PRId8
         ", %" PRId8 "\n",
         result_values[0], result_values[1], result_values[2], result_values[3],
         result_values[4], result_values[5], result_values[6], result_values[7],
         result_values[8], result_values[9], result_values[10],
         result_values[11], result_values[12], result_values[13],
         result_values[14], result_values[15]);
}

int main(int argc, char** argv) {
  (void)argc;
  (void)argv;

  uint64_t s0, s1;
  RandomSeed(&s0, &s1);

  alignas(64) int32_t input_values[16];
  alignas(16) int8_t result_values[16];

  for (size_t i = 0; i < 16; i++) {
    uint32_t bits = (uint32_t)RandomValue(&s0, &s1);
    int bit_len = (int)(RandomValue(&s0, &s1) % 31u) + 2;

    uint32_t msb = (uint32_t)(UINT32_C(1) << (bit_len - 1));
    input_values[i] = (int32_t)(((bits & (msb | (msb - 1))) ^ msb) - msb);
  }

  __m512i input_vect = _mm512_load_si512(input_values);
  __m128i result_vect = DemoteM512I32ToI8(input_vect);
  _mm_store_si128((__m128i*)result_values, result_vect);

  PrintInputAndResultValues(input_values, result_values);

  return 0;
}

Here is the error that MSAN reports when the above program is compiled with Clang 17.0.6:

==6170==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x56295a24d229 in main (/home/testuser/programming/avx512_demote_u32_to_i8_rand_vals_010524_clang_msan+0xc0229) (BuildId: 71568913205c15c4c114d9cedfd2ea9142f359b0)
    #1 0x7efc50829d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #2 0x7efc50829e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #3 0x56295a1be294 in _start (/home/testuser/programming/avx512_demote_u32_to_i8_rand_vals_010524_clang_msan+0x31294) (BuildId: 71568913205c15c4c114d9cedfd2ea9142f359b0)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/testuser/programming/avx512_demote_u32_to_i8_rand_vals_010524_clang_msan+0xc0229) (BuildId: 71568913205c15c4c114d9cedfd2ea9142f359b0) in main
Exiting

Here is the function that causes the false MSAN positive when compiled with -O2 -fsanitize=memory -march=skylake-avx512:

static inline __m128i DemoteM512I32ToI8(__m512i vect) {
  vect = _mm512_packs_epi32(vect, vect);
  vect = _mm512_packs_epi16(vect, vect);
  return _mm512_castsi512_si128(_mm512_permutexvar_epi32(
      _mm512_setr_epi32(0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12),
      vect));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions