From: Matt Arsenault Date: Tue, 2 Jul 2019 14:16:39 +0000 (+0000) Subject: GlobalISel: Add G_FENCE X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ac62c2b3bd98869767bb54375d589e2067a3465;p=llvm GlobalISel: Add G_FENCE The pattern importer is for some reason emitting checks for G_CONSTANT for the immediate operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364926 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 989805c81a6..8654ba83f08 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -448,6 +448,7 @@ private: bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder); bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder); + bool translateFence(const User &U, MachineIRBuilder &MIRBuilder); // Stubs to keep the compiler happy while we implement the rest of the // translation. @@ -463,9 +464,6 @@ private: bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) { return false; } - bool translateFence(const User &U, MachineIRBuilder &MIRBuilder) { - return false; - } bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) { return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder); } diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 1db3c4ca1d3..cca503c3788 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -1136,6 +1136,9 @@ public: MachineInstrBuilder buildAtomicRMWUmin(Register OldValRes, Register Addr, Register Val, MachineMemOperand &MMO); + /// Build and insert `G_FENCE Ordering, Scope`. + MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope); + /// Build and insert \p Res = G_BLOCK_ADDR \p BA /// /// G_BLOCK_ADDR computes the address of a basic block. diff --git a/include/llvm/Support/TargetOpcodes.def b/include/llvm/Support/TargetOpcodes.def index bbaeffdb075..fa024638561 100644 --- a/include/llvm/Support/TargetOpcodes.def +++ b/include/llvm/Support/TargetOpcodes.def @@ -316,6 +316,9 @@ HANDLE_TARGET_OPCODE(G_ATOMICRMW_MIN) HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMAX) HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMIN) +// Generic atomic fence +HANDLE_TARGET_OPCODE(G_FENCE) + /// Generic conditional branch instruction. HANDLE_TARGET_OPCODE(G_BRCOND) diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index 4a75f77224d..11fbf621154 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -743,6 +743,12 @@ def G_ATOMICRMW_MIN : G_ATOMICRMW_OP; def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP; def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP; +def G_FENCE : GenericInstruction { + let OutOperandList = (outs); + let InOperandList = (ins i32imm:$ordering, i32imm:$scope); + let hasSideEffects = 1; +} + //------------------------------------------------------------------------------ // Variadic ops //------------------------------------------------------------------------------ diff --git a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index 6c38d1279c0..35c80c2a5a3 100644 --- a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -136,6 +136,7 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. // Should be used on defs that subclass GIComplexOperandMatcher<>. diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index 443ca730d55..96efcf7a373 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2029,6 +2029,14 @@ bool IRTranslator::translateAtomicRMW(const User &U, return true; } +bool IRTranslator::translateFence(const User &U, + MachineIRBuilder &MIRBuilder) { + const FenceInst &Fence = cast(U); + MIRBuilder.buildFence(static_cast(Fence.getOrdering()), + Fence.getSyncScopeID()); + return true; +} + void IRTranslator::finishPendingPhis() { #ifndef NDEBUG DILocationVerifier Verifier; diff --git a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 00dce14fe07..4d6026ade86 100644 --- a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -850,6 +850,13 @@ MachineIRBuilder::buildAtomicRMWUmin(Register OldValRes, Register Addr, MMO); } +MachineInstrBuilder +MachineIRBuilder::buildFence(unsigned Ordering, unsigned Scope) { + return buildInstr(TargetOpcode::G_FENCE) + .addImm(Ordering) + .addImm(Scope); +} + MachineInstrBuilder MachineIRBuilder::buildBlockAddress(Register Res, const BlockAddress *BA) { #ifndef NDEBUG diff --git a/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index 420add64882..37bd3c8193b 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -144,6 +144,9 @@ # DEBUG-NEXT: G_ATOMICRMW_UMIN (opcode {{[0-9]+}}): 2 type indices # DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected # +# DEBUG-NEXT: G_FENCE (opcode {{[0-9]+}}): 0 type indices +# DEBUG: .. type index coverage check SKIPPED: no rules defined +# # DEBUG-NEXT: G_BRCOND (opcode {{[0-9]+}}): 1 type index # DEBUG: .. the first uncovered type index: 1, OK # diff --git a/test/CodeGen/AMDGPU/GlobalISel/irtranslator-fence.ll b/test/CodeGen/AMDGPU/GlobalISel/irtranslator-fence.ll new file mode 100644 index 00000000000..684d566592a --- /dev/null +++ b/test/CodeGen/AMDGPU/GlobalISel/irtranslator-fence.ll @@ -0,0 +1,361 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -stop-after=irtranslator < %s | FileCheck %s + +define amdgpu_kernel void @system_one_as_acquire() { + ; CHECK-LABEL: name: system_one_as_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 2 + ; CHECK: S_ENDPGM 0 + fence syncscope("one-as") acquire + ret void +} + +define amdgpu_kernel void @system_one_as_release() { + ; CHECK-LABEL: name: system_one_as_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 2 + ; CHECK: S_ENDPGM 0 + fence syncscope("one-as") release + ret void +} + +define amdgpu_kernel void @system_one_as_acq_rel() { + ; CHECK-LABEL: name: system_one_as_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 2 + ; CHECK: S_ENDPGM 0 + fence syncscope("one-as") acq_rel + ret void +} + +define amdgpu_kernel void @system_one_as_seq_cst() { + ; CHECK-LABEL: name: system_one_as_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 2 + ; CHECK: S_ENDPGM 0 + fence syncscope("one-as") seq_cst + ret void +} + +define amdgpu_kernel void @singlethread_one_as_acquire() { + ; CHECK-LABEL: name: singlethread_one_as_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 3 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread-one-as") acquire + ret void +} + +define amdgpu_kernel void @singlethread_one_as_release() { + ; CHECK-LABEL: name: singlethread_one_as_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 3 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread-one-as") release + ret void +} + +define amdgpu_kernel void @singlethread_one_as_acq_rel() { + ; CHECK-LABEL: name: singlethread_one_as_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 3 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread-one-as") acq_rel + ret void +} + +define amdgpu_kernel void @singlethread_one_as_seq_cst() { + ; CHECK-LABEL: name: singlethread_one_as_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 3 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread-one-as") seq_cst + ret void +} + +define amdgpu_kernel void @agent_one_as_acquire() { + ; CHECK-LABEL: name: agent_one_as_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 4 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent-one-as") acquire + ret void +} + +define amdgpu_kernel void @agent_one_as_release() { + ; CHECK-LABEL: name: agent_one_as_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 4 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent-one-as") release + ret void +} + +define amdgpu_kernel void @agent_one_as_acq_rel() { + ; CHECK-LABEL: name: agent_one_as_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 4 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent-one-as") acq_rel + ret void +} + +define amdgpu_kernel void @agent_one_as_seq_cst() { + ; CHECK-LABEL: name: agent_one_as_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 4 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent-one-as") seq_cst + ret void +} + +define amdgpu_kernel void @workgroup_one_as_acquire() { + ; CHECK-LABEL: name: workgroup_one_as_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 5 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup-one-as") acquire + ret void +} + +define amdgpu_kernel void @workgroup_one_as_release() { + ; CHECK-LABEL: name: workgroup_one_as_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 5 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup-one-as") release + ret void +} + +define amdgpu_kernel void @workgroup_one_as_acq_rel() { + ; CHECK-LABEL: name: workgroup_one_as_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 5 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup-one-as") acq_rel + ret void +} + +define amdgpu_kernel void @workgroup_one_as_seq_cst() { + ; CHECK-LABEL: name: workgroup_one_as_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 5 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup-one-as") seq_cst + ret void +} + +define amdgpu_kernel void @wavefront_one_as_acquire() { + ; CHECK-LABEL: name: wavefront_one_as_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 6 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront-one-as") acquire + ret void +} + +define amdgpu_kernel void @wavefront_one_as_release() { + ; CHECK-LABEL: name: wavefront_one_as_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 6 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront-one-as") release + ret void +} + +define amdgpu_kernel void @wavefront_one_as_acq_rel() { + ; CHECK-LABEL: name: wavefront_one_as_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 6 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront-one-as") acq_rel + ret void +} + +define amdgpu_kernel void @wavefront_one_as_seq_cst() { + ; CHECK-LABEL: name: wavefront_one_as_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 6 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront-one-as") seq_cst + ret void +} + +define amdgpu_kernel void @system_acquire() { + ; CHECK-LABEL: name: system_acquire + ; CHECK: bb.1.entry: + ; CHECK: S_ENDPGM 0 +entry: + ret void +} + +define amdgpu_kernel void @system_release() { + ; CHECK-LABEL: name: system_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 1 + ; CHECK: S_ENDPGM 0 + fence release + ret void +} + +define amdgpu_kernel void @system_acq_rel() { + ; CHECK-LABEL: name: system_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 1 + ; CHECK: S_ENDPGM 0 + fence acq_rel + ret void +} + +define amdgpu_kernel void @system_seq_cst() { + ; CHECK-LABEL: name: system_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 1 + ; CHECK: S_ENDPGM 0 + fence seq_cst + ret void +} + +define amdgpu_kernel void @singlethread_acquire() { + ; CHECK-LABEL: name: singlethread_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 0 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread") acquire + ret void +} + +define amdgpu_kernel void @singlethread_release() { + ; CHECK-LABEL: name: singlethread_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 0 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread") release + ret void +} + +define amdgpu_kernel void @singlethread_acq_rel() { + ; CHECK-LABEL: name: singlethread_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 0 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread") acq_rel + ret void +} + +define amdgpu_kernel void @singlethread_seq_cst() { + ; CHECK-LABEL: name: singlethread_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 0 + ; CHECK: S_ENDPGM 0 + fence syncscope("singlethread") seq_cst + ret void +} + +define amdgpu_kernel void @agent_acquire() { + ; CHECK-LABEL: name: agent_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 7 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent") acquire + ret void +} + +define amdgpu_kernel void @agent_release() { + ; CHECK-LABEL: name: agent_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 7 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent") release + ret void +} + +define amdgpu_kernel void @agent_acq_rel() { + ; CHECK-LABEL: name: agent_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 7 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent") acq_rel + ret void +} + +define amdgpu_kernel void @agent_seq_cst() { + ; CHECK-LABEL: name: agent_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 7 + ; CHECK: S_ENDPGM 0 + fence syncscope("agent") seq_cst + ret void +} + +define amdgpu_kernel void @workgroup_acquire() { + ; CHECK-LABEL: name: workgroup_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 8 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup") acquire + ret void +} + +define amdgpu_kernel void @workgroup_release() { + ; CHECK-LABEL: name: workgroup_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 8 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup") release + ret void +} + +define amdgpu_kernel void @workgroup_acq_rel() { + ; CHECK-LABEL: name: workgroup_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 8 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup") acq_rel + ret void +} + +define amdgpu_kernel void @workgroup_seq_cst() { + ; CHECK-LABEL: name: workgroup_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 8 + ; CHECK: S_ENDPGM 0 + fence syncscope("workgroup") seq_cst + ret void +} + +define amdgpu_kernel void @wavefront_acquire() { + ; CHECK-LABEL: name: wavefront_acquire + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 4, 9 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront") acquire + ret void +} + +define amdgpu_kernel void @wavefront_release() { + ; CHECK-LABEL: name: wavefront_release + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 5, 9 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront") release + ret void +} + +define amdgpu_kernel void @wavefront_acq_rel() { + ; CHECK-LABEL: name: wavefront_acq_rel + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 6, 9 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront") acq_rel + ret void +} + +define amdgpu_kernel void @wavefront_seq_cst() { + ; CHECK-LABEL: name: wavefront_seq_cst + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: G_FENCE 7, 9 + ; CHECK: S_ENDPGM 0 + fence syncscope("wavefront") seq_cst + ret void +}