Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -38,6 +38,18 @@ // deleted if dead. def IntrReadMem : IntrinsicProperty; +// IntrWriteMem - This intrinsic writes to unspecified memory, but does not +// read from memory, and has no other side effects. This means dead stores +// before calls to this intrinsics may be removed. +def IntrWriteMem : IntrinsicProperty; + +// IntrWriteArgMem - This intrinsic writes only to memory that one of its +// arguments points to, but may access an unspecified amount. The writes may +// be volatile, but the intrinsic does not read from memory and has no other +// side effects. This means that dead stores before calls to this intrinsics +// may be removed. +def IntrWriteArgMem : IntrinsicProperty; + // IntrReadWriteArgMem - This intrinsic reads and writes only from memory that // one of its arguments points to, but may access an unspecified amount. The // reads and writes may be volatile, but except for this it has no other side Index: include/llvm/IR/IntrinsicsAMDGPU.td =================================================================== --- include/llvm/IR/IntrinsicsAMDGPU.td +++ include/llvm/IR/IntrinsicsAMDGPU.td @@ -230,7 +230,7 @@ llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - []>; + [IntrWriteMem]>; class AMDGPUBufferAtomic : Intrinsic < [llvm_i32_ty], Index: lib/Target/AMDGPU/SIInstructions.td =================================================================== --- lib/Target/AMDGPU/SIInstructions.td +++ lib/Target/AMDGPU/SIInstructions.td @@ -949,23 +949,18 @@ defm BUFFER_LOAD_FORMAT_XYZW : MUBUF_Load_Helper < mubuf<0x03>, "buffer_load_format_xyzw", VReg_128 >; -// Without mayLoad and hasSideEffects, TableGen complains about the pattern -// matching llvm.amdgcn.buffer.store.format. Eventually, we'll need a way -// to express the effects of the intrinsic more precisely. -let mayLoad = 1, hasSideEffects = 1 in { - defm BUFFER_STORE_FORMAT_X : MUBUF_Store_Helper < - mubuf<0x04>, "buffer_store_format_x", VGPR_32 - >; - defm BUFFER_STORE_FORMAT_XY : MUBUF_Store_Helper < - mubuf<0x05>, "buffer_store_format_xy", VReg_64 - >; - defm BUFFER_STORE_FORMAT_XYZ : MUBUF_Store_Helper < - mubuf<0x06>, "buffer_store_format_xyz", VReg_96 - >; - defm BUFFER_STORE_FORMAT_XYZW : MUBUF_Store_Helper < - mubuf<0x07>, "buffer_store_format_xyzw", VReg_128 - >; -} +defm BUFFER_STORE_FORMAT_X : MUBUF_Store_Helper < + mubuf<0x04>, "buffer_store_format_x", VGPR_32 +>; +defm BUFFER_STORE_FORMAT_XY : MUBUF_Store_Helper < + mubuf<0x05>, "buffer_store_format_xy", VReg_64 +>; +defm BUFFER_STORE_FORMAT_XYZ : MUBUF_Store_Helper < + mubuf<0x06>, "buffer_store_format_xyz", VReg_96 +>; +defm BUFFER_STORE_FORMAT_XYZW : MUBUF_Store_Helper < + mubuf<0x07>, "buffer_store_format_xyzw", VReg_128 +>; defm BUFFER_LOAD_UBYTE : MUBUF_Load_Helper < mubuf<0x08, 0x10>, "buffer_load_ubyte", VGPR_32, i32, az_extloadi8_global >; Index: utils/TableGen/CodeGenDAGPatterns.cpp =================================================================== --- utils/TableGen/CodeGenDAGPatterns.cpp +++ utils/TableGen/CodeGenDAGPatterns.cpp @@ -2816,14 +2816,14 @@ if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { // If this is an intrinsic, analyze it. - if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem) + if (IntInfo->ModRef & CodeGenIntrinsic::MR_Ref) mayLoad = true;// These may load memory. - if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteArgMem) + if (IntInfo->ModRef & CodeGenIntrinsic::MR_Mod) mayStore = true;// Intrinsics that can write to memory are 'mayStore'. if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem) - // WriteMem intrinsics can have other strange effects. + // ReadWriteMem intrinsics can have other strange effects. hasSideEffects = true; } } Index: utils/TableGen/CodeGenIntrinsics.h =================================================================== --- utils/TableGen/CodeGenIntrinsics.h +++ utils/TableGen/CodeGenIntrinsics.h @@ -59,11 +59,36 @@ IntrinsicSignature IS; - // Memory mod/ref behavior of this intrinsic. - enum ModRefKind { - NoMem, ReadArgMem, ReadMem, ReadWriteArgMem, ReadWriteMem + /// Bit flags describing the type (ref/mod) and location of memory + /// accesses that may be performed by the intrinsics. Analogous to + /// \c FunctionModRefBehaviour. + enum ModRefBits { + /// The intrinsic may access memory anywhere, i.e. it is not restricted + /// to access through pointer arguments. + MR_Anywhere = 1, + + /// The intrinsic may read memory. + MR_Ref = 2, + + /// The intrinsic may write memory. + MR_Mod = 4, + + /// The intrinsic may both read and write memory. + MR_ModRef = MR_Ref | MR_Mod, }; - ModRefKind ModRef; + + /// Memory mod/ref behavior of this intrinsic, corresponding to + /// intrinsic properties (IntrReadMem, IntrReadArgMem, etc.). + enum ModRefBehavior { + NoMem = 0, + ReadArgMem = MR_Ref, + ReadMem = MR_Ref | MR_Anywhere, + WriteArgMem = MR_Mod, + WriteMem = MR_Mod | MR_Anywhere, + ReadWriteArgMem = MR_ModRef, + ReadWriteMem = MR_ModRef | MR_Anywhere, + }; + ModRefBehavior ModRef; /// This is set to true if the intrinsic is overloaded by its argument /// types. Index: utils/TableGen/CodeGenTarget.cpp =================================================================== --- utils/TableGen/CodeGenTarget.cpp +++ utils/TableGen/CodeGenTarget.cpp @@ -577,6 +577,10 @@ ModRef = ReadArgMem; else if (Property->getName() == "IntrReadMem") ModRef = ReadMem; + else if (Property->getName() == "IntrWriteMem") + ModRef = WriteMem; + else if (Property->getName() == "IntrWriteArgMem") + ModRef = WriteArgMem; else if (Property->getName() == "IntrReadWriteArgMem") ModRef = ReadWriteArgMem; else if (Property->getName() == "Commutative") Index: utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- utils/TableGen/IntrinsicEmitter.cpp +++ utils/TableGen/IntrinsicEmitter.cpp @@ -462,8 +462,8 @@ return R->isConvergent; // Try to order by readonly/readnone attribute. - CodeGenIntrinsic::ModRefKind LK = L->ModRef; - CodeGenIntrinsic::ModRefKind RK = R->ModRef; + CodeGenIntrinsic::ModRefBehavior LK = L->ModRef; + CodeGenIntrinsic::ModRefBehavior RK = R->ModRef; if (LK != RK) return (LK > RK); // Order by argument attributes. @@ -616,11 +616,13 @@ OS << ","; OS << "Attribute::ReadOnly"; break; + case CodeGenIntrinsic::WriteArgMem: case CodeGenIntrinsic::ReadWriteArgMem: if (addComma) OS << ","; OS << "Attribute::ArgMemOnly"; break; + case CodeGenIntrinsic::WriteMem: case CodeGenIntrinsic::ReadWriteMem: break; }