[llvm] [RFC] IR: Define noalias.addrspace metadata (PR #102461)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 11 14:28:19 PDT 2024
================
@@ -5180,6 +5206,13 @@ void Verifier::visitInstruction(Instruction &I) {
visitRangeMetadata(I, Range, I.getType());
}
+ if (MDNode *Range = I.getMetadata(LLVMContext::MD_noalias_addrspace)) {
+ Check(isa<LoadInst>(I) || isa<StoreInst>(I) || isa<AtomicRMWInst>(I) ||
+ isa<AtomicCmpXchgInst>(I) || isa<CallInst>(I),
+ "noalias.addrspace are only for memory operations!", &I);
+ visitNoaliasAddrspaceMetadata(I, Range, I.getType());
----------------
jurahul wrote:
Just some thought:
The spec language is: *The ``noalias.addrspace`` metadata is used to identify memory
operations which cannot access a range of address spaces*.
In general, given a pointer in AS 'n', we can have set of address spaces that potentially alias with 'n', and then any memory access using AS `n` pointer is a potential access to any of the aliasing address spaces. And then this metadata is a guarantee that some of those aliasing address spaces can be dropped from the set, right? If `Aliases(P)` is all address spaces that can potentially alias with P (including P itself), then a `LoadInst` for example would be invalid if Aliases(P) - `noalias.addrspace` is an empty set, i.e., no address space is left to define the access?
Assuming address spaces are organized as a tree (or a DAG), where each node is an address space, and its children/directed neighbors are all address spaces that overlap with the parent, Aliases(P) is all address spaces k such that k is on a path from some root to some leaf that contains node (p). So, Aliases(p) capture all sub-address spaces within (p) as well as all address spaces that p is a sub-address space of. Note that we can have another definition where Aliases(P) is only its sub-address spaces looking down in this tree but not up (Descendents).
So, whenever you access a pointer in AS p, you can potentially access any of the address spaces in Aliases(P). And then noalias.addrspace drops some address spaces from that. If we have native LoadInst whose pointer AS is P, and then noalias.addrespace, the set of legal address spaces its allowed to access is:
Aliases(P) - noalias.addrspace
If this set happens to be empty, then I'd think the IR is invalid (we have not left any address space for the load to do its memory access. Or maybe undefined)?
And if Alias(P) includes parents as well as descendent address spaces, then
load with pointer p and noalias.addresspace = p can be well defined, since Alias(P) - {p) will include say a parent address space, and the load is "required" to upcast the pointer from AS p to that parent address space (say generic) to do the access.
If OTOH we define the set of legal address spaces to be:
Descendents(P) - (union(Descendents(noalias.addrspace))
which I think is the more logical meaning, then load with pointer p and noalias.addresspace = p will always be undefined as the set of legal address spaces left will always be null.
Essentially, I am defining legality by first defining the set of legal address spaces that a load can access, and then making a load/store legal only if that set is non-empty. Whether we use AscendentsAndDescendepts(p) or just Descendents(p) I guess depends on the intended semantics.
https://github.com/llvm/llvm-project/pull/102461
More information about the llvm-commits
mailing list