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

Hal Finkel hfinkel at anl.gov
Fri Oct 17 05:12:12 PDT 2014


----- Original Message -----
> From: "Aliaksei Zasenka" <listhex at gmail.com>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: LLVMdev at cs.uiuc.edu
> Sent: Friday, October 17, 2014 6:57:14 AM
> Subject: Re: [LLVMdev] opt -O2 leads to incorrect operation (possibly a bug in the DSE)
> 
> 
> 
> Hal,
> Thanks for your answer. Should I report a bug?

Generally speaking, yes. In this case, don't bother; I removed the offending logic in r220035. Thanks for isolating the problem!

 -Hal

> 
> Best regards,
> Alexey
> 
> 
> 2014-10-17 14:30 GMT+03:00 Hal Finkel < hfinkel at anl.gov > :
> 
> 
> 
> 
> ----- Original Message -----
> > From: "Aliaksei Zasenka" < listhex at gmail.com >
> > To: LLVMdev at cs.uiuc.edu
> > Sent: Friday, October 17, 2014 4:24:27 AM
> > Subject: [LLVMdev] opt -O2 leads to incorrect operation (possibly a
> > bug in the DSE)
> > 
> > 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?
> > 
> 
> Looks like a bug in DSE, you're not doing anything wrong. We don't
> test much without data layouts anymore. This code might pre-date
> DSE's handling of memcpy intrinsics (just a guess). In any case,
> we'll fix it.
> 
> -Hal
> 
> > 
> > 
> > 
> > Best regards,
> > Alexey
> > 
> > _______________________________________________
> > LLVM Developers mailing list
> > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> > 
> 
> --
> Hal Finkel
> Assistant Computational Scientist
> Leadership Computing Facility
> Argonne National Laboratory
> 
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-dev mailing list