[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