Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -92,6 +92,12 @@ // information to AsmPrinter. uint8_t NumMemRefs; // Information on memory references. + // Note that MemRefs == nullptr, means 'don't know', not 'no memory access'. + // Calling code must treat missing information conservatively. If the number + // of memory operands required to be precise exceeds the maximum value of + // NumMemRefs - currently 256 - we remove the operands entirely. Note also + // that this is a non-owning reference to a shared copy on write buffer owned + // by the MachineFunction and created via MF.allocateMemRefsArray. mmo_iterator MemRefs; DebugLoc debugLoc; // Source line information. @@ -346,6 +352,9 @@ /// Access to memory operands of the instruction mmo_iterator memoperands_begin() const { return MemRefs; } mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } + /// Return true if we don't have any memory operands which described the the + /// memory access done by this instruction. If this is true, calling code + /// must be conservative. bool memoperands_empty() const { return NumMemRefs == 0; } iterator_range memoperands() { Index: lib/CodeGen/MachineLICM.cpp =================================================================== --- lib/CodeGen/MachineLICM.cpp +++ lib/CodeGen/MachineLICM.cpp @@ -330,6 +330,10 @@ /// Return true if instruction stores to the specified frame. static bool InstructionStoresToFI(const MachineInstr *MI, int FI) { + // If we lost memory operands, conservatively assume that the instruction + // writes to all slots. + if (MI->memoperands_empty()) + return true; for (MachineInstr::mmo_iterator o = MI->memoperands_begin(), oe = MI->memoperands_end(); o != oe; ++o) { if (!(*o)->isStore() || !(*o)->getPseudoValue()) @@ -846,8 +850,14 @@ /// Return true if this machine instruction loads from global offset table or /// constant pool. -static bool isLoadFromGOTOrConstantPool(MachineInstr &MI) { +static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI) { assert (MI.mayLoad() && "Expected MI that loads!"); + + // If we lost memory operands, conservatively assume that the instruction + // reads from everything.. + if (MI.memoperands_empty()) + return true; + for (MachineInstr::mmo_iterator I = MI.memoperands_begin(), E = MI.memoperands_end(); I != E; ++I) { if (const PseudoSourceValue *PSV = (*I)->getPseudoValue()) { @@ -872,7 +882,7 @@ // from constant memory are not safe to speculate all the time, for example // indexed load from a jump table. // Stores and side effects are already checked by isSafeToMove. - if (I.mayLoad() && !isLoadFromGOTOrConstantPool(I) && + if (I.mayLoad() && !mayLoadFromGOTOrConstantPool(I) && !IsGuaranteedToExecute(I.getParent())) return false;