[LLVMdev] opt -O2 leads to incorrect operation (possibly a bug in the DSE)

Aliaksei Zasenka
Fri, 17 Oct 2014 09:24:27 -0000

Hi all,

Consider the following example:

define void @fn(i8* %buf) #0 {
entry:
  %arrayidx = getelementptr i8* %buf, i64 18
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %arrayidx, i8* %buf, i64
18, i32 1, i1 false)
  %arrayidx1 = getelementptr i8* %buf, i64 18
  store i8 1, i8* %arrayidx1, align 1
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %buf, i8* %arrayidx, i64
18, i32 1, i1 false)
  ret void
}

I ran opt -O2 ex.ll -S, and got:

define void @fn(i8* nocapture %buf) #0 {
entry:
  %arrayidx = getelementptr i8* %buf, i64 18
  store i8 1, i8* %arrayidx, align 1
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %buf, i8* %arrayidx, i64
18, i32 1, i1 false)
  ret void
}

In that case previous contents of bytes 0-17 are overwritten by bytes 18-35
(pre-opt code doesn't do that).

Another point, if I change the code to:

define void @fn(i8* %buf) #0 {
entry:
  %arrayidx = getelementptr i8* %buf, i64 18
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %arrayidx, i8* %buf, i64
18, i32 1, i1 false)
;changing 19th byte, not 18th:
  %arrayidx1 = getelementptr i8* %buf, i64 19
  store i8 1, i8* %arrayidx1, align 1
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %buf, i8* %arrayidx, i64
18, i32 1, i1 false)
  ret void
}

I get correct piece of code:

define void @fn(i8* nocapture %buf) #0 {
entry:
  %arrayidx = getelementptr i8* %buf, i64 18
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %arrayidx, i8* %buf, i64
18, i32 1, i1 false)
  %arrayidx1 = getelementptr i8* %buf, i64 19
  store i8 1, i8* %arrayidx1, align 1
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %buf, i8* %arrayidx, i64
18, i32 1, i1 false)
  ret void
}

Adding some datalayout to module also solves the issue.

-print-after-all shows that the 'Dead Store Elimination' pass erases
first
call to memcpy.

I found that the following code in DeadStoreElimination.cpp leads to such
behavior:
      if (DL == nullptr && Later.Ptr->getType() ==
Earlier.Ptr->getType())
        return OverwriteComplete;

Is this issue a bug in DSE or maybe I'm doing some wrong?

Best regards,
Alexey
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20141017/376f01fb/attachment.html>