diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp | 50 |
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 |
