[llvm-bugs] [Bug 27690] New: Loop vectorizer removes meaningful casts resulting in wrong output

via llvm-bugs llvm-bugs at lists.llvm.org
Mon May 9 14:28:26 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=27690

            Bug ID: 27690
           Summary: Loop vectorizer removes meaningful casts resulting in
                    wrong output
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Loop Optimizer
          Assignee: unassignedbugs at nondot.org
          Reporter: andrew.b.adams at gmail.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

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:
http://buildbot.halide-lang.org:8010/builders/arm64-linux-64-trunk/builds/232/steps/make%20test_correctness/logs/stdio

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160509/cadde8d7/attachment.html>


More information about the llvm-bugs mailing list