diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -321,6 +321,7 @@ void Select_FREEZE(SDNode *N); void Select_ARITH_FENCE(SDNode *N); + void Select_MEMBARRIER(SDNode *N); void pushStackMapLiveVariable(SmallVectorImpl &Ops, SDValue Operand, SDLoc DL); diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -222,6 +222,10 @@ HANDLE_TARGET_OPCODE(ICALL_BRANCH_FUNNEL) +// This is a fence with the singlethread scope. It represents a compiler memory +// barrier, but does not correspond to any generated instruction. +HANDLE_TARGET_OPCODE(MEMBARRIER) + /// The following generic opcodes are not supposed to appear after ISel. /// This is something we might want to relax, but for now, this is convenient /// to produce diagnostics. diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -1432,6 +1432,14 @@ let AsmString = ""; let hasSideEffects = true; } +def MEMBARRIER : StandardPseudoInstruction { + let OutOperandList = (outs); + let InOperandList = (ins); + let AsmString = ""; + let hasSideEffects = true; + let Size = 0; + let isMeta = true; +} // Generic opcodes used in GlobalISel. include "llvm/Target/GenericOpcodes.td" diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1653,6 +1653,9 @@ if (isVerbose()) OutStreamer->emitRawComment("ARITH_FENCE"); break; + case TargetOpcode::MEMBARRIER: + OutStreamer->emitRawComment("MEMBARRIER"); + break; default: emitInstruction(&MI); if (CanDoExtraAnalysis) { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2245,6 +2245,11 @@ N->getOperand(0)); } +void SelectionDAGISel::Select_MEMBARRIER(SDNode *N) { + CurDAG->SelectNodeTo(N, TargetOpcode::MEMBARRIER, N->getValueType(0), + N->getOperand(0)); +} + void SelectionDAGISel::pushStackMapLiveVariable(SmallVectorImpl &Ops, SDValue OpVal, SDLoc DL) { SDNode *OpNode = OpVal.getNode(); @@ -2899,6 +2904,9 @@ case ISD::ARITH_FENCE: Select_ARITH_FENCE(NodeToMatch); return; + case ISD::MEMBARRIER: + Select_MEMBARRIER(NodeToMatch); + return; case ISD::STACKMAP: Select_STACKMAP(NodeToMatch); return; diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -116,9 +116,6 @@ 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/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1843,9 +1843,6 @@ (AddiPairImmSmall AddiPair:$rs2))>; } -let hasSideEffects = 1, isMeta = 1 in -def PseudoMemBarrier : Pseudo<(outs), (ins), [(membarrier)]>; - //===----------------------------------------------------------------------===// // Standard extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -530,11 +530,6 @@ .addImm(15).addReg(SystemZ::R0D); break; - // Emit nothing here but a comment if we can. - case SystemZ::MemBarrier: - OutStreamer->emitRawComment("MEMBARRIER"); - return; - // We want to emit "j .+2" for traps, jumping to the relative immediate field // of the jump instruction, which is an illegal instruction. We cannot emit a // "." symbol, so create and emit a temp label before the instruction and use diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -1716,10 +1716,6 @@ let hasSideEffects = 1 in def Serialize : Alias<2, (outs), (ins), []>; -// A pseudo instruction that serves as a compiler barrier. -let hasSideEffects = 1, hasNoSchedulingInfo = 1 in -def MemBarrier : Pseudo<(outs), (ins), [(membarrier)]>; - let Predicates = [FeatureInterlockedAccess1], Defs = [CC] in { def LAA : LoadAndOpRSY<"laa", 0xEBF8, atomic_load_add_32, GR32>; def LAAG : LoadAndOpRSY<"laag", 0xEBE8, atomic_load_add_64, GR64>; diff --git a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp --- a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp +++ b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp @@ -217,7 +217,7 @@ assert((Size || // These do not have a size: MI.isDebugOrPseudoInstr() || MI.isPosition() || MI.isKill() || - MI.isImplicitDef() || MI.getOpcode() == SystemZ::MemBarrier || + MI.isImplicitDef() || MI.getOpcode() == TargetOpcode::MEMBARRIER || // These have a size that may be zero: MI.isInlineAsm() || MI.getOpcode() == SystemZ::STACKMAP || MI.getOpcode() == SystemZ::PATCHPOINT) && diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -2018,10 +2018,6 @@ "# GET STACK TOP", [(set iPTR:$dst, (GetStackTop))]>; -// MEMBARRIER -let hasSideEffects = 1 in -def MEMBARRIER : Pseudo<(outs), (ins), "# MEMBARRIER", [(membarrier)] >; - //===----------------------------------------------------------------------===// // Other patterns //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -681,11 +681,6 @@ Requires<[Not64BitMode]>, OpSize32, LOCK, Sched<[WriteALURMW]>; -let hasSideEffects = 1, isMeta = 1 in -def Int_MemBarrier : I<0, Pseudo, (outs), (ins), - "#MEMBARRIER", - [(membarrier)]>, Sched<[WriteLoad]>; - // RegOpc corresponds to the mr version of the instruction // ImmOpc corresponds to the mi version of the instruction // ImmOpc8 corresponds to the mi8 version of the instruction diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -2506,11 +2506,6 @@ case TargetOpcode::DBG_VALUE: llvm_unreachable("Should be handled target independently"); - // Emit nothing here but a comment if we can. - case X86::Int_MemBarrier: - OutStreamer->emitRawComment("MEMBARRIER"); - return; - case X86::EH_RETURN: case X86::EH_RETURN64: { // Lower these as normal, but add some comments. diff --git a/llvm/lib/Target/XCore/XCoreInstrInfo.td b/llvm/lib/Target/XCore/XCoreInstrInfo.td --- a/llvm/lib/Target/XCore/XCoreInstrInfo.td +++ b/llvm/lib/Target/XCore/XCoreInstrInfo.td @@ -358,10 +358,6 @@ (select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>; } -let hasSideEffects = 1, isMeta = 1 in -def Int_MemBarrier : PseudoInstXCore<(outs), (ins), "#MEMBARRIER", - [(membarrier)]>; - //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/X86/atomic-idempotent.ll b/llvm/test/CodeGen/X86/atomic-idempotent.ll --- a/llvm/test/CodeGen/X86/atomic-idempotent.ll +++ b/llvm/test/CodeGen/X86/atomic-idempotent.ll @@ -359,6 +359,8 @@ ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: retl atomicrmw or ptr %p, i32 0 monotonic ret void @@ -385,6 +387,8 @@ ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: retl atomicrmw or ptr %p, i32 0 acquire ret void @@ -410,6 +414,8 @@ ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: retl atomicrmw or ptr %p, i32 0 release ret void @@ -435,6 +441,8 @@ ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop +; X86-ATOM-NEXT: nop ; X86-ATOM-NEXT: retl atomicrmw or ptr %p, i32 0 acq_rel ret void diff --git a/llvm/unittests/MIR/MachineMetadata.cpp b/llvm/unittests/MIR/MachineMetadata.cpp --- a/llvm/unittests/MIR/MachineMetadata.cpp +++ b/llvm/unittests/MIR/MachineMetadata.cpp @@ -334,7 +334,7 @@ LIFETIME_END 0 PSEUDO_PROBE 6699318081062747564, 1, 0, 0 $xmm0 = ARITH_FENCE $xmm0 - Int_MemBarrier + MEMBARRIER ... )MIR";