aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp50
1 files changed, 23 insertions, 27 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
index 02f5ce2d18ff..0a163f8dc7f6 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
@@ -151,23 +151,18 @@ PreservedAnalyses AMDGPUAtomicOptimizerPass::run(Function &F,
}
bool AMDGPUAtomicOptimizerImpl::run() {
-
// Scan option None disables the Pass
- if (ScanImpl == ScanOptions::None) {
+ if (ScanImpl == ScanOptions::None)
return false;
- }
visit(F);
+ if (ToReplace.empty())
+ return false;
- const bool Changed = !ToReplace.empty();
-
- for (ReplacementInfo &Info : ToReplace) {
- optimizeAtomic(*Info.I, Info.Op, Info.ValIdx, Info.ValDivergent);
- }
-
+ for (auto &[I, Op, ValIdx, ValDivergent] : ToReplace)
+ optimizeAtomic(*I, Op, ValIdx, ValDivergent);
ToReplace.clear();
-
- return Changed;
+ return true;
}
static bool isLegalCrossLaneType(Type *Ty) {
@@ -247,9 +242,7 @@ void AMDGPUAtomicOptimizerImpl::visitAtomicRMWInst(AtomicRMWInst &I) {
// If we get here, we can optimize the atomic using a single wavefront-wide
// atomic operation to do the calculation for the entire wavefront, so
// remember the instruction so we can come back to it.
- const ReplacementInfo Info = {&I, Op, ValIdx, ValDivergent};
-
- ToReplace.push_back(Info);
+ ToReplace.push_back({&I, Op, ValIdx, ValDivergent});
}
void AMDGPUAtomicOptimizerImpl::visitIntrinsicInst(IntrinsicInst &I) {
@@ -333,17 +326,14 @@ void AMDGPUAtomicOptimizerImpl::visitIntrinsicInst(IntrinsicInst &I) {
// If any of the other arguments to the intrinsic are divergent, we can't
// optimize the operation.
for (unsigned Idx = 1; Idx < I.getNumOperands(); Idx++) {
- if (UA.isDivergentUse(I.getOperandUse(Idx))) {
+ if (UA.isDivergentUse(I.getOperandUse(Idx)))
return;
- }
}
// If we get here, we can optimize the atomic using a single wavefront-wide
// atomic operation to do the calculation for the entire wavefront, so
// remember the instruction so we can come back to it.
- const ReplacementInfo Info = {&I, Op, ValIdx, ValDivergent};
-
- ToReplace.push_back(Info);
+ ToReplace.push_back({&I, Op, ValIdx, ValDivergent});
}
// Use the builder to create the non-atomic counterpart of the specified
@@ -676,7 +666,7 @@ void AMDGPUAtomicOptimizerImpl::optimizeAtomic(Instruction &I,
// Record I's original position as the entry block.
PixelEntryBB = I.getParent();
- Value *const Cond = B.CreateIntrinsic(Intrinsic::amdgcn_ps_live, {}, {});
+ Value *const Cond = B.CreateIntrinsic(Intrinsic::amdgcn_ps_live, {});
Instruction *const NonHelperTerminator =
SplitBlockAndInsertIfThen(Cond, &I, false, nullptr, &DTU, nullptr);
@@ -708,15 +698,14 @@ void AMDGPUAtomicOptimizerImpl::optimizeAtomic(Instruction &I,
// using the mbcnt intrinsic.
Value *Mbcnt;
if (ST.isWave32()) {
- Mbcnt = B.CreateIntrinsic(Intrinsic::amdgcn_mbcnt_lo, {},
- {Ballot, B.getInt32(0)});
+ Mbcnt =
+ B.CreateIntrinsic(Intrinsic::amdgcn_mbcnt_lo, {Ballot, B.getInt32(0)});
} else {
Value *const ExtractLo = B.CreateTrunc(Ballot, Int32Ty);
Value *const ExtractHi = B.CreateTrunc(B.CreateLShr(Ballot, 32), Int32Ty);
- Mbcnt = B.CreateIntrinsic(Intrinsic::amdgcn_mbcnt_lo, {},
+ Mbcnt = B.CreateIntrinsic(Intrinsic::amdgcn_mbcnt_lo,
{ExtractLo, B.getInt32(0)});
- Mbcnt =
- B.CreateIntrinsic(Intrinsic::amdgcn_mbcnt_hi, {}, {ExtractHi, Mbcnt});
+ Mbcnt = B.CreateIntrinsic(Intrinsic::amdgcn_mbcnt_hi, {ExtractHi, Mbcnt});
}
Function *F = I.getFunction();
@@ -898,8 +887,15 @@ void AMDGPUAtomicOptimizerImpl::optimizeAtomic(Instruction &I,
// We need to broadcast the value who was the lowest active lane (the first
// lane) to all other lanes in the wavefront.
- Value *BroadcastI = nullptr;
- BroadcastI = B.CreateIntrinsic(Ty, Intrinsic::amdgcn_readfirstlane, PHI);
+
+ Value *ReadlaneVal = PHI;
+ if (TyBitWidth < 32)
+ ReadlaneVal = B.CreateZExt(PHI, B.getInt32Ty());
+
+ Value *BroadcastI = B.CreateIntrinsic(
+ ReadlaneVal->getType(), Intrinsic::amdgcn_readfirstlane, ReadlaneVal);
+ if (TyBitWidth < 32)
+ BroadcastI = B.CreateTrunc(BroadcastI, Ty);
// Now that we have the result of our single atomic operation, we need to
// get our individual lane's slice into the result. We use the lane offset