<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>