[llvm] [Mips] Support mips1 and singlethread ATOMIC_FENCE (PR #190129)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 22 19:46:51 PDT 2026


https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/190129

>From bb9e3b01a6177d812416394a1518fe6e0bc083dc Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Thu, 2 Apr 2026 15:54:45 +0800
Subject: [PATCH 1/3] [Mips] Support mips1 and singlethread ATOMIC_FENCE

Fix #61166.
---
 llvm/lib/Target/Mips/MipsISelLowering.cpp | 19 ++++++++++--
 llvm/test/CodeGen/Mips/fence.ll           | 37 +++++++++++++++++++++++
 2 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/Mips/fence.ll

diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index c29f1b616356a..298b525e48cff 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -2667,8 +2667,23 @@ SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDValue Op,
   // FIXME: Set SType for weaker fences where supported/appropriate.
   unsigned SType = 0;
   SDLoc DL(Op);
-  return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0),
-                     DAG.getConstant(SType, DL, MVT::i32));
+  SyncScope::ID FenceSSID =
+      static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
+
+  if (Subtarget.hasMips2() && FenceSSID == SyncScope::System)
+    return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0),
+                       DAG.getTargetConstant(SType, DL, MVT::i32));
+
+  // 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 ((Subtarget.hasMips1() && !Subtarget.hasMips2()) ||
+      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 MipsTargetLowering::lowerShiftLeftParts(SDValue Op,
diff --git a/llvm/test/CodeGen/Mips/fence.ll b/llvm/test/CodeGen/Mips/fence.ll
new file mode 100644
index 0000000000000..ff38b98e862f1
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/fence.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=mipsel-linux-gnu -mcpu=mips1 < %s | FileCheck %s --check-prefix=MIPS1
+; RUN: llc --mtriple=mipsel-linux-gnu -mcpu=mips2 < %s | FileCheck %s --check-prefix=MIPS2
+
+define void @fence_singlethread() {
+; MIPS1-LABEL: fence_singlethread:
+; MIPS1:       # %bb.0:
+; MIPS1-NEXT:    #MEMBARRIER
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+
+; MIPS2-LABEL: fence_singlethread:
+; MIPS2:       # %bb.0:
+; MIPS2-NEXT:    #MEMBARRIER
+; MIPS2-NEXT:    jr $ra
+; MIPS2-NEXT:    nop
+
+  fence syncscope("singlethread") seq_cst
+  ret void
+}
+
+define void @fence() {
+; MIPS1-LABEL: fence:
+; MIPS1:       # %bb.0:
+; MIPS1-NEXT:    #MEMBARRIER
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+
+; MIPS2-LABEL: fence:
+; MIPS2:       # %bb.0:
+; MIPS2-NEXT:    sync
+; MIPS2-NEXT:    jr $ra
+; MIPS2-NEXT:    nop
+
+  fence seq_cst
+  ret void
+}

>From d4d42fea9562aedcdc50c567e4e22dd9b9e1a501 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Wed, 22 Apr 2026 16:23:23 +0800
Subject: [PATCH 2/3] Fix the compile error: can not select `sync
 targetconstant 0`

---
 llvm/lib/Target/Mips/MipsInstrInfo.td | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 51e011ca86942..7e9556fae05d6 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -1244,6 +1244,8 @@ def Plus1 : SDNodeXForm<imm, [{
 // Node immediate is zero (e.g. insve.d)
 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
 
+def timmz : PatLeaf<(timm), [{ return N->getSExtValue() == 0; }]>;
+
 // Node immediate fits as 16-bit sign extended on target immediate.
 // e.g. addi, andi
 def immSExt8  : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
@@ -3217,7 +3219,7 @@ def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
       ISA_MIPS1_NOT_32R6_64R6;
 
 // SYNC
-def : MipsPat<(MipsSync (i32 immz)),
+def : MipsPat<(MipsSync (i32 timmz)),
               (SYNC 0)>, ISA_MIPS2;
 
 // Call

>From d8abe16731eff18200bd1fbc7576eca137374560 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Thu, 23 Apr 2026 10:45:52 +0800
Subject: [PATCH 3/3] Fix micromips compile error: can not select `sync
 targetconstant 0`

---
 llvm/lib/Target/Mips/MipsInstrInfo.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 7e9556fae05d6..76bfe31534161 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -1697,7 +1697,7 @@ class DEI_FT<string opstr, RegisterOperand RO,
 let hasSideEffects = 1 in
 class SYNC_FT<string opstr> :
   InstSE<(outs), (ins uimm5:$stype), "sync $stype",
-         [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
+         [(MipsSync timmZExt5:$stype)], II_SYNC, FrmOther, opstr>;
 
 class SYNCI_FT<string opstr, DAGOperand MO> :
   InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],



More information about the llvm-commits mailing list