Index: llvm/trunk/include/llvm/CodeGen/MachineInstr.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h @@ -1110,12 +1110,14 @@ /// ordered or volatile memory references. bool hasOrderedMemoryRef() const; - /// Return true if this instruction is loading from a - /// location whose value is invariant across the function. For example, - /// loading a value from the constant pool or from the argument area of - /// a function if it does not change. This should only return true of *all* - /// loads the instruction does are invariant (if it does multiple loads). - bool isInvariantLoad(AliasAnalysis *AA) const; + /// Return true if this load instruction never traps and points to a memory + /// location whose value doesn't change during the execution of this function. + /// + /// Examples include loading a value from the constant pool or from the + /// argument area of a function (if it does not change). If the instruction + /// does multiple loads, this returns true only if all of the loads are + /// dereferenceable and invariant. + bool isDereferenceableInvariantLoad(AliasAnalysis *AA) const; /// If the specified instruction is a PHI that always merges together the /// same virtual register, return the register, otherwise return 0. Index: llvm/trunk/lib/CodeGen/MachineCSE.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineCSE.cpp +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp @@ -346,7 +346,7 @@ // Okay, this instruction does a load. As a refinement, we allow the target // to decide whether the loaded value is actually a constant. If so, we can // actually use it as a load. - if (!MI->isInvariantLoad(AA)) + if (!MI->isDereferenceableInvariantLoad(AA)) // FIXME: we should be able to hoist loads with no other side effects if // there are no other instructions which can change memory in this loop. // This is a trivial form of alias analysis. Index: llvm/trunk/lib/CodeGen/MachineInstr.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp @@ -1531,7 +1531,7 @@ // destination. The check for isInvariantLoad gives the targe the chance to // classify the load as always returning a constant, e.g. a constant pool // load. - if (mayLoad() && !isInvariantLoad(AA)) + if (mayLoad() && !isDereferenceableInvariantLoad(AA)) // Otherwise, this is a real load. If there is a store between the load and // end of block, we can't move it. return !SawStore; @@ -1562,12 +1562,10 @@ }); } -/// isInvariantLoad - Return true if this instruction is loading from a -/// location whose value is invariant across the function. For example, -/// loading a value from the constant pool or from the argument area -/// of a function if it does not change. This should only return true of -/// *all* loads the instruction does are invariant (if it does multiple loads). -bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const { +/// isDereferenceableInvariantLoad - Return true if this instruction will never +/// trap and is loading from a location whose value is invariant across a run of +/// this function. +bool MachineInstr::isDereferenceableInvariantLoad(AliasAnalysis *AA) const { // If the instruction doesn't load at all, it isn't an invariant load. if (!mayLoad()) return false; Index: llvm/trunk/lib/CodeGen/MachineLICM.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp @@ -1138,7 +1138,8 @@ // High register pressure situation, only hoist if the instruction is going // to be remat'ed. - if (!TII->isTriviallyReMaterializable(MI, AA) && !MI.isInvariantLoad(AA)) { + if (!TII->isTriviallyReMaterializable(MI, AA) && + !MI.isDereferenceableInvariantLoad(AA)) { DEBUG(dbgs() << "Can't remat / high reg-pressure: " << MI); return false; } @@ -1157,7 +1158,7 @@ // If not, we may be able to unfold a load and hoist that. // First test whether the instruction is loading from an amenable // memory location. - if (!MI->isInvariantLoad(AA)) + if (!MI->isDereferenceableInvariantLoad(AA)) return nullptr; // Next determine the register class for a temporary register. Index: llvm/trunk/lib/CodeGen/MachinePipeliner.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachinePipeliner.cpp +++ llvm/trunk/lib/CodeGen/MachinePipeliner.cpp @@ -997,7 +997,7 @@ static bool isDependenceBarrier(MachineInstr &MI, AliasAnalysis *AA) { return MI.isCall() || MI.hasUnmodeledSideEffects() || (MI.hasOrderedMemoryRef() && - (!MI.mayLoad() || !MI.isInvariantLoad(AA))); + (!MI.mayLoad() || !MI.isDereferenceableInvariantLoad(AA))); } /// Return the underlying objects for the memory references of an instruction. Index: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp =================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -554,7 +554,7 @@ /// (like a call or something with unmodeled side effects). static inline bool isGlobalMemoryObject(AliasAnalysis *AA, MachineInstr *MI) { return MI->isCall() || MI->hasUnmodeledSideEffects() || - (MI->hasOrderedMemoryRef() && !MI->isInvariantLoad(AA)); + (MI->hasOrderedMemoryRef() && !MI->isDereferenceableInvariantLoad(AA)); } /// This returns true if the two MIs need a chain edge between them. @@ -1023,7 +1023,8 @@ } // If it's not a store or a variant load, we're done. - if (!MI.mayStore() && !(MI.mayLoad() && !MI.isInvariantLoad(AA))) + if (!MI.mayStore() && + !(MI.mayLoad() && !MI.isDereferenceableInvariantLoad(AA))) continue; // Always add dependecy edge to BarrierChain if present. Index: llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp =================================================================== --- llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp +++ llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp @@ -866,7 +866,7 @@ return false; // Avoid instructions which load from potentially varying memory. - if (MI.mayLoad() && !MI.isInvariantLoad(AA)) + if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad(AA)) return false; // If any of the registers accessed are non-constant, conservatively assume Index: llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp =================================================================== --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp @@ -130,7 +130,7 @@ return; // Check for loads. - if (MI.mayLoad() && !MI.isInvariantLoad(&AA)) + if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad(&AA)) Read = true; // Check for stores. Index: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp @@ -2654,7 +2654,7 @@ MI.getOperand(1 + X86::AddrScaleAmt).isImm() && MI.getOperand(1 + X86::AddrIndexReg).isReg() && MI.getOperand(1 + X86::AddrIndexReg).getReg() == 0 && - MI.isInvariantLoad(AA)) { + MI.isDereferenceableInvariantLoad(AA)) { unsigned BaseReg = MI.getOperand(1 + X86::AddrBaseReg).getReg(); if (BaseReg == 0 || BaseReg == X86::RIP) return true;