]> granicus.if.org Git - llvm/commitdiff
[aarch64][globalisel] Define G_ATOMIC_CMPXCHG and G_ATOMICRMW_* and make them legal
authorDaniel Sanders <daniel_l_sanders@apple.com>
Tue, 28 Nov 2017 20:21:15 +0000 (20:21 +0000)
committerDaniel Sanders <daniel_l_sanders@apple.com>
Tue, 28 Nov 2017 20:21:15 +0000 (20:21 +0000)
The IRTranslator cannot generate these instructions at the moment so there's no
issue with not having implemented ISel for them yet. D40092 will add
G_ATOMIC_CMPXCHG_WITH_SUCCESS and G_ATOMICRMW_* to the IRTranslator and a
further patch will add support for lowering G_ATOMIC_CMPXCHG_WITH_SUCCESS into
G_ATOMIC_CMPXCHG with an external success check via the `Lower` action.

The separation of G_ATOMIC_CMPXCHG_WITH_SUCCESS and G_ATOMIC_CMPXCHG is
to import SelectionDAG rules while still supporting targets that prefer to
custom lower the original LLVM-IR-like operation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319216 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/TargetOpcodes.def
include/llvm/Target/GenericOpcodes.td
lib/Target/AArch64/AArch64LegalizerInfo.cpp
lib/Target/AArch64/AArch64LegalizerInfo.h
lib/Target/AArch64/AArch64Subtarget.cpp

index 37e2e41b43dafba8646ef089db9ad6e754bda5b3..3497dcf195d017f8b6c1dbb3d8fe3277dc6c523e 100644 (file)
@@ -265,6 +265,22 @@ HANDLE_TARGET_OPCODE(G_LOAD)
 /// Generic store.
 HANDLE_TARGET_OPCODE(G_STORE)
 
+/// Generic atomic cmpxchg.
+HANDLE_TARGET_OPCODE(G_ATOMIC_CMPXCHG)
+
+/// Generic atomicrmw.
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_XCHG)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_ADD)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_SUB)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_AND)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_NAND)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_OR)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_XOR)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_MAX)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_MIN)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMAX)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMIN)
+
 /// Generic conditional branch instruction.
 HANDLE_TARGET_OPCODE(G_BRCOND)
 
index 557217c345622f1332152d1da50e5c1fdebd7ebb..b1cb3022fc1f141622819466a84d78bf2ff5bd49 100644 (file)
@@ -482,6 +482,104 @@ def G_STORE : Instruction {
   let mayStore = 1;
 }
 
+// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
+// operands.
+def G_ATOMIC_CMPXCHG : Instruction {
+  let OutOperandList = (outs type0:$oldval);
+  let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+
+// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
+// operands.
+class G_ATOMICRMW_OP : Instruction {
+  let OutOperandList = (outs type0:$oldval);
+  let InOperandList = (ins ptype1:$addr, type0:$val);
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+
+def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_ADD : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_SUB : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_AND : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_NAND : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_OR : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_XOR : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_MAX : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_MIN : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP {
+  // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+  //        block which overrides the value inherited from G_ATOMICRMW_OP. Work
+  //        around this for now. See http://reviews.llvm.org/D40096
+  let mayLoad = 1;
+  let mayStore = 1;
+}
+
 //------------------------------------------------------------------------------
 // Variadic ops
 //------------------------------------------------------------------------------
index f7027394f8031621dbef904361016f75725a6d44..b04031530a291cdc69abe8bc36616d76326422f6 100644 (file)
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AArch64LegalizerInfo.h"
+#include "AArch64Subtarget.h"
 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -127,7 +128,7 @@ widen_1_8_16_32(const LegalizerInfo::SizeAndActionsVec &v) {
   return result;
 }
 
-AArch64LegalizerInfo::AArch64LegalizerInfo() {
+AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
   using namespace TargetOpcode;
   const LLT p0 = LLT::pointer(0, 64);
   const LLT s1 = LLT::scalar(1);
@@ -349,6 +350,22 @@ AArch64LegalizerInfo::AArch64LegalizerInfo() {
   for (auto Ty : {s8, s16, s32, s64, p0})
     setAction({G_VAARG, Ty}, Custom);
 
+  if (ST.hasLSE()) {
+    for (auto Ty : {s8, s16, s32, s64})
+      setAction({G_ATOMIC_CMPXCHG, Ty}, Legal);
+    setAction({G_ATOMIC_CMPXCHG, 1, p0}, Legal);
+
+    for (auto Op :
+         {G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND,
+          G_ATOMICRMW_OR, G_ATOMICRMW_XOR, G_ATOMICRMW_MIN, G_ATOMICRMW_MAX,
+          G_ATOMICRMW_UMIN, G_ATOMICRMW_UMAX}) {
+      for (auto Ty : {s8, s16, s32, s64}) {
+        setAction({Op, Ty}, Legal);
+      }
+      setAction({Op, 1, p0}, Legal);
+    }
+  }
+
   computeTables();
 }
 
index 42d4ac130c5c83f3d9891bbc1fc3eec99e3c56b5..a745b0edbc6d943e0af989863005bc11d20bcec6 100644 (file)
 namespace llvm {
 
 class LLVMContext;
+class AArch64Subtarget;
 
 /// This class provides the information for the target register banks.
 class AArch64LegalizerInfo : public LegalizerInfo {
 public:
-  AArch64LegalizerInfo();
+  AArch64LegalizerInfo(const AArch64Subtarget &ST);
 
   bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI,
                       MachineIRBuilder &MIRBuilder) const override;
index 28b8f7c79cf191944b5d0fca4c569a931eea8b68..60cbe54bd39a22fd42f4fc432a7c5ffb5024dd95 100644 (file)
@@ -154,7 +154,7 @@ AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
       InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
       TLInfo(TM, *this) {
   CallLoweringInfo.reset(new AArch64CallLowering(*getTargetLowering()));
-  Legalizer.reset(new AArch64LegalizerInfo());
+  Legalizer.reset(new AArch64LegalizerInfo(*this));
 
   auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo());