This RFC is to get the opinion of and promote awareness for a ValueTracking feature I am working on: [ValueTracking] Allow tracking values through Integral AddrSpaceCasts for improved alignments by jrbyrnes · Pull Request #70483 · llvm/llvm-project · GitHub .
The feature will enable tracking values through integral AddrSpaceCasts, which allows for improved reasoning about alignments. Since the semantics of AddrSpaceCasts are target specific, I thought this was the proper channel for this discussion.
The main motivation is, as mentioned, to allow for improved reasoning about alignments.
As we can see in this short example Example 1 , InferAlignment Pass is able to reason about the alignment of the load. The global array it is loading from is 16 byte aligned, and we know the element that we are loading has an index that is a multiple of 16 due to the shl. Therefore, the load is 16 byte aligned and the compiler is able to determine such (as seen by the change in alignment).
However, if we insert an AddrSpaceCast, then the compiler is no longer able to determine the alignment Example 2 . The issue is that ValueTracking doesn’t support AddrSpaceCasts.
In the example, we are casting between the address spaces 256 and 0 (which are integral for x86). As we can see in X86ISelLowering.cpp::LowerADDRSPACECAST, AddrSpaceCasts between these two address spaces is semantically equivalent to a sign extend. In order to reason about the alignment, the low bits of the address must be preserved through the AddrSpaceCasts. That is the case for casts between these two address spaces.
Moreover, after looking through all the backends, I can confirm that every target that has DataLayout defined integral address spaces has integral AddrSpaceCast semantics which preserve the low bits from the original pointer. There are some instances where AddrSpaceCasts involve truncating the original pointer, however, the non truncated bits are left unmodified which is the key to this analysis. There are a handful of targets that do not have DataLayout defined address spaces, but do have addrspace handling and test coverage. The majority of these targets have defined isNoopAddrSpaceCast to be basically universally true. However, I am unable to fully conclude about integral addrspacecast semantics for the following targets: DirectX, XCore and SPIRV.
Nonetheless, I am proposing to enable tracking values through integral AddrSpaceCasts. This modifies the semantics of integral AddrSpaceCasts such that they must now preserve the non-truncated bits of the original pointer. Targets are still able to express different AddrSpaceCasts semantics through non-integral addressspaces.
I wonder if there are any conerns with this, or if anyone happens to know if DirectX, XCore and SPIRV currently uphold this behavior.