Hello,
Do we have a pass that propagate the noalias annotation down to the callee when:
- it is static
- it is always called with non aliasing pointers
?
Or maybe that is incorrect?
Hello,
Do we have a pass that propagate the noalias annotation down to the callee when:
Or maybe that is incorrect?
Hi, Alexandre,
We don't have anything currently which does this. Note that, without further analysis of the uses of the potentially-noalias pointers, you can do this only for arguments with distinct (and identified) underlying objects (i.e., you need something a bit stronger than just "non-aliasing pointers").
-Hal
Could you elaborate “Note that, without further analysis of the uses of the potentially-noalias pointers, you can do this only …”?
Why the uses, instead of the def, of pointer matter?
Thanks
Hongbin
Both matter. static int foo(int *a, int *b) { return a[0] + b[1]; } int bar(int *x) { return foo(x+1, x); } You can’t mark a and b as noalias here, even though NoAlias(x+1, x) == true. This is why I was saying that, unless the pointers come from distinct, identified underlying objects, you need to look at the uses of the pointers too. -Hal P.S. As discussed in D4609, we probably want to try adding CGSCC AA wrappers, to look back through function arguments, instead of using attribute propagation.
Do you mean a and b are noalias if:
static int foo(int *a, int *b) {
return a[0] + b[0];
}
int bar(int *x) {
return foo(x+1, x);
}
?
To me, because “AA.alias((x+1, MemoryLocation::UnknownSize), (x, MemoryLocation::UnknownSize)) != NoAlias”, so a and b are not noalias.
Maybe my version is too conservative.
Thanks
Hongbin
Could you elaborate "Note that, without further analysis of the uses of
the potentially-noalias pointers, you can do this only ..."?
Why the uses, instead of the def, of pointer matter?Both matter.
static int foo(int *a, int *b) {
return a[0] + b[1];
}int bar(int *x) {
return foo(x+1, x);
}You can't mark a and b as noalias here, even though NoAlias(x+1, x) ==
true. This is why I was saying that, unless the pointers come from
distinct, identified underlying objects, you need to look at the uses of
the pointers too.-Hal
P.S. As discussed in D4609, we probably want to try adding CGSCC AA
wrappers, to look back through function arguments, instead of using
attribute propagation.
Also, is CFLSteensAA able to help D4609?
Thanks
Hongbin
Remember that MemoryLocation::UnknownSize is unknown, but positive. So you need to check both “AA.alias((x+1, MemoryLocation::UnknownSize), (x, MemoryLocation::UnknownSize)) == NoAlias” and “AA.alias((x, MemoryLocation::UnknownSize), (x+1, MemoryLocation::UnknownSize)) == NoAlias” to partition by underlying object. One of these should be false. -Hal
Do you mean a and b are noalias if:
static int foo(int *a, int *b) {
return a[0] + b[0];
}int bar(int *x) {
return foo(x+1, x);
}?
To me, because "AA.alias((x+1, MemoryLocation::UnknownSize),
(x, MemoryLocation::UnknownSize)) != NoAlias", so a and b are not noalias.Remember that MemoryLocation::UnknownSize is unknown, but positive. So you
need to check both "AA.alias((x+1, MemoryLocation::UnknownSize), (x,
MemoryLocation::UnknownSize)) == NoAlias" and "AA.alias((x,
MemoryLocation::UnknownSize), (x+1, MemoryLocation::UnknownSize)) ==
NoAlias" to partition by underlying object. One of these should be false.
Thanks a lot for the explanation.
Do you mean AA.alias(X,Y) may not always return the same result as
AA.alias(Y,X)? (otherwise why we need to do both of them)
[1] Didn't mention this detail.
Thanks again
Hongbin
[1] LLVM Alias Analysis Infrastructure — LLVM 18.0.0git documentation
Yes, but I should clarify (what I typed gives the wrong implication). If both values have an unknown size, then it should be symmetric. If only one is, however, there can be a difference between: | x | | y … → | and: | x … → | | y | and this is because the unknown size is unknown, but positive. -Hal