[RISCV] Add codegen support for atomic load/stores with RV32A
Fences are inserted according to table A.6 in the current draft of version 2.3
of the RISC-V Instruction Set Manual, which incorporates the memory model
changes and definitions contributed by the RISC-V Memory Consistency Model
task group.
Instruction selection failures will now occur for 8/16/32-bit atomicrmw and
cmpxchg operations when targeting RV32IA until lowering for these operations
is added in a follow-on patch.
Differential Revision: https://reviews.llvm.org/D47589
llvm-svn: 334591
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b98f057..dda26a7 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -137,8 +137,10 @@
setOperationAction(ISD::BlockAddress, XLenVT, Custom);
setOperationAction(ISD::ConstantPool, XLenVT, Custom);
- // Atomic operations aren't suported in the base RV32I ISA.
- setMaxAtomicSizeInBitsSupported(0);
+ if (Subtarget.hasStdExtA())
+ setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
+ else
+ setMaxAtomicSizeInBitsSupported(0);
setBooleanContents(ZeroOrOneBooleanContent);
@@ -1553,3 +1555,21 @@
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
}
+
+Instruction *RISCVTargetLowering::emitLeadingFence(IRBuilder<> &Builder,
+ Instruction *Inst,
+ AtomicOrdering Ord) const {
+ if (isa<LoadInst>(Inst) && Ord == AtomicOrdering::SequentiallyConsistent)
+ return Builder.CreateFence(Ord);
+ if (isa<StoreInst>(Inst) && isReleaseOrStronger(Ord))
+ return Builder.CreateFence(AtomicOrdering::Release);
+ return nullptr;
+}
+
+Instruction *RISCVTargetLowering::emitTrailingFence(IRBuilder<> &Builder,
+ Instruction *Inst,
+ AtomicOrdering Ord) const {
+ if (isa<LoadInst>(Inst) && isAcquireOrStronger(Ord))
+ return Builder.CreateFence(AtomicOrdering::Acquire);
+ return nullptr;
+}