Selecting the address from a very long chain of GEPs can blow the stack.

The recursive nature of the address selection code can cause the stack to
explode if there is a long chain of GEPs. Convert the recursive bit into a
iterative method to avoid this.

<rdar://problem/12445434>

llvm-svn: 191252
This commit is contained in:
Bill Wendling 2013-09-24 00:13:08 +00:00
parent 25f007f054
commit 585a901a12
2 changed files with 25619 additions and 3 deletions

View File

@ -347,6 +347,7 @@ bool X86FastISel::X86FastEmitExtend(ISD::NodeType Opc, EVT DstVT,
/// X86SelectAddress - Attempt to fill in an address from the given value. /// X86SelectAddress - Attempt to fill in an address from the given value.
/// ///
bool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) { bool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) {
redo_gep:
const User *U = NULL; const User *U = NULL;
unsigned Opcode = Instruction::UserOp1; unsigned Opcode = Instruction::UserOp1;
if (const Instruction *I = dyn_cast<Instruction>(V)) { if (const Instruction *I = dyn_cast<Instruction>(V)) {
@ -469,16 +470,24 @@ bool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) {
goto unsupported_gep; goto unsupported_gep;
} }
} }
// Check for displacement overflow. // Check for displacement overflow.
if (!isInt<32>(Disp)) if (!isInt<32>(Disp))
break; break;
// Ok, the GEP indices were covered by constant-offset and scaled-index
// addressing. Update the address state and move on to examining the base.
AM.IndexReg = IndexReg; AM.IndexReg = IndexReg;
AM.Scale = Scale; AM.Scale = Scale;
AM.Disp = (uint32_t)Disp; AM.Disp = (uint32_t)Disp;
if (X86SelectAddress(U->getOperand(0), AM))
if (const GetElementPtrInst *GEP =
dyn_cast<GetElementPtrInst>(U->getOperand(0))) {
// Ok, the GEP indices were covered by constant-offset and scaled-index
// addressing. Update the address state and move on to examining the base.
V = GEP;
goto redo_gep;
} else if (X86SelectAddress(U->getOperand(0), AM)) {
return true; return true;
}
// If we couldn't merge the gep value into this addr mode, revert back to // If we couldn't merge the gep value into this addr mode, revert back to
// our address and just match the value instead of completely failing. // our address and just match the value instead of completely failing.

File diff suppressed because it is too large Load Diff