From e3b557809604d036af6e00c60f012c2025b59a5e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 11 Feb 2023 13:38:04 +0100 Subject: Vendor import of llvm-project main llvmorg-16-init-18548-gb0daacf58f41, the last commit before the upstream release/17.x branch was created. --- llvm/lib/Transforms/Utils/LowerAtomic.cpp | 57 ++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 20 deletions(-) (limited to 'llvm/lib/Transforms/Utils/LowerAtomic.cpp') diff --git a/llvm/lib/Transforms/Utils/LowerAtomic.cpp b/llvm/lib/Transforms/Utils/LowerAtomic.cpp index 2247b8107739..b6f40de0daa6 100644 --- a/llvm/lib/Transforms/Utils/LowerAtomic.cpp +++ b/llvm/lib/Transforms/Utils/LowerAtomic.cpp @@ -41,43 +41,60 @@ bool llvm::lowerAtomicCmpXchgInst(AtomicCmpXchgInst *CXI) { Value *llvm::buildAtomicRMWValue(AtomicRMWInst::BinOp Op, IRBuilderBase &Builder, Value *Loaded, - Value *Inc) { + Value *Val) { Value *NewVal; switch (Op) { case AtomicRMWInst::Xchg: - return Inc; + return Val; case AtomicRMWInst::Add: - return Builder.CreateAdd(Loaded, Inc, "new"); + return Builder.CreateAdd(Loaded, Val, "new"); case AtomicRMWInst::Sub: - return Builder.CreateSub(Loaded, Inc, "new"); + return Builder.CreateSub(Loaded, Val, "new"); case AtomicRMWInst::And: - return Builder.CreateAnd(Loaded, Inc, "new"); + return Builder.CreateAnd(Loaded, Val, "new"); case AtomicRMWInst::Nand: - return Builder.CreateNot(Builder.CreateAnd(Loaded, Inc), "new"); + return Builder.CreateNot(Builder.CreateAnd(Loaded, Val), "new"); case AtomicRMWInst::Or: - return Builder.CreateOr(Loaded, Inc, "new"); + return Builder.CreateOr(Loaded, Val, "new"); case AtomicRMWInst::Xor: - return Builder.CreateXor(Loaded, Inc, "new"); + return Builder.CreateXor(Loaded, Val, "new"); case AtomicRMWInst::Max: - NewVal = Builder.CreateICmpSGT(Loaded, Inc); - return Builder.CreateSelect(NewVal, Loaded, Inc, "new"); + NewVal = Builder.CreateICmpSGT(Loaded, Val); + return Builder.CreateSelect(NewVal, Loaded, Val, "new"); case AtomicRMWInst::Min: - NewVal = Builder.CreateICmpSLE(Loaded, Inc); - return Builder.CreateSelect(NewVal, Loaded, Inc, "new"); + NewVal = Builder.CreateICmpSLE(Loaded, Val); + return Builder.CreateSelect(NewVal, Loaded, Val, "new"); case AtomicRMWInst::UMax: - NewVal = Builder.CreateICmpUGT(Loaded, Inc); - return Builder.CreateSelect(NewVal, Loaded, Inc, "new"); + NewVal = Builder.CreateICmpUGT(Loaded, Val); + return Builder.CreateSelect(NewVal, Loaded, Val, "new"); case AtomicRMWInst::UMin: - NewVal = Builder.CreateICmpULE(Loaded, Inc); - return Builder.CreateSelect(NewVal, Loaded, Inc, "new"); + NewVal = Builder.CreateICmpULE(Loaded, Val); + return Builder.CreateSelect(NewVal, Loaded, Val, "new"); case AtomicRMWInst::FAdd: - return Builder.CreateFAdd(Loaded, Inc, "new"); + return Builder.CreateFAdd(Loaded, Val, "new"); case AtomicRMWInst::FSub: - return Builder.CreateFSub(Loaded, Inc, "new"); + return Builder.CreateFSub(Loaded, Val, "new"); case AtomicRMWInst::FMax: - return Builder.CreateMaxNum(Loaded, Inc); + return Builder.CreateMaxNum(Loaded, Val); case AtomicRMWInst::FMin: - return Builder.CreateMinNum(Loaded, Inc); + return Builder.CreateMinNum(Loaded, Val); + case AtomicRMWInst::UIncWrap: { + Constant *One = ConstantInt::get(Loaded->getType(), 1); + Value *Inc = Builder.CreateAdd(Loaded, One); + Value *Cmp = Builder.CreateICmpUGE(Loaded, Val); + Constant *Zero = ConstantInt::get(Loaded->getType(), 0); + return Builder.CreateSelect(Cmp, Zero, Inc, "new"); + } + case AtomicRMWInst::UDecWrap: { + Constant *Zero = ConstantInt::get(Loaded->getType(), 0); + Constant *One = ConstantInt::get(Loaded->getType(), 1); + + Value *Dec = Builder.CreateSub(Loaded, One); + Value *CmpEq0 = Builder.CreateICmpEQ(Loaded, Zero); + Value *CmpOldGtVal = Builder.CreateICmpUGT(Loaded, Val); + Value *Or = Builder.CreateOr(CmpEq0, CmpOldGtVal); + return Builder.CreateSelect(Or, Val, Dec, "new"); + } default: llvm_unreachable("Unknown atomic op"); } -- cgit v1.2.3