Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -2235,6 +2235,14 @@ class LLVM_ABI TargetLoweringBase {
return false;
}

/// Whether AtomicExpandPass should automatically insert a seq_cst trailing
/// fence without reducing the ordering for this atomic store. Defaults to
/// false.
virtual bool
shouldInsertTrailingSeqCstFenceForAtomicStore(const Instruction *I) const {
return false;
}

// The memory ordering that AtomicExpandPass should assign to a atomic
// instruction that it has lowered by adding fences. This can be used
// to "fold" one of the fences into the atomic instruction.
Expand All @@ -2243,13 +2251,6 @@ class LLVM_ABI TargetLoweringBase {
return AtomicOrdering::Monotonic;
}

/// Whether AtomicExpandPass should automatically insert a trailing fence
/// without reducing the ordering for this atomic. Defaults to false.
virtual bool
shouldInsertTrailingFenceForAtomicStore(const Instruction *I) const {
return false;
}

/// Perform a load-linked operation on Addr, returning a "Value *" with the
/// corresponding pointee type. This may entail some non-trivial operations to
/// truncate or reconstruct types that will be illegal in the backend. See
Expand Down
22 changes: 7 additions & 15 deletions llvm/lib/CodeGen/AtomicExpandPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,21 +345,13 @@ bool AtomicExpandImpl::processAtomicInstr(Instruction *I) {
if (FenceOrdering != AtomicOrdering::Monotonic) {
MadeChange |= bracketInstWithFences(I, FenceOrdering);
}
} else if (I->hasAtomicStore() &&
TLI->shouldInsertTrailingFenceForAtomicStore(I)) {
auto FenceOrdering = AtomicOrdering::Monotonic;
if (SI)
FenceOrdering = SI->getOrdering();
else if (RMWI)
FenceOrdering = RMWI->getOrdering();
else if (CASI && TLI->shouldExpandAtomicCmpXchgInIR(CASI) !=
TargetLoweringBase::AtomicExpansionKind::LLSC)
// LLSC is handled in expandAtomicCmpXchg().
FenceOrdering = CASI->getSuccessOrdering();

} else if (TLI->shouldInsertTrailingSeqCstFenceForAtomicStore(I) &&
!(CASI && TLI->shouldExpandAtomicCmpXchgInIR(CASI) ==
TargetLoweringBase::AtomicExpansionKind::LLSC)) {
// CmpXchg LLSC is handled in expandAtomicCmpXchg().
IRBuilder Builder(I);
if (auto TrailingFence =
TLI->emitTrailingFence(Builder, I, FenceOrdering)) {
if (auto TrailingFence = TLI->emitTrailingFence(
Builder, I, AtomicOrdering::SequentiallyConsistent)) {
TrailingFence->moveAfter(I);
MadeChange = true;
}
Expand Down Expand Up @@ -1512,7 +1504,7 @@ bool AtomicExpandImpl::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
// necessary.
Builder.SetInsertPoint(SuccessBB);
if (ShouldInsertFencesForAtomic ||
TLI->shouldInsertTrailingFenceForAtomicStore(CI))
TLI->shouldInsertTrailingSeqCstFenceForAtomicStore(CI))
TLI->emitTrailingFence(Builder, CI, SuccessOrder);
Builder.CreateBr(ExitBB);

Expand Down
31 changes: 18 additions & 13 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29446,7 +29446,7 @@ bool AArch64TargetLowering::shouldInsertFencesForAtomic(
return false;
}

bool AArch64TargetLowering::shouldInsertTrailingFenceForAtomicStore(
bool AArch64TargetLowering::shouldInsertTrailingSeqCstFenceForAtomicStore(
const Instruction *I) const {
// Store-Release instructions only provide seq_cst guarantees when paired with
// Load-Acquire instructions. MSVC CRT does not use these instructions to
Expand All @@ -29455,19 +29455,24 @@ bool AArch64TargetLowering::shouldInsertTrailingFenceForAtomicStore(
if (!Subtarget->getTargetTriple().isWindowsMSVCEnvironment())
return false;

switch (I->getOpcode()) {
default:
if (auto *SI = dyn_cast<StoreInst>(I))
return SI->getOrdering() == AtomicOrdering::SequentiallyConsistent;

auto *CAS = dyn_cast<AtomicCmpXchgInst>(I);
auto *RMW = dyn_cast<AtomicRMWInst>(I);
// Not a store.
if (!CAS && !RMW)
return false;
case Instruction::AtomicCmpXchg:
return cast<AtomicCmpXchgInst>(I)->getSuccessOrdering() ==
AtomicOrdering::SequentiallyConsistent;
case Instruction::AtomicRMW:
return cast<AtomicRMWInst>(I)->getOrdering() ==
AtomicOrdering::SequentiallyConsistent;
case Instruction::Store:
return cast<StoreInst>(I)->getOrdering() ==
AtomicOrdering::SequentiallyConsistent;
}

// Fence only needed for seq_cst.
if (CAS &&
CAS->getSuccessOrdering() != AtomicOrdering::SequentiallyConsistent)
return false;
if (RMW && RMW->getOrdering() != AtomicOrdering::SequentiallyConsistent)
return false;

// We do not need a fence if we have LSE atomics.
return !Subtarget->hasLSE();
}

// Loads and stores less than 128-bits are already atomic; ones above that
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,8 @@ class AArch64TargetLowering : public TargetLowering {
bool isOpSuitableForLSE128(const Instruction *I) const;
bool isOpSuitableForRCPC3(const Instruction *I) const;
bool shouldInsertFencesForAtomic(const Instruction *I) const override;
bool
shouldInsertTrailingFenceForAtomicStore(const Instruction *I) const override;
bool shouldInsertTrailingSeqCstFenceForAtomicStore(
const Instruction *I) const override;

TargetLoweringBase::AtomicExpansionKind
shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
Expand Down
Loading