From 74fef128e4c72640b44142d22d3e931c8eb03365 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 6 Jan 2017 17:20:50 -0800 Subject: [PATCH] Support s390x atomic fence --- llvm-d18644-systemz-atomic-fence.patch | 169 +++++++++++++++++++++++++ llvm.spec | 9 +- 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 llvm-d18644-systemz-atomic-fence.patch diff --git a/llvm-d18644-systemz-atomic-fence.patch b/llvm-d18644-systemz-atomic-fence.patch new file mode 100644 index 0000000..c3996fa --- /dev/null +++ b/llvm-d18644-systemz-atomic-fence.patch @@ -0,0 +1,169 @@ +Index: llvm/trunk/lib/Target/SystemZ/SystemZAsmPrinter.cpp +=================================================================== +--- llvm/trunk/lib/Target/SystemZ/SystemZAsmPrinter.cpp ++++ llvm/trunk/lib/Target/SystemZ/SystemZAsmPrinter.cpp +@@ -260,6 +260,11 @@ + .addImm(15).addReg(SystemZ::R0D); + break; + ++ // Emit nothing here but a comment if we can. ++ case SystemZ::MemBarrier: ++ OutStreamer->emitRawComment("MEMBARRIER"); ++ return; ++ + default: + Lower.lower(MI, LoweredMI); + break; +Index: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h +=================================================================== +--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h ++++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h +@@ -146,6 +146,9 @@ + // Perform a serialization operation. (BCR 15,0 or BCR 14,0.) + SERIALIZE, + ++ // Compiler barrier only; generate a no-op. ++ MEMBARRIER, ++ + // Transaction begin. The first operand is the chain, the second + // the TDB pointer, and the third the immediate control field. + // Returns chain and glue. +@@ -479,6 +482,7 @@ + SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerCTPOP(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG, +Index: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp +=================================================================== +--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp ++++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp +@@ -216,6 +216,8 @@ + setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, Custom); + setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Custom); + ++ setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); ++ + // z10 has instructions for signed but not unsigned FP conversion. + // Handle unsigned 32-bit types as signed 64-bit types. + if (!Subtarget.hasFPExtension()) { +@@ -3118,6 +3120,25 @@ + return Op; + } + ++SDValue SystemZTargetLowering::lowerATOMIC_FENCE(SDValue Op, ++ SelectionDAG &DAG) const { ++ SDLoc DL(Op); ++ AtomicOrdering FenceOrdering = static_cast( ++ cast(Op.getOperand(1))->getZExtValue()); ++ SynchronizationScope FenceScope = static_cast( ++ cast(Op.getOperand(2))->getZExtValue()); ++ ++ // The only fence that needs an instruction is a sequentially-consistent ++ // cross-thread fence. ++ if (FenceOrdering == SequentiallyConsistent && FenceScope == CrossThread) { ++ return SDValue(DAG.getMachineNode(SystemZ::Serialize, DL, MVT::Other, ++ Op.getOperand(0)), 0); ++ } ++ ++ // MEMBARRIER is a compiler barrier; it codegens to a no-op. ++ return DAG.getNode(SystemZISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); ++} ++ + // Op is an atomic load. Lower it into a normal volatile load. + SDValue SystemZTargetLowering::lowerATOMIC_LOAD(SDValue Op, + SelectionDAG &DAG) const { +@@ -4444,6 +4465,8 @@ + case ISD::CTTZ_ZERO_UNDEF: + return DAG.getNode(ISD::CTTZ, SDLoc(Op), + Op.getValueType(), Op.getOperand(0)); ++ case ISD::ATOMIC_FENCE: ++ return lowerATOMIC_FENCE(Op, DAG); + case ISD::ATOMIC_SWAP: + return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_SWAPW); + case ISD::ATOMIC_STORE: +@@ -4547,6 +4570,7 @@ + OPCODE(SEARCH_STRING); + OPCODE(IPM); + OPCODE(SERIALIZE); ++ OPCODE(MEMBARRIER); + OPCODE(TBEGIN); + OPCODE(TBEGIN_NOFLOAT); + OPCODE(TEND); +@@ -5307,6 +5331,7 @@ + MachineBasicBlock * + SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, + MachineBasicBlock *MBB) const { ++ + MachineFunction &MF = *MBB->getParent(); + const SystemZInstrInfo *TII = + static_cast(Subtarget.getInstrInfo()); +Index: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td +=================================================================== +--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td ++++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td +@@ -1231,6 +1231,10 @@ + let hasSideEffects = 1 in + def Serialize : Alias<2, (outs), (ins), [(z_serialize)]>; + ++// A pseudo instruction that serves as a compiler barrier. ++let hasSideEffects = 1 in ++def MemBarrier : Pseudo<(outs), (ins), [(z_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>; +Index: llvm/trunk/lib/Target/SystemZ/SystemZOperators.td +=================================================================== +--- llvm/trunk/lib/Target/SystemZ/SystemZOperators.td ++++ llvm/trunk/lib/Target/SystemZ/SystemZOperators.td +@@ -188,6 +188,8 @@ + + def z_serialize : SDNode<"SystemZISD::SERIALIZE", SDTNone, + [SDNPHasChain, SDNPMayStore]>; ++def z_membarrier : SDNode<"SystemZISD::MEMBARRIER", SDTNone, ++ [SDNPHasChain, SDNPSideEffect]>; + + // Defined because the index is an i32 rather than a pointer. + def z_vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", +Index: llvm/trunk/test/CodeGen/SystemZ/atomic-fence-01.ll +=================================================================== +--- llvm/trunk/test/CodeGen/SystemZ/atomic-fence-01.ll ++++ llvm/trunk/test/CodeGen/SystemZ/atomic-fence-01.ll +@@ -0,0 +1,16 @@ ++; Test (fast) serialization. ++; ++; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s --check-prefix=Z10 ++; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s --check-prefix=Z196 ++; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s --check-prefix=ZEC12 ++; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s --check-prefix=Z13 ++ ++define void @test() { ++; Z10: bcr 15, %r0 ++; Z196: bcr 14, %r0 ++; ZEC12: bcr 14, %r0 ++; Z13: bcr 14, %r0 ++ fence seq_cst ++ ret void ++} ++ +Index: llvm/trunk/test/CodeGen/SystemZ/atomic-fence-02.ll +=================================================================== +--- llvm/trunk/test/CodeGen/SystemZ/atomic-fence-02.ll ++++ llvm/trunk/test/CodeGen/SystemZ/atomic-fence-02.ll +@@ -0,0 +1,13 @@ ++; Serialization is emitted only for fence seq_cst. ++; ++; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s ++ ++define void @test() { ++; CHECK: #MEMBARRIER ++ fence acquire ++; CHECK: #MEMBARRIER ++ fence release ++; CHECK: #MEMBARRIER ++ fence acq_rel ++ ret void ++} diff --git a/llvm.spec b/llvm.spec index ebfa448..8295ba4 100644 --- a/llvm.spec +++ b/llvm.spec @@ -7,7 +7,7 @@ Name: llvm Version: 3.8.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: The Low Level Virtual Machine License: NCSA @@ -19,6 +19,9 @@ Source100: llvm-config.h # recognize s390 as SystemZ when configuring build Patch0: llvm-3.7.1-cmake-s390.patch +# backport D18644 [SystemZ] Support ATOMIC_FENCE +Patch1: llvm-d18644-systemz-atomic-fence.patch + BuildRequires: cmake BuildRequires: zlib-devel BuildRequires: libffi-devel @@ -70,6 +73,7 @@ Static libraries for the LLVM compiler infrastructure. %prep %setup -q -n %{name}-%{version}.src %patch0 -p1 -b .s390 +%patch1 -p2 -b .s390-fence %build mkdir -p _build @@ -185,6 +189,9 @@ make check-all || : %{_libdir}/*.a %changelog +* Sat Jan 07 2017 Josh Stone - 3.8.1-2 +- Support s390x atomic fence + * Wed Jul 13 2016 Adam Jackson - 3.8.1-1 - llvm 3.8.1 - Add mips target