Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -24,6 +24,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/InlineAsm.h" @@ -804,12 +805,19 @@ /// Return true if this instruction could possibly read memory. /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. + /// Also returns true if an instruction is marked mayAccessMemory + /// *and* carries a memory operand representing a load. bool mayLoad(QueryType Type = AnyInBundle) const { if (isInlineAsm()) { unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); if (ExtraInfo & InlineAsm::Extra_MayLoad) return true; } + if (hasProperty(MCID::MayAccessMemory, Type)) { + for (const auto *MMO : memoperands()) + if (MMO->isLoad()) + return true; + } return hasProperty(MCID::MayLoad, Type); } @@ -817,12 +825,19 @@ /// Instructions with this flag set are not necessarily simple store /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. + /// Also returns true if an instruction is marked mayAccessMemory + /// *and* carries a memory operand representing a store. bool mayStore(QueryType Type = AnyInBundle) const { if (isInlineAsm()) { unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); if (ExtraInfo & InlineAsm::Extra_MayStore) return true; } + if (hasProperty(MCID::MayAccessMemory, Type)) { + for (const auto *MMO : memoperands()) + if (MMO->isStore()) + return true; + } return hasProperty(MCID::MayStore, Type); } Index: include/llvm/MC/MCInstrDesc.h =================================================================== --- include/llvm/MC/MCInstrDesc.h +++ include/llvm/MC/MCInstrDesc.h @@ -135,6 +135,7 @@ FoldableAsLoad, MayLoad, MayStore, + MayAccessMemory, Predicable, NotDuplicable, UnmodeledSideEffects, @@ -398,6 +399,13 @@ /// may not actually modify anything, for example. bool mayStore() const { return Flags & (1ULL << MCID::MayStore); } + /// Return true if this instruction may optionally access memory. + /// Such instructions are only considered to actually access memory + /// if they carry MachineMemOperand entries. + bool mayAccessMemory() const { + return Flags & (1ULL << MCID::MayAccessMemory); + } + /// Return true if this instruction has side /// effects that are not modeled by other flags. This does not return true /// for instructions whose effects are captured by: Index: include/llvm/Target/Target.td =================================================================== --- include/llvm/Target/Target.td +++ include/llvm/Target/Target.td @@ -453,6 +453,7 @@ bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? bit mayLoad = ?; // Is it possible for this inst to read memory? bit mayStore = ?; // Is it possible for this inst to write memory? + bit mayAccessMemory = 0; // Can this inst have optional memory operands? bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote? bit isCommutable = 0; // Is this 3 operand instruction commutable? bit isTerminator = 0; // Is this part of the terminator for a basic block? Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3609,8 +3609,8 @@ // Only attach load or store memory operands if the generated // instruction may load or store. const MCInstrDesc &MCID = TII->get(TargetOpc); - bool mayLoad = MCID.mayLoad(); - bool mayStore = MCID.mayStore(); + bool mayLoad = MCID.mayAccessMemory() || MCID.mayLoad(); + bool mayStore = MCID.mayAccessMemory() || MCID.mayStore(); // We expect to have relatively few of these so just filter them into a // temporary buffer so that we can easily add them to the instruction. Index: utils/TableGen/CodeGenInstruction.h =================================================================== --- utils/TableGen/CodeGenInstruction.h +++ utils/TableGen/CodeGenInstruction.h @@ -239,6 +239,7 @@ bool mayLoad_Unset : 1; bool mayStore : 1; bool mayStore_Unset : 1; + bool mayAccessMemory : 1; bool isPredicable : 1; bool isConvertibleToThreeAddress : 1; bool isCommutable : 1; Index: utils/TableGen/CodeGenInstruction.cpp =================================================================== --- utils/TableGen/CodeGenInstruction.cpp +++ utils/TableGen/CodeGenInstruction.cpp @@ -337,6 +337,7 @@ mayLoad_Unset = Unset; mayStore = R->getValueAsBitOrUnset("mayStore", Unset); mayStore_Unset = Unset; + mayAccessMemory = R->getValueAsBit("mayAccessMemory"); hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", Unset); hasSideEffects_Unset = Unset; Index: utils/TableGen/DAGISelMatcherGen.cpp =================================================================== --- utils/TableGen/DAGISelMatcherGen.cpp +++ utils/TableGen/DAGISelMatcherGen.cpp @@ -663,7 +663,7 @@ Record *Op = N->getOperator(); const CodeGenTarget &CGT = CGP.getTargetInfo(); CodeGenInstruction &II = CGT.getInstruction(Op); - return II.mayLoad || II.mayStore; + return II.mayLoad || II.mayStore || II.mayAccessMemory; } static unsigned Index: utils/TableGen/InstrInfoEmitter.cpp =================================================================== --- utils/TableGen/InstrInfoEmitter.cpp +++ utils/TableGen/InstrInfoEmitter.cpp @@ -585,6 +585,7 @@ if (Inst.canFoldAsLoad) OS << "|(1ULL<