Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4417,10 +4417,10 @@ auto Alignment = DAG.getEVTAlignment(MemVT); - // FIXME: Volatile isn't really correct; we should keep track of atomic - // orderings in the memoperand. - auto Flags = MachineMemOperand::MOVolatile | MachineMemOperand::MOLoad | - MachineMemOperand::MOStore; + auto Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore; + if (I.isVolatile()) + Flags |= MachineMemOperand::MOVolatile; + Flags |= DAG.getTargetLoweringInfo().getMMOFlags(I); MachineFunction &MF = DAG.getMachineFunction(); MachineMemOperand *MMO = @@ -4468,12 +4468,10 @@ auto MemVT = getValue(I.getValOperand()).getSimpleValueType(); auto Alignment = DAG.getEVTAlignment(MemVT); - // For now, atomics are considered to be volatile always, and they are - // chained as such. - // FIXME: Volatile isn't really correct; we should keep track of atomic - // orderings in the memoperand. - auto Flags = MachineMemOperand::MOVolatile | - MachineMemOperand::MOLoad | MachineMemOperand::MOStore; + auto Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore; + if (I.isVolatile()) + Flags |= MachineMemOperand::MOVolatile; + Flags |= DAG.getTargetLoweringInfo().getMMOFlags(I); MachineFunction &MF = DAG.getMachineFunction(); MachineMemOperand *MMO = @@ -4518,12 +4516,15 @@ I.getAlignment() < VT.getStoreSize()) report_fatal_error("Cannot generate unaligned atomic load"); + auto Flags = MachineMemOperand::MOLoad; + if (I.isVolatile()) + Flags |= MachineMemOperand::MOVolatile; + Flags |= TLI.getMMOFlags(I); + MachineMemOperand *MMO = DAG.getMachineFunction(). getMachineMemOperand(MachinePointerInfo(I.getPointerOperand()), - MachineMemOperand::MOVolatile | - MachineMemOperand::MOLoad, - VT.getStoreSize(), + Flags, VT.getStoreSize(), I.getAlignment() ? I.getAlignment() : DAG.getEVTAlignment(VT), AAMDNodes(), nullptr, SSID, Order); @@ -4554,11 +4555,10 @@ if (I.getAlignment() < VT.getStoreSize()) report_fatal_error("Cannot generate unaligned atomic store"); - // For now, atomics are considered to be volatile always, and they are - // chained as such. - // FIXME: Volatile isn't really correct; we should keep track of atomic - // orderings in the memoperand. - auto Flags = MachineMemOperand::MOVolatile | MachineMemOperand::MOStore; + auto Flags = MachineMemOperand::MOStore; + if (I.isVolatile()) + Flags |= MachineMemOperand::MOVolatile; + Flags |= TLI.getMMOFlags(I); MachineFunction &MF = DAG.getMachineFunction(); MachineMemOperand *MMO = Index: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h =================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h @@ -642,6 +642,7 @@ MachineBasicBlock *MBB, unsigned Opcode) const; + MachineMemOperand::Flags getMMOFlags(const Instruction &I) const override; const TargetRegisterClass *getRepRegClassFor(MVT VT) const override; }; Index: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -3718,6 +3718,27 @@ return SDValue(); } +MachineMemOperand::Flags +SystemZTargetLowering::getMMOFlags(const Instruction &I) const { + // Because of how we convert atomic_load and atomic_store to normal loads and + // stores in the DAG, we need to ensure that the MMOs are marked volatile + // since DAGCombine hasn't been updated to account for atomic, but non + // volatile loads. (See D57601) + if (auto *SI = dyn_cast(&I)) + if (SI->isAtomic()) + return MachineMemOperand::MOVolatile; + if (auto *LI = dyn_cast(&I)) + if (LI->isAtomic()) + return MachineMemOperand::MOVolatile; + if (auto *AI = dyn_cast(&I)) + if (AI->isAtomic()) + return MachineMemOperand::MOVolatile; + if (auto *AI = dyn_cast(&I)) + if (AI->isAtomic()) + return MachineMemOperand::MOVolatile; + return MachineMemOperand::MONone; +} + SDValue SystemZTargetLowering::lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); Index: llvm/trunk/lib/Target/XCore/XCoreISelLowering.h =================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.h +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.h @@ -188,6 +188,8 @@ SDValue LowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const; SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const; + MachineMemOperand::Flags getMMOFlags(const Instruction &I) const override; + // Inline asm support std::pair getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, Index: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp @@ -1008,6 +1008,27 @@ return SDValue(); } +MachineMemOperand::Flags +XCoreTargetLowering::getMMOFlags(const Instruction &I) const { + // Because of how we convert atomic_load and atomic_store to normal loads and + // stores in the DAG, we need to ensure that the MMOs are marked volatile + // since DAGCombine hasn't been updated to account for atomic, but non + // volatile loads. (See D57601) + if (auto *SI = dyn_cast(&I)) + if (SI->isAtomic()) + return MachineMemOperand::MOVolatile; + if (auto *LI = dyn_cast(&I)) + if (LI->isAtomic()) + return MachineMemOperand::MOVolatile; + if (auto *AI = dyn_cast(&I)) + if (AI->isAtomic()) + return MachineMemOperand::MOVolatile; + if (auto *AI = dyn_cast(&I)) + if (AI->isAtomic()) + return MachineMemOperand::MOVolatile; + return MachineMemOperand::MONone; +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// Index: llvm/trunk/test/CodeGen/AMDGPU/syncscopes.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/syncscopes.ll +++ llvm/trunk/test/CodeGen/AMDGPU/syncscopes.ll @@ -1,9 +1,9 @@ ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -stop-after=si-insert-skips < %s | FileCheck --check-prefix=GCN %s ; GCN-LABEL: name: syncscopes -; GCN: FLAT_STORE_DWORD killed renamable $vgpr1_vgpr2, killed renamable $vgpr0, 0, 0, 0, implicit $exec, implicit $flat_scr :: (volatile store syncscope("agent") seq_cst 4 into %ir.agent_out) -; GCN: FLAT_STORE_DWORD killed renamable $vgpr4_vgpr5, killed renamable $vgpr3, 0, 0, 0, implicit $exec, implicit $flat_scr :: (volatile store syncscope("workgroup") seq_cst 4 into %ir.workgroup_out) -; GCN: FLAT_STORE_DWORD killed renamable $vgpr7_vgpr8, killed renamable $vgpr6, 0, 0, 0, implicit $exec, implicit $flat_scr :: (volatile store syncscope("wavefront") seq_cst 4 into %ir.wavefront_out) +; GCN: FLAT_STORE_DWORD killed renamable $vgpr1_vgpr2, killed renamable $vgpr0, 0, 0, 0, implicit $exec, implicit $flat_scr :: (store syncscope("agent") seq_cst 4 into %ir.agent_out) +; GCN: FLAT_STORE_DWORD killed renamable $vgpr4_vgpr5, killed renamable $vgpr3, 0, 0, 0, implicit $exec, implicit $flat_scr :: (store syncscope("workgroup") seq_cst 4 into %ir.workgroup_out) +; GCN: FLAT_STORE_DWORD killed renamable $vgpr7_vgpr8, killed renamable $vgpr6, 0, 0, 0, implicit $exec, implicit $flat_scr :: (store syncscope("wavefront") seq_cst 4 into %ir.wavefront_out) define void @syncscopes( i32 %agent, i32* %agent_out,