Alias analysis is unable to disambiguate accesses to the structure
fields without it unlike distinct variables. As a result we cannot
combine ds_read and ds_write operations in a case of any store in
between which always considered clobbering.
Details
Diff Detail
Event Timeline
What happens if the original accesses had alias metadata? Can you add a case where it already has alias.scope, plus tbaa?
llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp | ||
---|---|---|
294 | Is a different domain needed for each variable/field, or can just one domain be created? |
- Switched to single domain.
- Skip setting and merging scope metadata if exists.
- Added test with pre-existing alias scope and tbaa metadata.
Actually concatenating metadata is wrong. For alias.scope correct correct merging method is MDNode::getMostGenericAliasScope() and for noalias intersect. Both methods however create more pessimistic metadata than before the merge, so if we have any of scoped alias metadata it seems better to just leave it alone.
TBAA is not affected at all. Tests added.
llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp | ||
---|---|---|
294 | A single domain works, thanks! |
I have realized scope.alias metadata is not well formed. It shall be a list of scopes, not a scope itself even if the list consists of a single scope. Even though it works it is incorrect.
Then if that is a list normal merging shall work properly.
In addition I think that concatentate is right for this specific case, we are not creating new aliasing by the transformation.
Change looks good but this comment is strange:
// Create alias.scope and their lists. Each field in the new structure // does not alias with all other fields.
That is true of any structure. Each s/field/pointer in the new?
It seems a shame that moving variables into a struct thwarts AA at present.
That is all true, but unfortunately... it is true. I have tried to create a struct upfront and clang didn't produce this sort of metadata. And no AA was able to disambiguate pointers to fields. So we will be in a better position with this change than anybody who just have created a structure in the source. I do agree, this is a shame. Maybe if FE would create this sort of AA metadata that is a solution, maybe yet another AA pass is. Right now structs are a problem.
One of the benefits of combining LDS into a single aggregate was to combine loads and stores because we know the layout of LDS. And that turns to be not working. Well, I hope this will help at least that problem. Sure anough if there is an AA pass to disambiguate struct fields this patch will become unnecessary, but I am afraid in the existence of offsetof operator that might not happen. I can see a very easy way to exploit it. In fact any assumed layout combined with an ability to take and cast pointers is.
I.e. to the defence of the comment:
struct { int a; int b; } object;
memset(&object.a, 0, sizeof(object));
This case only references the first field and yet clobbers the entire struct. So the "pointer" is not a right word here. Pointer and an access size is, which is... a field in our case.
Is a different domain needed for each variable/field, or can just one domain be created?