[LLVMdev] opt -O2 leads to incorrect operation (possibly a bug in the DSE) (original) (raw)
Hal Finkel hfinkel at anl.gov
Fri Oct 17 04:30:41 PDT 2014
- Previous message: [LLVMdev] opt -O2 leads to incorrect operation (possibly a bug in the DSE)
- Next message: [LLVMdev] opt -O2 leads to incorrect operation (possibly a bug in the DSE)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
----- 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
- Previous message: [LLVMdev] opt -O2 leads to incorrect operation (possibly a bug in the DSE)
- Next message: [LLVMdev] opt -O2 leads to incorrect operation (possibly a bug in the DSE)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]