[llvm] cd050a0 - [Mips] Support mips1 and singlethread ATOMIC_FENCE (#190129)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 23 03:54:03 PDT 2026
Author: yingopq
Date: 2026-04-23T11:53:58+01:00
New Revision: cd050a0fe32d402c949f6ae2fb3583db73270e1b
URL: https://github.com/llvm/llvm-project/commit/cd050a0fe32d402c949f6ae2fb3583db73270e1b
DIFF: https://github.com/llvm/llvm-project/commit/cd050a0fe32d402c949f6ae2fb3583db73270e1b.diff
LOG: [Mips] Support mips1 and singlethread ATOMIC_FENCE (#190129)
Fix #61166.
Added:
llvm/test/CodeGen/Mips/fence.ll
Modified:
llvm/lib/Target/Mips/MipsISelLowering.cpp
llvm/lib/Target/Mips/MipsInstrInfo.td
Removed:
################################################################################
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/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 51e011ca86942..76bfe31534161 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()); }]>;
@@ -1695,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"), [],
@@ -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
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
+}
More information about the llvm-commits
mailing list