<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - Loop vectorizer removes meaningful casts resulting in wrong output"
   href="https://llvm.org/bugs/show_bug.cgi?id=27690">27690</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Loop vectorizer removes meaningful casts resulting in wrong output
          </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>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Loop Optimizer
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>andrew.b.adams@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The following .ll computes half the difference ((a - b)/2) of i8 values, doing
the subtract in an i16 temporary:

define void @fn(i8 * %a_ptr, i8 * %b_ptr, i8 * %c_ptr) {
entry:
        br label %for.body

for.body:
        %loop_var = phi i64 [0, %entry], [%next_loop_var, %for.body]
        %next_loop_var = add i64 %loop_var, 1
        %a_addr = getelementptr inbounds i8, i8 * %a_ptr, i64 %loop_var
        %b_addr = getelementptr inbounds i8, i8 * %b_ptr, i64 %loop_var
        %c_addr = getelementptr inbounds i8, i8 * %c_ptr, i64 %loop_var
        %a = load i8, i8 * %a_addr
        %b = load i8, i8 * %b_addr
        %a16 = sext i8 %a to i16
        %b16 = sext i8 %b to i16
        %diff = sub i16 %a16, %b16
        %avg16 = ashr i16 %diff, 1
        %avg = trunc i16 %avg16 to i8
        store i8 %avg, i8 * %c_addr
        %exitcond = icmp eq i64 %next_loop_var, 1000
        br i1 %exitcond, label %exit, label %for.body
exit:
        ret void
}

The loop vectorizer creates a vector version that looks like this:

  %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.body.preheader ]
  %0 = getelementptr inbounds i8, i8* %a_ptr, i64 %index
  %1 = getelementptr inbounds i8, i8* %b_ptr, i64 %index
  %2 = getelementptr inbounds i8, i8* %c_ptr, i64 %index
  %3 = bitcast i8* %0 to <4 x i8>*
  %4 = load <4 x i8>, <4 x i8>* %3, align 1, !alias.scope !0
  %5 = bitcast i8* %1 to <4 x i8>*
  %6 = load <4 x i8>, <4 x i8>* %5, align 1, !alias.scope !3
  %7 = sub nsw <4 x i8> %4, %6
  %8 = lshr <4 x i8> %7, <i8 1, i8 1, i8 1, i8 1>
  %9 = bitcast i8* %2 to <4 x i8>*
  store <4 x i8> %8, <4 x i8>* %9, align 1, !alias.scope !5, !noalias !7
  %index.next = add i64 %index, 4
  %10 = icmp eq i64 %index.next, 1000
  br i1 %10, label %exit.loopexit8, label %vector.body, !llvm.loop !8

The sext instructions are gone, and the subtraction is done in 8-bit. This
overflows and produces the wrong output. To repro, dump the ll at the top to
opt -O3.

This is very recent bug. Our buildbots just started failing due to it this
morning:
<a href="http://buildbot.halide-lang.org:8010/builders/arm64-linux-64-trunk/builds/232/steps/make%20test_correctness/logs/stdio">http://buildbot.halide-lang.org:8010/builders/arm64-linux-64-trunk/builds/232/steps/make%20test_correctness/logs/stdio</a></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>