ramosian-glider / memory-sanitizer

Automatically exported from code.google.com/p/memory-sanitizer
0 stars 0 forks source link

Missing origin in a vectorized loop #56

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <sanitizer/msan_interface.h>

static void variance(const unsigned char *src_ptr, int source_stride,
                     const unsigned char *ref_ptr, int recon_stride, int w,
                     int h, unsigned int *sse, int *sum) {
  int i, j;
  int diff;

  *sum = 0;
  *sse = 0;

  for (i = 0; i < h; i++) {
    for (j = 0; j < w; j++) {
      /* fprintf(stderr, "--\n"); */
      diff = src_ptr[j] - ref_ptr[j];
      *sum += diff;
      *sse += diff * diff;
    }

    src_ptr += source_stride;
    ref_ptr += recon_stride;
  }
}

__attribute__((noinline)) unsigned int vp8_variance16x16_c(
    const unsigned char *src_ptr, int source_stride,
    const unsigned char *ref_ptr, int recon_stride, unsigned int *sse) {
  unsigned int var;
  int avg;

  variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16, &var, &avg);
  *sse = var;
  return (var - (((unsigned int)avg * avg) >> 8));
}

int main(void) {
  unsigned char *p;
  unsigned char *q;
  posix_memalign((void **)&p, 1024, 1024 * 1024);
  posix_memalign((void **)&q, 1024, 1024 * 1024);
  memset(q, 0, 1024 * 1024);
  unsigned int sse;
  unsigned int z = vp8_variance16x16_c(p, 1024, q, 1024, &sse);
  __msan_print_shadow(&z, sizeof(z));
  return 0;
}

Compile with -O2 -fsanitize=memory -fsanitize-memory-track-origins -xc.

Output:
Shadow map of [0x3fffa0da5f40, 0x3fffa0da5f44), 4 bytes:
0x3fffa0da5f40: ff000000 ........ ........ ........  |A . . .|

Origin A (origin_id 0):
  invalid origin id(0)

Uncommenting fprintf() call seems to break loop vectorization and "fixes" MSan.
MSan fails to propagate origin through the vectorized loop for some reason.

Original issue reported on code.google.com by euge...@google.com on 9 Jun 2014 at 12:33

GoogleCodeExporter commented 8 years ago
This comes from inexact instrumentation of shufflevector.
We pick origin that corresponds to the first not fully initialized operand, 
which is a gross oversimplification.
It's very common for shufflevector to have partially uninitialized (often 
literally undef) operands which do not make it the result. Even worse, they may 
affect shufflevector result, but get dropped somewhere later.

It looks like we need to track vector origins per-element.

Original comment by euge...@google.com on 9 Jun 2014 at 2:02

GoogleCodeExporter commented 8 years ago
A workaround in r210472 should cover this case, but it is not a complete fix.

Original comment by euge...@google.com on 9 Jun 2014 at 2:37

GoogleCodeExporter commented 8 years ago
Adding Project:MemorySanitizer as part of GitHub migration.

Original comment by gli...@google.com on 30 Jul 2015 at 9:22