diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index ceb61300ae1..05ccf04ec76 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -644,7 +644,7 @@ public: /// materializeFrameBaseRegister - Insert defining instruction(s) for /// BaseReg to be a pointer to FrameIdx before insertion point I. - virtual void materializeFrameBaseRegister(MachineBasicBlock::iterator I, + virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB, unsigned BaseReg, int FrameIdx, int64_t Offset) const { assert(0 && "materializeFrameBaseRegister does not exist on this target"); diff --git a/lib/CodeGen/LocalStackSlotAllocation.cpp b/lib/CodeGen/LocalStackSlotAllocation.cpp index 7e366f0ceec..38a69825534 100644 --- a/lib/CodeGen/LocalStackSlotAllocation.cpp +++ b/lib/CodeGen/LocalStackSlotAllocation.cpp @@ -230,24 +230,25 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) { const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); bool StackGrowsDown = TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; - MachineBasicBlock::iterator InsertionPt = Fn.begin()->begin(); // Collect all of the instructions in the block that reference // a frame index. Also store the frame index referenced to ease later // lookup. (For any insn that has more than one FI reference, we arbitrarily // choose the first one). SmallVector FrameReferenceInsns; - // A base register definition is a register+offset pair. - SmallVector, 8> BaseRegisters; + // A base register definition is a register + offset pair. + SmallVector, 8> BaseRegisters; for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { MachineInstr *MI = I; + // Debug value instructions can't be out of range, so they don't need // any updates. if (MI->isDebugValue()) continue; + // For now, allocate the base register(s) within the basic block // where they're used, and don't try to keep them around outside // of that. It may be beneficial to try sharing them more broadly @@ -268,11 +269,13 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) { } } } + // Sort the frame references by local offset array_pod_sort(FrameReferenceInsns.begin(), FrameReferenceInsns.end()); + MachineBasicBlock *Entry = Fn.begin(); - // Loop throught the frame references and allocate for them as necessary + // Loop through the frame references and allocate for them as necessary. for (int ref = 0, e = FrameReferenceInsns.size(); ref < e ; ++ref) { MachineBasicBlock::iterator I = FrameReferenceInsns[ref].getMachineInstr(); @@ -321,10 +324,12 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) { DEBUG(dbgs() << " Materializing base register " << BaseReg << " at frame local offset " << LocalOffsets[FrameIdx] + InstrOffset << "\n"); + // Tell the target to insert the instruction to initialize // the base register. - TRI->materializeFrameBaseRegister(InsertionPt, BaseReg, - FrameIdx, InstrOffset); + // MachineBasicBlock::iterator InsertionPt = Entry->begin(); + TRI->materializeFrameBaseRegister(Entry, BaseReg, FrameIdx, + InstrOffset); // The base register already includes any offset specified // by the instruction, so account for that so it doesn't get diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index bdecaca37d0..9928105d214 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -1029,19 +1029,25 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { return true; } -/// materializeFrameBaseRegister - Insert defining instruction(s) for -/// BaseReg to be a pointer to FrameIdx before insertion point I. +/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to +/// be a pointer to FrameIdx at the beginning of the basic block. void ARMBaseRegisterInfo:: -materializeFrameBaseRegister(MachineBasicBlock::iterator I, unsigned BaseReg, - int FrameIdx, int64_t Offset) const { - ARMFunctionInfo *AFI = - I->getParent()->getParent()->getInfo(); +materializeFrameBaseRegister(MachineBasicBlock *MBB, + unsigned BaseReg, int FrameIdx, + int64_t Offset) const { + ARMFunctionInfo *AFI = MBB->getParent()->getInfo(); unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : (AFI->isThumb1OnlyFunction() ? ARM::tADDrSPi : ARM::t2ADDri); + MachineBasicBlock::iterator Ins = MBB->begin(); + DebugLoc DL; // Defaults to "unknown" + if (Ins != MBB->end()) + DL = Ins->getDebugLoc(); + MachineInstrBuilder MIB = - BuildMI(*I->getParent(), I, I->getDebugLoc(), TII.get(ADDriOpc), BaseReg) + BuildMI(*MBB, Ins, DL, TII.get(ADDriOpc), BaseReg) .addFrameIndex(FrameIdx).addImm(Offset); + if (!AFI->isThumb1OnlyFunction()) AddDefaultCC(AddDefaultPred(MIB)); } diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index 23a466fad95..ba6bd2b3208 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -145,7 +145,7 @@ public: bool needsStackRealignment(const MachineFunction &MF) const; int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const; bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const; - void materializeFrameBaseRegister(MachineBasicBlock::iterator I, + void materializeFrameBaseRegister(MachineBasicBlock *MBB, unsigned BaseReg, int FrameIdx, int64_t Offset) const; void resolveFrameIndex(MachineBasicBlock::iterator I, diff --git a/test/CodeGen/ARM/2010-12-17-LocalStackSlotCrash.ll b/test/CodeGen/ARM/2010-12-17-LocalStackSlotCrash.ll new file mode 100644 index 00000000000..a2f50b587b2 --- /dev/null +++ b/test/CodeGen/ARM/2010-12-17-LocalStackSlotCrash.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=armv6-apple-darwin10 +; +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:64-n32" +target triple = "armv6-apple-darwin10" + +define void @func() nounwind optsize { +entry: + %buf = alloca [8096 x i8], align 1 + br label %bb + +bb: + %p.2 = getelementptr [8096 x i8]* %buf, i32 0, i32 0 + store i8 undef, i8* %p.2, align 1 + ret void +}