[llvm] c4ce1e0 - [RISCV] Avoid emitting hardware fences for singlethread fences
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 10 10:10:26 PST 2023
Author: Philip Reames
Date: 2023-01-10T10:09:59-08:00
New Revision: c4ce1e0131aa04cec4803740c3c203c7f000e837
URL: https://github.com/llvm/llvm-project/commit/c4ce1e0131aa04cec4803740c3c203c7f000e837
DIFF: https://github.com/llvm/llvm-project/commit/c4ce1e0131aa04cec4803740c3c203c7f000e837.diff
LOG: [RISCV] Avoid emitting hardware fences for singlethread fences
singlethread fences only synchronize with code running on the same hardware thread (i.e. signal handlers). Because of this, we need to prevent instruction reordering, but do not need to emit hardware fence instructions.
The implementation strategy here matches many other backends. The main motivation of this patch is to introduce the MEMBARRIER node and get some test coverage for it.
Differential Revision: https://reviews.llvm.org/D141311
Added:
Modified:
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/test/CodeGen/RISCV/atomic-fence.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 5c36a917caeaa..3bafbccac9d59 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -116,6 +116,9 @@ void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) {
case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
LowerHWASAN_CHECK_MEMACCESS(*MI);
return;
+ case RISCV::PseudoMemBarrier:
+ OutStreamer->emitRawComment("MEMBARRIER");
+ return;
}
MCInst TmpInst;
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 74dc737ddf7f4..8c1c8b5501593 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -461,6 +461,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setMaxAtomicSizeInBitsSupported(0);
}
+ setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
+
setBooleanContents(ZeroOrOneBooleanContent);
if (Subtarget.hasVInstructions()) {
@@ -3667,11 +3669,28 @@ static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG,
return SDValue();
}
+static SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) {
+ SDLoc dl(Op);
+ SyncScope::ID FenceSSID =
+ static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
+
+ // singlethread fences only synchronize with signal handlers on the same
+ // thread and thus only need to preserve instruction order, not actually
+ // enforce memory ordering.
+ if (FenceSSID == SyncScope::SingleThread)
+ // MEMBARRIER is a compiler barrier; it codegens to a no-op.
+ return DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0));
+
+ return Op;
+}
+
SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
SelectionDAG &DAG) const {
switch (Op.getOpcode()) {
default:
report_fatal_error("unimplemented operand");
+ case ISD::ATOMIC_FENCE:
+ return LowerATOMIC_FENCE(Op, DAG);
case ISD::GlobalAddress:
return lowerGlobalAddress(Op, DAG);
case ISD::BlockAddress:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index c699a94943d82..e46982eb3da8c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1843,6 +1843,9 @@ def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
(AddiPairImmSmall AddiPair:$rs2))>;
}
+let hasSideEffects = 1, isMeta = 1 in
+def PseudoMemBarrier : Pseudo<(outs), (ins), [(membarrier)]>;
+
//===----------------------------------------------------------------------===//
// Standard extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/RISCV/atomic-fence.ll b/llvm/test/CodeGen/RISCV/atomic-fence.ll
index ff91652a253ec..a8d49ce7fa24b 100644
--- a/llvm/test/CodeGen/RISCV/atomic-fence.ll
+++ b/llvm/test/CodeGen/RISCV/atomic-fence.ll
@@ -51,7 +51,7 @@ define void @fence_seq_cst() nounwind {
define void @fence_singlethread_acquire() nounwind {
; CHECK-LABEL: fence_singlethread_acquire:
; CHECK: # %bb.0:
-; CHECK-NEXT: fence r, rw
+; CHECK-NEXT: #MEMBARRIER
; CHECK-NEXT: ret
fence syncscope("singlethread") acquire
ret void
@@ -60,7 +60,7 @@ define void @fence_singlethread_acquire() nounwind {
define void @fence_singlethread_release() nounwind {
; CHECK-LABEL: fence_singlethread_release:
; CHECK: # %bb.0:
-; CHECK-NEXT: fence rw, w
+; CHECK-NEXT: #MEMBARRIER
; CHECK-NEXT: ret
fence syncscope("singlethread") release
ret void
@@ -69,7 +69,7 @@ define void @fence_singlethread_release() nounwind {
define void @fence_singlethread_acq_rel() nounwind {
; CHECK-LABEL: fence_singlethread_acq_rel:
; CHECK: # %bb.0:
-; CHECK-NEXT: fence.tso
+; CHECK-NEXT: #MEMBARRIER
; CHECK-NEXT: ret
fence syncscope("singlethread") acq_rel
ret void
@@ -78,7 +78,7 @@ define void @fence_singlethread_acq_rel() nounwind {
define void @fence_singlethread_seq_cst() nounwind {
; CHECK-LABEL: fence_singlethread_seq_cst:
; CHECK: # %bb.0:
-; CHECK-NEXT: fence rw, rw
+; CHECK-NEXT: #MEMBARRIER
; CHECK-NEXT: ret
fence syncscope("singlethread") seq_cst
ret void
More information about the llvm-commits
mailing list