<div dir="ltr"><div>Ok, now I think I've found a bug:</div><div><br></div><div>Consider this C code:</div><div>void bar(int b) {</div><div>  int a[10];</div><div>  memset(a, b, 10);</div><div>}</div><div><br></div><div>which generates this IR code:</div><div>define dso_local void @bar(i32 %b) #0 {<br>entry:                             <br>  %b.addr = alloca i32, align 4       <br>  %a = alloca [10 x i32], align 16  <br>  store i32 %b, i32* %b.addr, align 4 <br>  %arraydecay = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 0<br>  %0 = bitcast i32* %arraydecay to i8*<br>  %1 = load i32, i32* %b.addr, align 4 <br>  %2 = trunc i32 %1 to i8 <br>  call void @llvm.memset.p0i8.i64(i8* align 16 %0, i8 %2, i64 10, i1 false) <br>  ret void               <br>}</div><div><br></div><div>Now I have a pass that inserts an intrinsic with IntrReadMem into the IR:</div><div><div>define dso_local void @bar(i32 %b) #0 {<br>entry:                             <br>  %b.addr = alloca i32, align 4       <br>  %a = alloca [10 x i32], align 16  <br>  store i32 %b, i32* %b.addr, align 4 <br>  %arraydecay = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 0<br>  %0 = bitcast i32* %arraydecay to i8*<br>  %1 = load i32, i32* %b.addr, align 4 <br>  %2 = trunc i32 %1 to i8 <br>  call void @llvm.memset.p0i8.i64(i8* align 16 %0, i8 %2, i64 10, i1 false)<br><div><b>  tail call void @mem_read_test(i8* %0)</b></div></div><div>  ret void               <br>}</div><div><br></div><div>; Function Attrs: nounwind readonly         <br>declare void @mem_read_test(i8*) #2 <br></div><div><br></div><div>However, the call to memset() still got optimized away by DSE. What am I missing here? Or this is indeed a bug in DSE?</div><div><br></div></div><div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">Son Tuan Vu</div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jul 24, 2019 at 6:47 PM Doerfert, Johannes <<a href="mailto:jdoerfert@anl.gov">jdoerfert@anl.gov</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">You are on the right track. Addresses could get exposed in various ways,<br>
a probably non-exclusive list is:<br>
 - passed as arguments<br>
 - communicated through a global<br>
 - via I/O, or more general, system calls. This includes all forms of<br>
   synchronization, e.g., inter-lane communication.<br>
 - transitively passed by any of the means above, e.g., the address of a<br>
   pointer to the object could be exposed.<br>
<br>
So if we take the example below and add:<br>
  bar(&A[50]);<br>
just before the call to unknown, we have to assume A is known to unknown<br>
now, at least if we do not have information about bar that would suggest<br>
otherwise.<br>
<br>
<br>
On 07/24, Son Tuan VU wrote:<br>
> Hi Johannes,<br>
> <br>
> Thanks for your reply. I now see more clearly how things work with these<br>
> properties. However, what would be an object whose address is potentially<br>
> known by a callee? I suppose the intrinsic arguments and global variable?<br>
> <br>
> So IIUC, if not restricted by *only properties, an intrinsic could access<br>
> to:<br>
> - only its arguments if IntrArgMemOnly specified,<br>
> - its arguments and the global variable as well if Intr*Mem (other than<br>
> IntrNoMem) specified.<br>
> <br>
> Please tell me if I'm correct or not!<br>
> <br>
> Thanks again,<br>
> <br>
> <br>
> <br>
> On Wed, Jul 24, 2019, 17:27 Doerfert, Johannes <<a href="mailto:jdoerfert@anl.gov" target="_blank">jdoerfert@anl.gov</a>> wrote:<br>
> <br>
> > Hi Son Tuan Vu,<br>
> ><br>
> > if not restricted by *writeonly*, *readonly*, or *readnone* (basically), a<br>
> > call can access any object for which the<br>
> > callee could potentially know the address. That means, if the address of<br>
> > an object cannot be known to the callee,<br>
> > it cannot access that object. An example is given below. Thus, a dead<br>
> > store can be eliminated if the memory cannot<br>
> > be read by any subsequent operation. If you think there is a bug, could<br>
> > you provide a reproducer?<br>
> ><br>
> > Example:<br>
> ><br>
> > void unknown();<br>
> > void foo() {<br>
> >    int *A = malloc(100 * sizeof(A[0]));<br>
> >    int B[100];<br>
> >   for (int i = 0; i < 100; i++)<br>
> >     A[i] = B[i] = i;<br>
> ><br>
> >   // The addresses/objects A and B are not known to the unknown function<br>
> > and the stores above can be removed.<br>
> >   unknown();<br>
> ><br>
> >   free(A);<br>
> > }<br>
> ><br>
> > I hope this helps,<br>
> >   Johannes<br>
> ><br>
> ><br>
> > ________________________________________<br>
> > From: llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>> on behalf of Son Tuan VU<br>
> > via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
> > Sent: Wednesday, July 24, 2019 08:20<br>
> > To: llvm-devmemory<br>
> > Subject: [llvm-dev] Intrinsics InstrReadMem memory properties<br>
> ><br>
> > Hello,<br>
> ><br>
> > According to include/llvm/IR/Intrinsics.td, InstrReadMem property<br>
> > indicates that the intrinsic only reads from and does not write to memory.<br>
> ><br>
> > Does this mean that it can read anywhere in the memory? Because we already<br>
> > have 'InstrArgMemOnly' for intrinsics which only access memory that its<br>
> > argument(s) point(s) to.<br>
> ><br>
> > If 'InstrReadMem' really means read from anywhere in the memory, this<br>
> > should imply that,  if there's an intrinsic having this property *after* a<br>
> > dead store, the latter should not be eliminated by optimizations?<br>
> ><br>
> > This is not the current behavior of LLVM though, so it seems that my<br>
> > guesses are wrong... But at least, can someone show me the mistake here?<br>
> ><br>
> > Thanks for your time,<br>
> ><br>
> > Son Tuan Vu<br>
> ><br>
<br>
-- <br>
<br>
Johannes Doerfert<br>
Researcher<br>
<br>
Argonne National Laboratory<br>
Lemont, IL 60439, USA<br>
<br>
<a href="mailto:jdoerfert@anl.gov" target="_blank">jdoerfert@anl.gov</a><br>
</blockquote></div>