-
Notifications
You must be signed in to change notification settings - Fork 872
[Codegen] Set alignment attributes over vectorized memory accesses #20267
Description
Hardware like amdgpu generally prefers wide memory accesses (e.g., dwordx4 or b128) but these only get selected by the llvm backend when the alignment is known and sufficiently large. LLVM is able to infer the alignment in some cases, but it's not guaranteed to always do the best job possible.
For example, consider this pseudo-IR:
%lds = memref.alloc() : memref<2x10xf16, #gpu.address_space<workgroup>>>
%x = vector.load %lds[%a, %b] : memref<2x10xf16, #gpu.address_space<workgroup>>>, vector<8xf16>Ideally, we would like to assume 16-byte alignment (8 * 2 bytes), but this requires knowing:
- That the alignment of the allocation itself is at least 16
- That memory access pattern guarantees
%bto be a multiple of 8
Just because the accessed type is vector<8xf16> is not enough to infer that the alignment is 16.
We can already accomplish 1. with the alignment attribute supported by memref.alloc op, but we have no way of expressing known alignment over memory accesses across memref/vector load/store ops. Similar with inbounds attributes, the most general representation would be per-dimension, but allowing it over 1-d vector types makes things simpler.
I think the following implementation should work:
- Add
alignmentattribute tomemref/vectormemory access ops. To keep it simple, require this to be a single byte value (instead of number of elements) wrt the first element accessed only. - Propagate these
alignmentattributes when converting frommemref/vectortollvm/spirv. - Flatten the memory accesses in IREE, so that we don't have to worry about any n-d cases.
- Set known alignment values in IREE codegen, e.g., for shared memory.