[llvm] 977f4d6 - [AMDGPU] Employ MemorySSA when rewriting out arguments (NFCI) (#207922)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 10 00:55:37 PDT 2026
Author: Antonio Frighetto
Date: 2026-07-10T09:55:33+02:00
New Revision: 977f4d603ae13c751357352f1256e389a4725e9f
URL: https://github.com/llvm/llvm-project/commit/977f4d603ae13c751357352f1256e389a4725e9f
DIFF: https://github.com/llvm/llvm-project/commit/977f4d603ae13c751357352f1256e389a4725e9f.diff
LOG: [AMDGPU] Employ MemorySSA when rewriting out arguments (NFCI) (#207922)
While transitioning away from MemoryDependenceAnalysis, replace MDA
`getPointerDependencyFrom` query with a reverse traversal of the memory
accesses of the return basic block (MemoryDefs and MemoryUses), looking
for the must-aliasing store to the out argument. The existing behaviour
is meant to be preserved.
Added:
Modified:
llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
index c0802de2763dc..7db637eaa0745 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
@@ -44,7 +44,8 @@
#include "AMDGPU.h"
#include "Utils/AMDGPUBaseInfo.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/MemoryDependenceAnalysis.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
@@ -81,7 +82,9 @@ namespace {
class AMDGPURewriteOutArguments : public FunctionPass {
private:
const DataLayout *DL = nullptr;
- MemoryDependenceResults *MDA = nullptr;
+ MemorySSA *MSSA = nullptr;
+ MemorySSAUpdater *MSSAU = nullptr;
+ AAResults *AA = nullptr;
Type *getStoredType(Value &Arg) const;
Type *getOutArgumentType(Argument &Arg) const;
@@ -92,7 +95,8 @@ class AMDGPURewriteOutArguments : public FunctionPass {
AMDGPURewriteOutArguments() : FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<MemoryDependenceWrapperPass>();
+ AU.addRequired<MemorySSAWrapperPass>();
+ AU.addRequired<AAResultsWrapperPass>();
FunctionPass::getAnalysisUsage(AU);
}
@@ -104,7 +108,7 @@ class AMDGPURewriteOutArguments : public FunctionPass {
INITIALIZE_PASS_BEGIN(AMDGPURewriteOutArguments, DEBUG_TYPE,
"AMDGPU Rewrite Out Arguments", false, false)
-INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(AMDGPURewriteOutArguments, DEBUG_TYPE,
"AMDGPU Rewrite Out Arguments", false, false)
@@ -170,6 +174,49 @@ bool AMDGPURewriteOutArguments::doInitialization(Module &M) {
return false;
}
+static StoreInst *findStoreForOutArgument(BasicBlock *BB, Argument *OutArg,
+ MemorySSA &MSSA,
+ BatchAAResults &BAA) {
+ MemoryLocation ArgLoc = MemoryLocation::getBeforeOrAfter(OutArg);
+ const auto *Accesses = MSSA.getBlockAccesses(BB);
+ if (!Accesses)
+ return nullptr;
+
+ for (const MemoryAccess &Access : reverse(*Accesses)) {
+ const auto *UseOrDef = dyn_cast<MemoryUseOrDef>(&Access);
+ if (!UseOrDef)
+ continue;
+
+ Instruction *I = UseOrDef->getMemoryInst();
+
+ // Return the must-alias store to the out argument.
+ if (auto *Store = dyn_cast<StoreInst>(I))
+ if (Store->getPointerOperand() == OutArg)
+ return Store;
+
+ if (auto *FI = dyn_cast<FenceInst>(I))
+ if (FI->getOrdering() == AtomicOrdering::Release)
+ continue;
+
+ if (auto *LI = dyn_cast<LoadInst>(I)) {
+ if (LI->isAtomic()) {
+ // May-alias reads with monotonic ordering are ignored.
+ if (isStrongerThan(LI->getOrdering(), AtomicOrdering::Monotonic))
+ return nullptr;
+ continue;
+ }
+ }
+
+ // Any other memory access that writes the location prevents the
+ // rewrite.
+ // FIXME: should handle aliasing reads too.
+ if (isModSet(BAA.getModRefInfo(I, ArgLoc)))
+ return nullptr;
+ }
+
+ return nullptr;
+}
+
bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
@@ -179,8 +226,6 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
AMDGPU::isEntryFunctionCC(F.getCallingConv()))
return false;
- MDA = &getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
-
unsigned ReturnNumRegs = 0;
// Maps an out-argument number to its field index in the return struct.
// Fields are in processing order, which the retry loop below can reorder
@@ -222,6 +267,13 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
if (Returns.empty())
return false;
+ AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
+
+ BatchAAResults BatchAA(*AA);
+ MemorySSAUpdater MSSAUpdater(MSSA);
+ MSSAU = &MSSAUpdater;
+
bool Changing;
do {
@@ -254,17 +306,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
for (ReturnInst *RI : Returns) {
BasicBlock *BB = RI->getParent();
- MemDepResult Q = MDA->getPointerDependencyFrom(
- MemoryLocation::getBeforeOrAfter(OutArg), true, BB->end(), BB, RI);
- StoreInst *SI = nullptr;
- if (Q.isDef())
- SI = dyn_cast<StoreInst>(Q.getInst());
-
- // MDA stops at the first may-aliasing store, which need not be to this
- // argument; only fold a store whose pointer is exactly OutArg.
- if (SI && SI->getPointerOperand() != OutArg)
- SI = nullptr;
-
+ StoreInst *SI = findStoreForOutArgument(BB, OutArg, *MSSA, BatchAA);
if (SI) {
LLVM_DEBUG(dbgs() << "Found out argument store: " << *SI << '\n');
ReplaceableStores.emplace_back(RI, SI);
@@ -291,6 +333,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
}
ValVec.emplace_back(OutArg, ReplVal);
+ MSSAU->removeMemoryAccess(Store.second);
Store.second->eraseFromParent();
}
More information about the llvm-commits
mailing list