Index: include/llvm/CodeGen/FastISel.h =================================================================== --- include/llvm/CodeGen/FastISel.h +++ include/llvm/CodeGen/FastISel.h @@ -226,6 +226,9 @@ /// be appended, and clear the local CSE map. void startNewBlock(); + /// \brief Performs post-processing of complete basic block. + void finishNewBlock(); + /// \brief Return current debug location information. DebugLoc getCurDebugLoc() const { return DbgLoc; } @@ -569,6 +572,10 @@ bool lowerCallOperands(const CallInst *CI, unsigned ArgIdx, unsigned NumArgs, const Value *Callee, bool ForceRetVoidTy, CallLoweringInfo &CLI); + + /// \brief Copies first non-empty debug location from list of instructions as + /// starting location for current block. + void fixupLocalValueLocations(); }; } // end namespace llvm Index: lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/FastISel.cpp +++ lib/CodeGen/SelectionDAG/FastISel.cpp @@ -104,6 +104,35 @@ LastLocalValue = EmitStartPt; } +void FastISel::finishNewBlock() { + fixupLocalValueLocations(); +} + +void FastISel::fixupLocalValueLocations() { + // Nothing to do if we didn't emit any local values. + if (LocalValueMap.empty()) + return; + + // Skip entry basic block to do not move "prologue_end" location above stack + // adjustment. + if (FuncInfo.MBB == FuncInfo.MBBMap[&FuncInfo.Fn->getEntryBlock()]) + return; + + // Find first local value by skipping past any EH_LABELs, which go before + // local values. + MachineBasicBlock::iterator FirstLocalValue = FuncInfo.MBB->begin(); + while (FirstLocalValue->getOpcode() == TargetOpcode::EH_LABEL) + ++FirstLocalValue; + + // Find first instruction with non-null debug location. + MachineBasicBlock::iterator InstWithLoc = FuncInfo.InsertPt; + while (InstWithLoc != FuncInfo.MBB->end() && !InstWithLoc->getDebugLoc()) + ++InstWithLoc; + + if (InstWithLoc != FuncInfo.MBB->end()) + FirstLocalValue->setDebugLoc(InstWithLoc->getDebugLoc()); +} + bool FastISel::lowerArguments() { if (!FuncInfo.CanLowerReturn) // Fallback to SDISel argument lowering code to deal with sret pointer Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1312,6 +1312,8 @@ } FinishBasicBlock(); + if (FastIS) + FastIS->finishNewBlock(); FuncInfo->PHINodesToUpdate.clear(); } Index: test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll =================================================================== --- test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll +++ test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll @@ -1,4 +1,5 @@ ; RUN: llc -filetype=asm -asm-verbose=0 < %s | FileCheck %s +; RUN: llc -fast-isel -filetype=asm -asm-verbose=0 < %s | FileCheck %s ; int main() ; {