[llvm] ed372d1 - [M68k] Add support for lowering atomic fence

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 1 19:59:28 PDT 2023


Author: Min-Yih Hsu
Date: 2023-04-01T19:57:04-07:00
New Revision: ed372d194f938b750855ad1297517d26f1102250

URL: https://github.com/llvm/llvm-project/commit/ed372d194f938b750855ad1297517d26f1102250
DIFF: https://github.com/llvm/llvm-project/commit/ed372d194f938b750855ad1297517d26f1102250.diff

LOG: [M68k] Add support for lowering atomic fence

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

We use a similar way to lower ATOMIC_FENCE.

Differential Revision: https://reviews.llvm.org/D146996

Added: 
    llvm/test/CodeGen/M68k/Atomics/fence.ll

Modified: 
    llvm/lib/Target/M68k/M68kISelLowering.cpp
    llvm/lib/Target/M68k/M68kISelLowering.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp
index c49b83fdc6eb..d261be6c944c 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -163,6 +163,8 @@ M68kTargetLowering::M68kTargetLowering(const M68kTargetMachine &TM,
   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 @@ SDValue M68kTargetLowering::LowerOperation(SDValue Op,
     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 @@ SDValue M68kTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
                       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

diff  --git a/llvm/lib/Target/M68k/M68kISelLowering.h b/llvm/lib/Target/M68k/M68kISelLowering.h
index f998f60f4c9d..bffb11961db7 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.h
+++ b/llvm/lib/Target/M68k/M68kISelLowering.h
@@ -238,6 +238,8 @@ class M68kTargetLowering : public TargetLowering {
   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,

diff  --git a/llvm/test/CodeGen/M68k/Atomics/fence.ll b/llvm/test/CodeGen/M68k/Atomics/fence.ll
new file mode 100644
index 000000000000..23318ac302da
--- /dev/null
+++ b/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
+}
+


        


More information about the llvm-commits mailing list