<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - MemorySanitizer false positive in divide-by-undef"
   href="https://bugs.llvm.org/show_bug.cgi?id=37523">37523</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>MemorySanitizer false positive in divide-by-undef
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Miscellaneous Instrumentation passes
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>eugeni.stepanov@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>#include <xmmintrin.h>
#include <sanitizer/msan_interface.h>

int main() {
  volatile int scale = 5;
  auto zz = _mm_div_ps(_mm_set1_ps(255), _mm_set1_ps(scale));
  __msan_print_shadow(&zz, sizeof(zz));
}

Until recently, it was represented like this in the IR:
  %vecinit.i = insertelement <4 x float> undef, float %conv, i32 0
  %vecinit3.i = shufflevector <4 x float> %vecinit.i, <4 x float> undef, <4 x
i32> zeroinitializer
  %div.i = fdiv <4 x float> <float 2.550000e+02, float 2.550000e+02, float
2.550000e+02, float 2.550000e+02>, %vecinit3.i

The something changed, and now we fill the first lane only, divide, and then
broadcast:

  %vecinit.i = insertelement <4 x float> undef, float %conv, i32 0
  %0 = fdiv <4 x float> <float 2.550000e+02, float undef, float undef, float
undef>, %vecinit.i
  %1 = shufflevector <4 x float> %0, <4 x float> undef, <4 x i32>
zeroinitializer

This in effect divides undef by undef and throws away the result.

MSan instruments division with a strict check for the divisor's shadow,
assuming that division by an uninitialized value may trap. This is not aligned
with IR semantics: LangRef describes fdiv as side effect free.

MSan should delay the check until the value is actually used (or not, like in
this case) by combining and propagating shadow.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>