]> granicus.if.org Git - llvm/commitdiff
GlobalISel: represent atomic loads & stores via the MachineMemOperand.
authorTim Northover <tnorthover@apple.com>
Mon, 13 Feb 2017 22:14:16 +0000 (22:14 +0000)
committerTim Northover <tnorthover@apple.com>
Mon, 13 Feb 2017 22:14:16 +0000 (22:14 +0000)
Also make sure the AArch64 backend doesn't try to convert them into normal
loads and stores.

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

lib/CodeGen/GlobalISel/IRTranslator.cpp
lib/Target/AArch64/AArch64InstructionSelector.cpp
test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

index 97292dc5bd7f6c712439c21a6cc1a22466a10f74..143134758c3e7e8fecc09702318693d389be0d71 100644 (file)
@@ -271,10 +271,6 @@ bool IRTranslator::translateIndirectBr(const User &U,
 bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
   const LoadInst &LI = cast<LoadInst>(U);
 
-  if (!TPC->isGlobalISelAbortEnabled() && LI.isAtomic())
-    return false;
-
-  assert(!LI.isAtomic() && "only non-atomic loads are supported at the moment");
   auto Flags = LI.isVolatile() ? MachineMemOperand::MOVolatile
                                : MachineMemOperand::MONone;
   Flags |= MachineMemOperand::MOLoad;
@@ -286,17 +282,13 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
       Res, Addr,
       *MF->getMachineMemOperand(MachinePointerInfo(LI.getPointerOperand()),
                                 Flags, DL->getTypeStoreSize(LI.getType()),
-                                getMemOpAlignment(LI)));
+                                getMemOpAlignment(LI), AAMDNodes(), nullptr,
+                                LI.getSynchScope(), LI.getOrdering()));
   return true;
 }
 
 bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
   const StoreInst &SI = cast<StoreInst>(U);
-
-  if (!TPC->isGlobalISelAbortEnabled() && SI.isAtomic())
-    return false;
-
-  assert(!SI.isAtomic() && "only non-atomic stores supported at the moment");
   auto Flags = SI.isVolatile() ? MachineMemOperand::MOVolatile
                                : MachineMemOperand::MONone;
   Flags |= MachineMemOperand::MOStore;
@@ -311,7 +303,8 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
       *MF->getMachineMemOperand(
           MachinePointerInfo(SI.getPointerOperand()), Flags,
           DL->getTypeStoreSize(SI.getValueOperand()->getType()),
-          getMemOpAlignment(SI)));
+          getMemOpAlignment(SI), AAMDNodes(), nullptr, SI.getSynchScope(),
+          SI.getOrdering()));
   return true;
 }
 
index 42b4daf2318cc008514ecf3937e513255b74e63e..6bced17d09d79730147eae9da15e52b729bb7704 100644 (file)
@@ -691,6 +691,12 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
       return false;
     }
 
+    auto &MemOp = **I.memoperands_begin();
+    if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
+      DEBUG(dbgs() << "Atomic load/store not supported yet\n");
+      return false;
+    }
+
 #ifndef NDEBUG
     // Sanity-check the pointer register.
     const unsigned PtrReg = I.getOperand(1).getReg();
index 96ec21527259f304cb4748fe680c6ea60f992698..4ef3dfcd11b94f123c1b27f3f8f6200a80c371b7 100644 (file)
@@ -90,3 +90,12 @@ define void @legal_default([8 x i8] %in) {
 define i128 @sequence_sizes([8 x i8] %in) {
   ret i128 undef
 }
+
+; Just to make sure we don't accidentally emit a normal load/store.
+; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for atomic_ops
+; FALLBACK-WITH-REPORT-LABEL: atomic_ops:
+define i64 @atomic_ops(i64* %addr) {
+  store atomic i64 0, i64* %addr unordered, align 8
+  %res = load atomic i64, i64* %addr seq_cst, align 8
+  ret i64 %res
+}
index acb342af9a5b1d9e62a421cc387141436db49bc9..418c71e3992d0ac38e24667035c17bb84323a6ee 100644 (file)
@@ -1155,3 +1155,24 @@ define void @test_lifetime_intrin() {
   call void @llvm.lifetime.end(i64 0, i8* %slot)
   ret void
 }
+
+define void @test_load_store_atomics(i8* %addr) {
+; CHECK-LABEL: name: test_load_store_atomics
+; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0
+; CHECK: [[V0:%[0-9]+]](s8) = G_LOAD [[ADDR]](p0) :: (load unordered 1 from %ir.addr)
+; CHECK: G_STORE [[V0]](s8), [[ADDR]](p0) :: (store monotonic 1 into %ir.addr)
+; CHECK: [[V1:%[0-9]+]](s8) = G_LOAD [[ADDR]](p0) :: (load acquire 1 from %ir.addr)
+; CHECK: G_STORE [[V1]](s8), [[ADDR]](p0) :: (store release 1 into %ir.addr)
+; CHECK: [[V2:%[0-9]+]](s8) = G_LOAD [[ADDR]](p0) :: (load singlethread seq_cst 1 from %ir.addr)
+; CHECK: G_STORE [[V2]](s8), [[ADDR]](p0) :: (store singlethread monotonic 1 into %ir.addr)
+  %v0 = load atomic i8, i8* %addr unordered, align 1
+  store atomic i8 %v0, i8* %addr monotonic, align 1
+
+  %v1 = load atomic i8, i8* %addr acquire, align 1
+  store atomic i8 %v1, i8* %addr release, align 1
+
+  %v2 = load atomic i8, i8* %addr singlethread seq_cst, align 1
+  store atomic i8 %v2, i8* %addr singlethread monotonic, align 1
+
+  ret void
+}