// RUN: %clangxx_msan -m64 -O2 %s -o %t && %run %t

#include <sanitizer/msan_interface.h>

struct S {
  S(int a0) : a(a0) {}
  int a;
  int b;
};

// Here S is passed to FooRun as a 64-bit integer.
// This triggers an optimization where 10000 * s.a is transformed into
// ((*(uint64_t *)&s) * (10000 * 2**32)) >> 32
// Test that MSan understands that this kills the uninitialized high half of S
// (i.e. S::b).
void FooRun(S s) {
  int64_t x = 10000 * s.a;
  __msan_check_mem_is_initialized(&x, sizeof(x));
}

int main(void) {
  S z(1);
  // Take &z to ensure that it is built on stack.
  S *volatile p = &z;
  FooRun(z);
  return 0;
}

Fix handling of multiplication by a constant with a number of trailing zeroes.
[msan] Fix handling of multiplication by a constant with a number of trailing zeroes.

Multiplication by an integer with a number of trailing zero bits leaves
the same number of lower bits of the result initialized to zero.
This change makes MSan take this into account in the case of multiplication by
a compile-time constant.

We don't handle the general, non-constant, case because
(a) it's not going to be cheap (computation-wise);
(b) multiplication by a partially uninitialized value in user code is
    a bad idea anyway.

Constant case must be handled because it appears from LLVM optimization of a
completely valid user code, as the test case in compiler-rt demonstrates.


git-svn-id: c199f293c43da69278bea8e88f92242bf3aa95f7@211092 91177308-0d34-0410-b5e6-96231b3b80d8
