//===- InstCombineAtomicRMW.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the visit functions for atomic rmw instructions. // //===----------------------------------------------------------------------===// #include "InstCombineInternal.h" #include "llvm/IR/Instructions.h" using namespace llvm; Instruction *InstCombiner::visitAtomicRMWInst(AtomicRMWInst &RMWI) { switch (RMWI.getOperation()) { default: break; case AtomicRMWInst::Add: case AtomicRMWInst::Sub: case AtomicRMWInst::Or: // Replace atomicrmw addr, 0 => load atomic addr. // Volatile RMWs perform a load and a store, we cannot replace // this by just a load. if (RMWI.isVolatile()) break; auto *CI = dyn_cast(RMWI.getValOperand()); if (!CI || !CI->isZero()) break; // Check if the required ordering is compatible with an // atomic load. AtomicOrdering Ordering = RMWI.getOrdering(); assert(Ordering != AtomicOrdering::NotAtomic && Ordering != AtomicOrdering::Unordered && "AtomicRMWs don't make sense with Unordered or NotAtomic"); if (Ordering != AtomicOrdering::Acquire && Ordering != AtomicOrdering::Monotonic) break; LoadInst *Load = new LoadInst(RMWI.getType(), RMWI.getPointerOperand()); Load->setAtomic(Ordering, RMWI.getSyncScopeID()); return Load; } return nullptr; }