[PATCH] D146996: [M68k] Add support for lowering atomic fence

Min-Yih Hsu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 27 12:39:12 PDT 2023


myhsu created this revision.
myhsu added reviewers: 0x59616e, RKSimon.
Herald added a subscriber: hiraditya.
Herald added a project: All.
myhsu requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Ideally we want to lower ATOMIC_FENCE into `__sync_synchronize`. However, libgcc doesn't implement that builtin as GCC simply generates an inline assembly memory barrier whenever there has to be a fence.

We use a similar way to lower ATOMIC_FENCE.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146996

Files:
  llvm/lib/Target/M68k/M68kISelLowering.cpp
  llvm/lib/Target/M68k/M68kISelLowering.h
  llvm/test/CodeGen/M68k/Atomics/fence.ll


Index: llvm/test/CodeGen/M68k/Atomics/fence.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/M68k/Atomics/fence.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=m68k-linux-gnu < %s | FileCheck %s
+
+; M68k's libgcc does NOT have __sync_synchronize so we shouldn't
+; lower to that.
+
+define void @atomic_fence() {
+; CHECK-LABEL: atomic_fence:
+; CHECK:         .cfi_startproc
+; CHECK-NEXT:  ; %bb.0: ; %entry
+; CHECK-NEXT:    ;APP
+; CHECK-NEXT:    ;NO_APP
+; CHECK-NEXT:    ;APP
+; CHECK-NEXT:    ;NO_APP
+; CHECK-NEXT:    ;APP
+; CHECK-NEXT:    ;NO_APP
+; CHECK-NEXT:    ;APP
+; CHECK-NEXT:    ;NO_APP
+; CHECK-NEXT:    rts
+entry:
+  fence acquire
+  fence release
+  fence acq_rel
+  fence seq_cst
+  ret void
+}
+
Index: llvm/lib/Target/M68k/M68kISelLowering.h
===================================================================
--- llvm/lib/Target/M68k/M68kISelLowering.h
+++ llvm/lib/Target/M68k/M68kISelLowering.h
@@ -238,6 +238,8 @@
   SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
 
+  SDValue LowerATOMICFENCE(SDValue Op, SelectionDAG &DAG) const;
+
   SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
                           CallingConv::ID CallConv, bool IsVarArg,
                           const SmallVectorImpl<ISD::InputArg> &Ins,
Index: llvm/lib/Target/M68k/M68kISelLowering.cpp
===================================================================
--- llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -163,6 +163,8 @@
   setOperationAction(ISD::ATOMIC_CMP_SWAP, {MVT::i8, MVT::i16, MVT::i32},
                      Subtarget.atLeastM68020() ? Legal : LibCall);
 
+  setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
+
   // M68k does not have native read-modify-write support, so expand all of them
   // to `__sync_fetch_*` for target < M68020, otherwise expand to CmpxChg.
   // See `shouldExpandAtomicRMWInIR` below.
@@ -1408,6 +1410,8 @@
     return LowerShiftRightParts(Op, DAG, true);
   case ISD::SRL_PARTS:
     return LowerShiftRightParts(Op, DAG, false);
+  case ISD::ATOMIC_FENCE:
+    return LowerATOMICFENCE(Op, DAG);
   }
 }
 
@@ -3240,6 +3244,28 @@
                       MachinePointerInfo(SV));
 }
 
+SDValue M68kTargetLowering::LowerATOMICFENCE(SDValue Op,
+                                             SelectionDAG &DAG) const {
+  // Lower to a memory barrier created from inline asm.
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  LLVMContext &Ctx = *DAG.getContext();
+
+  const unsigned Flags = InlineAsm::Extra_MayLoad | InlineAsm::Extra_MayStore |
+                         InlineAsm::Extra_HasSideEffects;
+  const SDValue AsmOperands[4] = {
+      Op.getOperand(0), // Input chain
+      DAG.getTargetExternalSymbol(
+          "", TLI.getProgramPointerTy(
+                  DAG.getDataLayout())),   // Empty inline asm string
+      DAG.getMDNode(MDNode::get(Ctx, {})), // (empty) srcloc
+      DAG.getTargetConstant(Flags, SDLoc(Op),
+                            TLI.getPointerTy(DAG.getDataLayout())), // Flags
+  };
+
+  return DAG.getNode(ISD::INLINEASM, SDLoc(Op),
+                     DAG.getVTList(MVT::Other, MVT::Glue), AsmOperands);
+}
+
 // Lower dynamic stack allocation to _alloca call for Cygwin/Mingw targets.
 // Calls to _alloca are needed to probe the stack when allocating more than 4k
 // bytes in one go. Touching the stack at 4K increments is necessary to ensure


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D146996.508760.patch
Type: text/x-patch
Size: 3665 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230327/b81d5430/attachment.bin>


More information about the llvm-commits mailing list