[Hexagon] Handle cases when the aligned stack pointer is missing
llvm-svn: 306288
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index f0b7f58..2b0ceaa 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -1051,10 +1051,26 @@
bool HasExtraAlign = HRI.needsStackRealignment(MF);
bool NoOpt = MF.getTarget().getOptLevel() == CodeGenOpt::None;
+ unsigned FrameSize = MFI.getStackSize();
unsigned SP = HRI.getStackRegister(), FP = HRI.getFrameRegister();
auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
unsigned AP = HMFI.getStackAlignBasePhysReg();
- unsigned FrameSize = MFI.getStackSize();
+ // It may happen that AP will be absent even HasAlloca && HasExtraAlign
+ // is true. HasExtraAlign may be set because of vector spills, without
+ // aligned locals or aligned outgoing function arguments. Since vector
+ // spills will ultimately be "unaligned", it is safe to use FP as the
+ // base register.
+ // In fact, in such a scenario the stack is actually not required to be
+ // aligned, although it may end up being aligned anyway, since this
+ // particular case is not easily detectable. The alignment will be
+ // unnecessary, but not incorrect.
+ // Unfortunately there is no quick way to verify that the above is
+ // indeed the case (and that it's not a result of an error), so just
+ // assume that missing AP will be replaced by FP.
+ // (A better fix would be to rematerialize AP from FP and always align
+ // vector spills.)
+ if (AP == 0)
+ AP = FP;
bool UseFP = false, UseAP = false; // Default: use SP (except at -O0).
// Use FP at -O0, except when there are objects with extra alignment.
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index f43101f..fec2dc5 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -94,10 +94,6 @@
///
/// Constants for Hexagon instructions.
///
-const int Hexagon_MEMV_OFFSET_MAX_128B = 896; // #s4: -8*128...7*128
-const int Hexagon_MEMV_OFFSET_MIN_128B = -1024; // #s4
-const int Hexagon_MEMV_OFFSET_MAX = 448; // #s4: -8*64...7*64
-const int Hexagon_MEMV_OFFSET_MIN = -512; // #s4
const int Hexagon_MEMW_OFFSET_MAX = 4095;
const int Hexagon_MEMW_OFFSET_MIN = -4096;
const int Hexagon_MEMD_OFFSET_MAX = 8191;
@@ -2443,8 +2439,7 @@
case Hexagon::V6_vS32b_ai:
case Hexagon::V6_vL32Ub_ai:
case Hexagon::V6_vS32Ub_ai:
- return (Offset >= Hexagon_MEMV_OFFSET_MIN) &&
- (Offset <= Hexagon_MEMV_OFFSET_MAX);
+ return isShiftedInt<4,6>(Offset);
case Hexagon::PS_vstorerq_ai_128B:
case Hexagon::PS_vstorerw_ai_128B:
@@ -2454,8 +2449,7 @@
case Hexagon::V6_vS32b_ai_128B:
case Hexagon::V6_vL32Ub_ai_128B:
case Hexagon::V6_vS32Ub_ai_128B:
- return (Offset >= Hexagon_MEMV_OFFSET_MIN_128B) &&
- (Offset <= Hexagon_MEMV_OFFSET_MAX_128B);
+ return isShiftedInt<4,7>(Offset);
case Hexagon::J2_loop0i:
case Hexagon::J2_loop1i: