diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-05-17 23:29:23 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-05-17 23:29:23 +0000 |
commit | 535af4a320ba169342c87433841dc64fbdcd72b3 (patch) | |
tree | 2e50db1f34b19ecb82c10c77780efd98172084df | |
parent | c6dcce3ba5bd22325ecf1dbdfddf8136b50d4838 (diff) |
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
-rw-r--r-- | lib/Target/ARM/ARMBaseRegisterInfo.cpp | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 9dcdce05e4..ed1c0cf248 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -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 } } |