ARMBaseRegisterInfo::estimateRSStackSizeLimit() could return prematurely with a

too large limit.

The function would return immediately when finding an addrmode 3/5 instruction.
It needs to keep scanning in case there is an addrmode 6 instruction which drops
the limit to 0.

A test case is very difficult to produce because it will only fail when the
scavenger is used.

rdar://problem/7894847

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103995 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2010-05-17 23:29:23 +00:00
parent c6dcce3ba5
commit 535af4a320

View File

@ -724,24 +724,25 @@ ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
I != E; ++I) {
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
if (!I->getOperand(i).isFI()) continue;
const TargetInstrDesc &Desc = TII.get(I->getOpcode());
unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
if (AddrMode == ARMII::AddrMode3 ||
AddrMode == ARMII::AddrModeT2_i8)
return (1 << 8) - 1;
if (AddrMode == ARMII::AddrMode5 ||
AddrMode == ARMII::AddrModeT2_i8s4)
switch (I->getDesc().TSFlags & ARMII::AddrModeMask) {
case ARMII::AddrMode3:
case ARMII::AddrModeT2_i8:
Limit = std::min(Limit, (1U << 8) - 1);
break;
case ARMII::AddrMode5:
case ARMII::AddrModeT2_i8s4:
Limit = std::min(Limit, ((1U << 8) - 1) * 4);
if (AddrMode == ARMII::AddrModeT2_i12 && hasFP(MF))
// When the stack offset is negative, we will end up using
// the i8 instructions instead.
return (1 << 8) - 1;
if (AddrMode == ARMII::AddrMode6)
break;
case ARMII::AddrModeT2_i12:
if (hasFP(MF)) Limit = std::min(Limit, (1U << 8) - 1);
break;
case ARMII::AddrMode6:
// Addressing mode 6 (load/store) instructions can't encode an
// immediate offset for stack references.
return 0;
default:
break;
}
break; // At most one FI per instruction
}
}