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