[llvm] r202985 - ARM: Correctly align arguments after a byval struct is passed on the stack

Oliver Stannard Oliver.Stannard at arm.com
Wed Mar 5 14:39:30 PST 2014


Thanks for fixing it, I'll make sure I build with Werror in the future.

Oliver
________________________________________
From: David Blaikie [dblaikie at gmail.com]
Sent: 05 March 2014 19:00
To: Oliver Stannard
Cc: llvm-commits at cs.uiuc.edu
Subject: Re: [llvm] r202985 - ARM: Correctly align arguments after a byval struct is passed on the stack

On Wed, Mar 5, 2014 at 7:25 AM, Oliver Stannard <oliver.stannard at arm.com> wrote:
> Author: olista01
> Date: Wed Mar  5 09:25:27 2014
> New Revision: 202985
>
> URL: http://llvm.org/viewvc/llvm-project?rev=202985&view=rev
> Log:
> ARM: Correctly align arguments after a byval struct is passed on the stack
>
>
> Added:
>     llvm/trunk/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll
> Modified:
>     llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
>     llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp
>     llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>     llvm/trunk/lib/Target/ARM/ARMISelLowering.h
>     llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp
>     llvm/trunk/test/CodeGen/ARM/2013-04-05-Small-ByVal-Structs-PR15293.ll
>     llvm/trunk/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll
>
> Modified: llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CallingConvLower.h?rev=202985&r1=202984&r2=202985&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/CallingConvLower.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/CallingConvLower.h Wed Mar  5 09:25:27 2014
> @@ -404,6 +404,11 @@ public:
>      ByValRegs.clear();
>    }
>
> +  // Rewind byval registers tracking info.
> +  void rewindByValRegsInfo() {
> +    InRegsParamsProceed = 0;
> +  }
> +
>    ParmContext getCallOrPrologue() const { return CallOrPrologue; }
>
>  private:
>
> Modified: llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp?rev=202985&r1=202984&r2=202985&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp Wed Mar  5 09:25:27 2014
> @@ -175,7 +175,7 @@ void ARMFrameLowering::emitPrologue(Mach
>    if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
>      return;
>
> -  // Allocate the vararg register save area. This is not counted in NumBytes.
> +  // Allocate the vararg register save area.
>    if (ArgRegsSaveSize) {
>      emitSPUpdate(isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
>                   MachineInstr::FrameSetup);
> @@ -188,13 +188,13 @@ void ARMFrameLowering::emitPrologue(Mach
>    }
>
>    if (!AFI->hasStackFrame()) {
> -    if (NumBytes != 0) {
> -      emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
> +    if (NumBytes - ArgRegsSaveSize != 0) {
> +      emitSPUpdate(isARM, MBB, MBBI, dl, TII, -(NumBytes - ArgRegsSaveSize),
>                     MachineInstr::FrameSetup);
>        MCSymbol *SPLabel = Context.CreateTempSymbol();
>        BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
>            .addSym(SPLabel);
> -      CFAOffset -= NumBytes;
> +      CFAOffset -= NumBytes - ArgRegsSaveSize;
>        MMI.addFrameInst(MCCFIInstruction::createDefCfaOffset(SPLabel,
>                                                              CFAOffset));
>      }
> @@ -246,12 +246,14 @@ void ARMFrameLowering::emitPrologue(Mach
>
>    // Determine starting offsets of spill areas.
>    bool HasFP = hasFP(MF);
> -  unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
> +  unsigned DPRCSOffset  = NumBytes - (ArgRegsSaveSize + GPRCS1Size
> +                                      + GPRCS2Size + DPRCSSize);
>    unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
>    unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
>    int FramePtrOffsetInPush = 0;
>    if (HasFP) {
> -    FramePtrOffsetInPush = MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size;
> +    FramePtrOffsetInPush = MFI->getObjectOffset(FramePtrSpillFI)
> +                           + GPRCS1Size + ArgRegsSaveSize;
>      AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
>                                  NumBytes);
>    }
> @@ -339,7 +341,7 @@ void ARMFrameLowering::emitPrologue(Mach
>        case ARM::LR:
>          MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel,
>             MRI->getDwarfRegNum(Reg, true),
> -           MFI->getObjectOffset(FI) - ArgRegsSaveSize));
> +           MFI->getObjectOffset(FI)));
>          break;
>        }
>      }
> @@ -390,7 +392,7 @@ void ARMFrameLowering::emitPrologue(Mach
>        case ARM::R12:
>          if (STI.isTargetMachO()) {
>            unsigned DwarfReg =  MRI->getDwarfRegNum(Reg, true);
> -          unsigned Offset = MFI->getObjectOffset(FI) - ArgRegsSaveSize;
> +          unsigned Offset = MFI->getObjectOffset(FI);
>            MMI.addFrameInst(
>                MCCFIInstruction::createOffset(SPLabel, DwarfReg, Offset));
>          }
> @@ -536,8 +538,8 @@ void ARMFrameLowering::emitEpilogue(Mach
>      return;
>
>    if (!AFI->hasStackFrame()) {
> -    if (NumBytes != 0)
> -      emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
> +    if (NumBytes - ArgRegsSaveSize != 0)
> +      emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes - ArgRegsSaveSize);
>    } else {
>      // Unwind MBBI to point to first LDR / VLDRD.
>      const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
> @@ -550,7 +552,8 @@ void ARMFrameLowering::emitEpilogue(Mach
>      }
>
>      // Move SP to start of FP callee save spill area.
> -    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
> +    NumBytes -= (ArgRegsSaveSize +
> +                 AFI->getGPRCalleeSavedArea1Size() +
>                   AFI->getGPRCalleeSavedArea2Size() +
>                   AFI->getDPRCalleeSavedAreaSize());
>
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=202985&r1=202984&r2=202985&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Mar  5 09:25:27 2014
> @@ -1826,22 +1826,6 @@ ARMTargetLowering::HandleByVal(
>            State->getCallOrPrologue() == Call) &&
>           "unhandled ParmContext");
>
> -  // For in-prologue parameters handling, we also introduce stack offset
> -  // for byval registers: see CallingConvLower.cpp, CCState::HandleByVal.
> -  // This behaviour outsides AAPCS rules (5.5 Parameters Passing) of how
> -  // NSAA should be evaluted (NSAA means "next stacked argument address").
> -  // So: NextStackOffset = NSAAOffset + SizeOfByValParamsStoredInRegs.
> -  // Then: NSAAOffset = NextStackOffset - SizeOfByValParamsStoredInRegs.
> -  unsigned NSAAOffset = State->getNextStackOffset();
> -  if (State->getCallOrPrologue() != Call) {
> -    for (unsigned i = 0, e = State->getInRegsParamsCount(); i != e; ++i) {
> -      unsigned RB, RE;
> -      State->getInRegsParamInfo(i, RB, RE);
> -      assert(NSAAOffset >= (RE-RB)*4 &&
> -             "Stack offset for byval regs doesn't introduced anymore?");
> -      NSAAOffset -= (RE-RB)*4;
> -    }
> -  }
>    if ((ARM::R0 <= reg) && (reg <= ARM::R3)) {
>      if (Subtarget->isAAPCS_ABI() && Align > 4) {
>        unsigned AlignInRegs = Align / 4;
> @@ -1856,6 +1840,7 @@ ARMTargetLowering::HandleByVal(
>        // all remained GPR regs. In that case we can't split parameter, we must
>        // send it to stack. We also must set NCRN to R4, so waste all
>        // remained registers.
> +      const unsigned NSAAOffset = State->getNextStackOffset();
>        if (Subtarget->isAAPCS_ABI() && NSAAOffset != 0 && size > excess) {
>          while (State->AllocateReg(GPRArgRegs, 4))
>            ;
> @@ -1875,18 +1860,14 @@ ARMTargetLowering::HandleByVal(
>        // allocate remained amount of registers we need.
>        for (unsigned i = reg+1; i != ByValRegEnd; ++i)
>          State->AllocateReg(GPRArgRegs, 4);
> -      // At a call site, a byval parameter that is split between
> -      // registers and memory needs its size truncated here.  In a
> -      // function prologue, such byval parameters are reassembled in
> -      // memory, and are not truncated.
> -      if (State->getCallOrPrologue() == Call) {
> -        // Make remained size equal to 0 in case, when
> -        // the whole structure may be stored into registers.
> -        if (size < excess)
> -          size = 0;
> -        else
> -          size -= excess;
> -      }
> +      // A byval parameter that is split between registers and memory needs its
> +      // size truncated here.
> +      // In the case where the entire structure fits in registers, we set the
> +      // size in memory to zero.
> +      if (size < excess)
> +        size = 0;
> +      else
> +        size -= excess;
>      }
>    }
>  }
> @@ -2794,7 +2775,9 @@ ARMTargetLowering::StoreByValRegs(CCStat
>                                    unsigned OffsetFromOrigArg,
>                                    unsigned ArgOffset,
>                                    unsigned ArgSize,
> -                                  bool ForceMutable) const {
> +                                  bool ForceMutable,
> +                                  unsigned ByValStoreOffset,
> +                                  unsigned TotalArgRegsSaveSize) const {
>
>    // Currently, two use-cases possible:
>    // Case #1. Non-var-args function, and we meet first byval parameter.
> @@ -2831,7 +2814,6 @@ ARMTargetLowering::StoreByValRegs(CCStat
>    // Note: once stack area for byval/varargs registers
>    // was initialized, it can't be initialized again.
>    if (ArgRegsSaveSize) {
> -
>      unsigned Padding = ArgRegsSaveSize - ArgRegsSize;
>
>      if (Padding) {
> @@ -2840,11 +2822,18 @@ ARMTargetLowering::StoreByValRegs(CCStat
>        AFI->setStoredByValParamsPadding(Padding);
>      }
>
> -    int FrameIndex = MFI->CreateFixedObject(
> -                      ArgRegsSaveSize,
> -                      Padding + ArgOffset,
> -                      false);
> +    int FrameIndex = MFI->CreateFixedObject(ArgRegsSaveSize,
> +                                            Padding +
> +                                              ByValStoreOffset -
> +                                              (int64_t)TotalArgRegsSaveSize,
> +                                            false);
>      SDValue FIN = DAG.getFrameIndex(FrameIndex, getPointerTy());
> +    if (Padding) {
> +       MFI->CreateFixedObject(Padding,
> +                              ArgOffset + ByValStoreOffset -
> +                                (int64_t)ArgRegsSaveSize,
> +                              false);
> +    }
>
>      SmallVector<SDValue, 4> MemOps;
>      for (unsigned i = 0; firstRegToSaveIndex < lastRegToSaveIndex;
> @@ -2872,10 +2861,16 @@ ARMTargetLowering::StoreByValRegs(CCStat
>        Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
>                            &MemOps[0], MemOps.size());
>      return FrameIndex;
> -  } else
> +  } else {
> +    if (ArgSize == 0) {
> +      // We cannot allocate a zero-byte object for the first variadic argument,
> +      // so just make up a size.
> +      ArgSize = 4;
> +    }
>      // This will point to the next argument passed via stack.
>      return MFI->CreateFixedObject(
> -        4, AFI->getStoredByValParamsPadding() + ArgOffset, !ForceMutable);
> +      ArgSize, ArgOffset, !ForceMutable);
> +  }
>  }
>
>  // Setup stack frame, the va_list pointer will start from.
> @@ -2883,6 +2878,7 @@ void
>  ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
>                                          SDLoc dl, SDValue &Chain,
>                                          unsigned ArgOffset,
> +                                        unsigned TotalArgRegsSaveSize,
>                                          bool ForceMutable) const {
>    MachineFunction &MF = DAG.getMachineFunction();
>    ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> @@ -2894,7 +2890,7 @@ ARMTargetLowering::VarArgStyleRegisters(
>    // argument passed via stack.
>    int FrameIndex =
>      StoreByValRegs(CCInfo, DAG, dl, Chain, 0, CCInfo.getInRegsParamsCount(),
> -                   0, ArgOffset, 0, ForceMutable);
> +                   0, ArgOffset, 0, ForceMutable, 0, TotalArgRegsSaveSize);
>
>    AFI->setVarArgsFrameIndex(FrameIndex);
>  }
> @@ -2931,6 +2927,51 @@ ARMTargetLowering::LowerFormalArguments(
>    // We also increase this value in case of varargs function.
>    AFI->setArgRegsSaveSize(0);
>
> +  unsigned ByValStoreOffset = 0;
> +  unsigned TotalArgRegsSaveSize = 0;
> +  unsigned ArgRegsSaveSizeMaxAlign = 4;
> +
> +  // Calculate the amount of stack space that we need to allocate to store
> +  // byval and variadic arguments that are passed in registers.
> +  // We need to know this before we allocate the first byval or variadic
> +  // argument, as they will be allocated a stack slot below the CFA (Canonical
> +  // Frame Address, the stack pointer at entry to the function).
> +  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
> +    CCValAssign &VA = ArgLocs[i];
> +    if (VA.isMemLoc()) {
> +      int index = VA.getValNo();
> +      if (index != lastInsIndex) {
> +        ISD::ArgFlagsTy Flags = Ins[index].Flags;
> +        if (Flags.isByVal()) {
> +          unsigned ExtraArgRegsSize;
> +          unsigned ExtraArgRegsSaveSize;
> +          computeRegArea(CCInfo, MF, CCInfo.getInRegsParamsProceed(),
> +                         Flags.getByValSize(),
> +                         ExtraArgRegsSize, ExtraArgRegsSaveSize);
> +
> +          TotalArgRegsSaveSize += ExtraArgRegsSaveSize;
> +          if (Flags.getByValAlign() > ArgRegsSaveSizeMaxAlign)
> +              ArgRegsSaveSizeMaxAlign = Flags.getByValAlign();
> +          CCInfo.nextInRegsParam();
> +        }
> +        lastInsIndex = index;
> +      }
> +    }
> +  }
> +  CCInfo.rewindByValRegsInfo();
> +  lastInsIndex = -1;
> +  if (isVarArg) {
> +    unsigned ExtraArgRegsSize;
> +    unsigned ExtraArgRegsSaveSize;
> +    computeRegArea(CCInfo, MF, CCInfo.getInRegsParamsCount(), 0,
> +                   ExtraArgRegsSize, ExtraArgRegsSaveSize);
> +    TotalArgRegsSaveSize += ExtraArgRegsSaveSize;
> +  }
> +  // If the arg regs save area contains N-byte aligned values, the
> +  // bottom of it must be at least N-byte aligned.
> +  TotalArgRegsSaveSize = RoundUpToAlignment(TotalArgRegsSaveSize, ArgRegsSaveSizeMaxAlign);
> +  TotalArgRegsSaveSize = std::min(TotalArgRegsSaveSize, 16U);
> +
>    for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
>      CCValAssign &VA = ArgLocs[i];
>      std::advance(CurOrigArg, Ins[VA.getValNo()].OrigArgIndex - CurArgIdx);
> @@ -3029,18 +3070,23 @@ ARMTargetLowering::LowerFormalArguments(
>            // a tail call.
>            if (Flags.isByVal()) {
>              unsigned CurByValIndex = CCInfo.getInRegsParamsProceed();
> +
> +            ByValStoreOffset = RoundUpToAlignment(ByValStoreOffset, Flags.getByValAlign());
>              int FrameIndex = StoreByValRegs(
>                  CCInfo, DAG, dl, Chain, CurOrigArg,
>                  CurByValIndex,
>                  Ins[VA.getValNo()].PartOffset,
>                  VA.getLocMemOffset(),
>                  Flags.getByValSize(),
> -                true /*force mutable frames*/);
> +                true /*force mutable frames*/,
> +                ByValStoreOffset,
> +                TotalArgRegsSaveSize);
> +            ByValStoreOffset += Flags.getByValSize();
> +            ByValStoreOffset = std::min(ByValStoreOffset, 16U);
>              InVals.push_back(DAG.getFrameIndex(FrameIndex, getPointerTy()));
>              CCInfo.nextInRegsParam();
>            } else {
> -            unsigned FIOffset = VA.getLocMemOffset() +
> -                                AFI->getStoredByValParamsPadding();
> +            unsigned FIOffset = VA.getLocMemOffset();
>              int FI = MFI->CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
>                                              FIOffset, true);
>
> @@ -3058,7 +3104,8 @@ ARMTargetLowering::LowerFormalArguments(
>    // varargs
>    if (isVarArg)
>      VarArgStyleRegisters(CCInfo, DAG, dl, Chain,
> -                         CCInfo.getNextStackOffset());
> +                         CCInfo.getNextStackOffset(),
> +                         TotalArgRegsSaveSize);
>
>    return Chain;
>  }
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=202985&r1=202984&r2=202985&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Wed Mar  5 09:25:27 2014
> @@ -492,11 +492,14 @@ namespace llvm {
>                         unsigned OffsetFromOrigArg,
>                         unsigned ArgOffset,
>                         unsigned ArgSize,
> -                       bool ForceMutable) const;
> +                       bool ForceMutable,
> +                       unsigned ByValStoreOffset,
> +                                          unsigned TotalArgRegsSaveSize) const;
>
>      void VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
>                                SDLoc dl, SDValue &Chain,
>                                unsigned ArgOffset,
> +                                                         unsigned TotalArgRegsSaveSize,
>                                bool ForceMutable = false) const;
>
>      void computeRegArea(CCState &CCInfo, MachineFunction &MF,
>
> Modified: llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp?rev=202985&r1=202984&r2=202985&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp Wed Mar  5 09:25:27 2014
> @@ -94,6 +94,8 @@ void Thumb1FrameLowering::emitPrologue(M
>    unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment();
>    unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align);
>    unsigned NumBytes = MFI->getStackSize();
> +  assert(NumBytes >= ArgRegsSaveSize &&
> +         "ArgRegsSaveSize is included in NumBytes");
>    const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
>    DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
>    unsigned FramePtr = RegInfo->getFrameRegister(MF);
> @@ -121,13 +123,13 @@ void Thumb1FrameLowering::emitPrologue(M
>    }
>
>    if (!AFI->hasStackFrame()) {
> -    if (NumBytes != 0) {
> -      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
> +    if (NumBytes - ArgRegsSaveSize != 0) {
> +      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -(NumBytes - ArgRegsSaveSize),
>                     MachineInstr::FrameSetup);
>        MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol();
>        BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
>            .addSym(SPLabel);
> -      CFAOffset -= NumBytes;
> +      CFAOffset -= NumBytes - ArgRegsSaveSize;
>        MMI.addFrameInst(
>            MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
>      }
> @@ -168,7 +170,7 @@ void Thumb1FrameLowering::emitPrologue(M
>    }
>
>    // Determine starting offsets of spill areas.
> -  unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
> +  unsigned DPRCSOffset  = NumBytes - ArgRegsSaveSize - (GPRCS1Size + GPRCS2Size + DPRCSSize);
>    unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
>    unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
>    bool HasFP = hasFP(MF);
> @@ -219,7 +221,7 @@ void Thumb1FrameLowering::emitPrologue(M
>      case ARM::LR:
>        MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel,
>           MRI->getDwarfRegNum(Reg, true),
> -         MFI->getObjectOffset(FI) - ArgRegsSaveSize));
> +         MFI->getObjectOffset(FI)));
>        break;
>      }
>    }
> @@ -227,7 +229,8 @@ void Thumb1FrameLowering::emitPrologue(M
>
>    // Adjust FP so it point to the stack slot that contains the previous FP.
>    if (HasFP) {
> -    FramePtrOffsetInBlock += MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size;
> +    FramePtrOffsetInBlock += MFI->getObjectOffset(FramePtrSpillFI)
> +                                    + GPRCS1Size + ArgRegsSaveSize;
>      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
>        .addReg(ARM::SP).addImm(FramePtrOffsetInBlock / 4)
>        .setMIFlags(MachineInstr::FrameSetup));
> @@ -324,12 +327,14 @@ void Thumb1FrameLowering::emitEpilogue(M
>    unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment();
>    unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align);
>    int NumBytes = (int)MFI->getStackSize();
> +  assert(NumBytes >= ArgRegsSaveSize &&

This breaks the Clang -Werror build. I fixed it with a cast in r202992.

> +         "ArgRegsSaveSize is included in NumBytes");
>    const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs();
>    unsigned FramePtr = RegInfo->getFrameRegister(MF);
>
>    if (!AFI->hasStackFrame()) {
> -    if (NumBytes != 0)
> -      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes);
> +    if (NumBytes - ArgRegsSaveSize != 0)
> +      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes - ArgRegsSaveSize);
>    } else {
>      // Unwind MBBI to point to first LDR / VLDRD.
>      if (MBBI != MBB.begin()) {
> @@ -343,7 +348,8 @@ void Thumb1FrameLowering::emitEpilogue(M
>      // Move SP to start of FP callee save spill area.
>      NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
>                   AFI->getGPRCalleeSavedArea2Size() +
> -                 AFI->getDPRCalleeSavedAreaSize());
> +                 AFI->getDPRCalleeSavedAreaSize() +
> +                 ArgRegsSaveSize);
>
>      if (AFI->shouldRestoreSPFromFP()) {
>        NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
>
> Modified: llvm/trunk/test/CodeGen/ARM/2013-04-05-Small-ByVal-Structs-PR15293.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2013-04-05-Small-ByVal-Structs-PR15293.ll?rev=202985&r1=202984&r2=202985&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/2013-04-05-Small-ByVal-Structs-PR15293.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/2013-04-05-Small-ByVal-Structs-PR15293.ll Wed Mar  5 09:25:27 2014
> @@ -4,8 +4,8 @@
>  ;CHECK-LABEL: foo:
>  ;CHECK:        sub     sp, sp, #8
>  ;CHECK:        push    {r11, lr}
> -;CHECK:        str     r0, [sp, #8]
> -;CHECK:        add     r0, sp, #8
> +;CHECK:        str     r0, [sp, #12]
> +;CHECK:        add     r0, sp, #12
>  ;CHECK:        bl      fooUseParam
>  ;CHECK:        pop     {r11, lr}
>  ;CHECK:        add     sp, sp, #8
>
> Modified: llvm/trunk/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll?rev=202985&r1=202984&r2=202985&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll Wed Mar  5 09:25:27 2014
> @@ -23,9 +23,9 @@ define void @foo(double %vfp0,     ; -->
>  entry:
>    ;CHECK: sub sp, #8
>    ;CHECK: push.w {r11, lr}
> -  ;CHECK: add r0, sp, #16
> -  ;CHECK: str r2, [sp, #20]
> -  ;CHECK: str r1, [sp, #16]
> +  ;CHECK: add r0, sp, #8
> +  ;CHECK: str r2, [sp, #12]
> +  ;CHECK: str r1, [sp, #8]
>    ;CHECK: bl  fooUseStruct
>    call void @fooUseStruct(%st_t* %p1)
>    ret void
>
> Added: llvm/trunk/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll?rev=202985&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll Wed Mar  5 09:25:27 2014
> @@ -0,0 +1,114 @@
> +; RUN: llc -mtriple=arm-linux-gnueabihf < %s | FileCheck %s
> +
> +%struct4bytes = type { i32 }
> +%struct8bytes8align = type { i64 }
> +%struct12bytes = type { i32, i32, i32 }
> +
> +declare void @useIntPtr(%struct4bytes*)
> +declare void @useLong(i64)
> +declare void @usePtr(%struct8bytes8align*)
> +
> +; a -> r0
> +; b -> r1..r3
> +; c -> sp+0..sp+7
> +define void @foo1(i32 %a, %struct12bytes* byval %b, i64 %c) {
> +; CHECK-LABEL: foo1
> +; CHECK: sub  sp, sp, #16
> +; CHECK: push  {r11, lr}
> +; CHECK: add  [[SCRATCH:r[0-9]+]], sp, #12
> +; CHECK: stm  [[SCRATCH]], {r1, r2, r3}
> +; CHECK: ldr  r0, [sp, #24]
> +; CHECK: ldr  r1, [sp, #28]
> +; CHECK: bl  useLong
> +; CHECK: pop  {r11, lr}
> +; CHECK: add  sp, sp, #16
> +
> +  tail call void @useLong(i64 %c)
> +  ret void
> +}
> +
> +; a -> r0
> +; b -> r2..r3
> +define void @foo2(i32 %a, %struct8bytes8align* byval %b) {
> +; CHECK-LABEL: foo2
> +; CHECK: sub  sp, sp, #8
> +; CHECK: push  {r11, lr}
> +; CHECK: add  r0, sp, #8
> +; CHECK: str  r3, [sp, #12]
> +; CHECK: str  r2, [sp, #8]
> +; CHECK: bl   usePtr
> +; CHECK: pop  {r11, lr}
> +; CHECK: add  sp, sp, #8
> +
> +  tail call void @usePtr(%struct8bytes8align* %b)
> +  ret void
> +}
> +
> +; a -> r0..r1
> +; b -> r2
> +define void @foo3(%struct8bytes8align* byval %a, %struct4bytes* byval %b) {
> +; CHECK-LABEL: foo3
> +; CHECK: sub  sp, sp, #16
> +; CHECK: push  {r11, lr}
> +; CHECK: add  [[SCRATCH:r[0-9]+]], sp, #8
> +; CHECK: stm  [[SCRATCH]], {r0, r1, r2}
> +; CHECK: add  r0, sp, #8
> +; CHECK: bl   usePtr
> +; CHECK: pop  {r11, lr}
> +; CHECK: add  sp, sp, #16
> +
> +  tail call void @usePtr(%struct8bytes8align* %a)
> +  ret void
> +}
> +
> +; a -> r0
> +; b -> r2..r3
> +define void @foo4(%struct4bytes* byval %a, %struct8bytes8align* byval %b) {
> +; CHECK-LABEL: foo4
> +; CHECK: sub     sp, sp, #16
> +; CHECK: push    {r11, lr}
> +; CHECK: str     r0, [sp, #8]
> +; CHECK: add     r0, sp, #16
> +; CHECK: str     r3, [sp, #20]
> +; CHECK: str     r2, [sp, #16]
> +; CHECK: bl      usePtr
> +; CHECK: pop     {r11, lr}
> +; CHECK: add     sp, sp, #16
> +; CHECK: mov     pc, lr
> +
> +  tail call void @usePtr(%struct8bytes8align* %b)
> +  ret void
> +}
> +
> +; a -> r0..r1
> +; b -> r2
> +; c -> r3
> +define void @foo5(%struct8bytes8align* byval %a, %struct4bytes* byval %b, %struct4bytes* byval %c) {
> +; CHECK-LABEL: foo5
> +; CHECK: sub     sp, sp, #16
> +; CHECK: push    {r11, lr}
> +; CHECK: add     [[SCRATCH:r[0-9]+]], sp, #8
> +; CHECK: stm     [[SCRATCH]], {r0, r1, r2, r3}
> +; CHECK: add     r0, sp, #8
> +; CHECK: bl      usePtr
> +; CHECK: pop     {r11, lr}
> +; CHECK: add     sp, sp, #16
> +; CHECK: mov     pc, lr
> +
> +  tail call void @usePtr(%struct8bytes8align* %a)
> +  ret void
> +}
> +
> +; a..c -> r0..r2
> +; d -> sp+0..sp+7
> +define void @foo6(i32 %a, i32 %b, i32 %c, %struct8bytes8align* byval %d) {
> +; CHECK-LABEL: foo6
> +; CHECK: push {r11, lr}
> +; CHECK: add  r0, sp, #8
> +; CHECK: bl   usePtr
> +; CHECK: pop  {r11, lr}
> +; CHECK: mov  pc, lr
> +
> +  tail call void @usePtr(%struct8bytes8align* %d)
> +  ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium.  Thank you.

ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No:  2557590
ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No:  2548782





More information about the llvm-commits mailing list