aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp
diff options
context:
space:
mode:
authorSirish Pande <sirpande@amd.com>2025-04-28 14:02:18 -0500
committerGitHub <noreply@github.com>2025-04-28 14:02:18 -0500
commitabec9ff47da4fd8b614d0338203b2e3663c36aaf (patch)
tree28d0533d114d343b5dabd8568b43df679706309f /llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp
parent043b04acff53f3c3b2dd0d6eeb8c2127a229ac72 (diff)
downloadllvm-abec9ff47da4fd8b614d0338203b2e3663c36aaf.zip
llvm-abec9ff47da4fd8b614d0338203b2e3663c36aaf.tar.gz
llvm-abec9ff47da4fd8b614d0338203b2e3663c36aaf.tar.bz2
[AMDGPU] Correctly merge noalias scopes during lowering of LDS data. (#131664)
Currently, if there is already noalias metadata present on loads and stores, lower module lds pass is generating a more conservative aliasing set. This results in inhibiting scheduling intrinsics that would have otherwise generated a better pipelined instruction. The fix is not to always intersect already existing noalias metadata with noalias created for lowering of LDS. But to intersect only if noalias scopes are from the same domain, otherwise concatenate exising noalias sets with LDS noalias. There a few patches that have come for scopedAA in the past. Following three should be enough background information. https://reviews.llvm.org/D91576 https://reviews.llvm.org/D108315 https://reviews.llvm.org/D110049 Essentially, after a pass that might change aliasing info, one should check if that pass results in change number of MayAlias or ModRef using the following: `opt -S -aa-pipeline=basic-aa,scoped-noalias-aa -passes=aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output`
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp32
1 files changed, 31 insertions, 1 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp
index f9f2d43..88acfe1 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp
@@ -186,6 +186,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
@@ -1441,6 +1442,8 @@ private:
if (!MaxDepth || (A == 1 && !AliasScope))
return;
+ ScopedNoAliasAAResult ScopedNoAlias;
+
for (User *U : Ptr->users()) {
if (auto *I = dyn_cast<Instruction>(U)) {
if (AliasScope && I->mayReadOrWriteMemory()) {
@@ -1450,7 +1453,34 @@ private:
I->setMetadata(LLVMContext::MD_alias_scope, AS);
MDNode *NA = I->getMetadata(LLVMContext::MD_noalias);
- NA = (NA ? MDNode::intersect(NA, NoAlias) : NoAlias);
+
+ // Scoped aliases can originate from two different domains.
+ // First domain would be from LDS domain (created by this pass).
+ // All entries (LDS vars) into LDS struct will have same domain.
+
+ // Second domain could be existing scoped aliases that are the
+ // results of noalias params and subsequent optimizations that
+ // may alter thesse sets.
+
+ // We need to be careful how we create new alias sets, and
+ // have right scopes and domains for loads/stores of these new
+ // LDS variables. We intersect NoAlias set if alias sets belong
+ // to the same domain. This is the case if we have memcpy using
+ // LDS variables. Both src and dst of memcpy would belong to
+ // LDS struct, they donot alias.
+ // On the other hand, if one of the domains is LDS and other is
+ // existing domain prior to LDS, we need to have a union of all
+ // these aliases set to preserve existing aliasing information.
+
+ SmallPtrSet<const MDNode *, 16> ExistingDomains, LDSDomains;
+ ScopedNoAlias.collectScopedDomains(NA, ExistingDomains);
+ ScopedNoAlias.collectScopedDomains(NoAlias, LDSDomains);
+ auto Intersection = set_intersection(ExistingDomains, LDSDomains);
+ if (Intersection.empty()) {
+ NA = NA ? MDNode::concatenate(NA, NoAlias) : NoAlias;
+ } else {
+ NA = NA ? MDNode::intersect(NA, NoAlias) : NoAlias;
+ }
I->setMetadata(LLVMContext::MD_noalias, NA);
}
}