Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -67,6 +67,13 @@ int ArgNo = argNo; } +// IntrOnlyWriteMem - Despite writing to memory, this intrinsic neither reads +// from memory nor does it have "additional" side effects. What this means is +// target-dependent. The idea is that the intrinsic is lowered to a +// target-dependent instruction which is store-like, but whose memory access +// patterns cannot be properly modelled at the LLVM IR level. +def IntrOnlyWriteMem : IntrinsicProperty; + def IntrNoReturn : IntrinsicProperty; // IntrNoduplicate - Calls to this intrinsic cannot be duplicated. Index: include/llvm/IR/IntrinsicsAMDGPU.td =================================================================== --- include/llvm/IR/IntrinsicsAMDGPU.td +++ include/llvm/IR/IntrinsicsAMDGPU.td @@ -222,7 +222,7 @@ llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - []>; + [IntrOnlyWriteMem]>; 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,13 +2816,15 @@ if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { // If this is an intrinsic, analyze it. - if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem) + if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem && + !IntInfo->onlyWriteMem) mayLoad = true;// These may load memory. if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteArgMem) mayStore = true;// Intrinsics that can write to memory are 'mayStore'. - if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem) + if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem && + !IntInfo->onlyWriteMem) // WriteMem intrinsics can have other strange effects. hasSideEffects = true; } Index: utils/TableGen/CodeGenIntrinsics.h =================================================================== --- utils/TableGen/CodeGenIntrinsics.h +++ utils/TableGen/CodeGenIntrinsics.h @@ -65,6 +65,12 @@ }; ModRefKind ModRef; + /// This is set to true if the intrinsic is explicitly marked as not loading + /// and not having side effects despite writing to memory. This is useful + /// for targets with special store intrinsics that do not write through + /// LLVM IR pointers. + bool onlyWriteMem; + /// This is set to true if the intrinsic is overloaded by its argument /// types. bool isOverloaded; Index: utils/TableGen/CodeGenTarget.cpp =================================================================== --- utils/TableGen/CodeGenTarget.cpp +++ utils/TableGen/CodeGenTarget.cpp @@ -449,6 +449,7 @@ TheDef = R; std::string DefName = R->getName(); ModRef = ReadWriteMem; + onlyWriteMem = false; isOverloaded = false; isCommutative = false; canThrow = false; @@ -589,6 +590,8 @@ isConvergent = true; else if (Property->getName() == "IntrNoReturn") isNoReturn = true; + else if (Property->getName() == "IntrOnlyWriteMem") + onlyWriteMem = true; else if (Property->isSubClassOf("NoCapture")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));