diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h --- a/llvm/include/llvm/CodeGen/CallingConvLower.h +++ b/llvm/include/llvm/CodeGen/CallingConvLower.h @@ -461,9 +461,9 @@ // HandleByVal - Allocate a stack slot large enough to pass an argument by // value. The size and alignment information of the argument is encoded in its // parameter attribute. - void HandleByVal(unsigned ValNo, MVT ValVT, - MVT LocVT, CCValAssign::LocInfo LocInfo, - int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); + void HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, int MinSize, Align MinAlign, + ISD::ArgFlagsTy ArgFlags); // Returns count of byval arguments that are to be stored (even partly) // in registers. diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -3837,7 +3837,7 @@ } /// Target-specific cleanup for formal ByVal parameters. - virtual void HandleByVal(CCState *, unsigned &, unsigned) const {} + virtual void HandleByVal(CCState *, unsigned &, Align) const {} /// This hook should be implemented to check whether the return values /// described by the Outs array can fit into the return registers. If false diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp --- a/llvm/lib/CodeGen/CallingConvLower.cpp +++ b/llvm/lib/CodeGen/CallingConvLower.cpp @@ -42,8 +42,7 @@ /// its parameter attribute. void CCState::HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, int MinSize, - int MinAlignment, ISD::ArgFlagsTy ArgFlags) { - Align MinAlign(MinAlignment); + Align MinAlign, ISD::ArgFlagsTy ArgFlags) { Align Alignment = ArgFlags.getNonZeroByValAlign(); unsigned Size = ArgFlags.getByValSize(); if (MinSize > (int)Size) @@ -51,8 +50,7 @@ if (MinAlign > Alignment) Alignment = MinAlign; ensureMaxAlignment(Alignment); - MF.getSubtarget().getTargetLowering()->HandleByVal(this, Size, - Alignment.value()); + MF.getSubtarget().getTargetLowering()->HandleByVal(this, Size, Alignment); Size = unsigned(alignTo(Size, MinAlign)); unsigned Offset = AllocateStack(Size, Alignment.value()); addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -826,7 +826,7 @@ SmallVectorImpl &InVals) const override; /// HandleByVal - Target-specific cleanup for ByVal support. - void HandleByVal(CCState *, unsigned &, unsigned) const override; + void HandleByVal(CCState *, unsigned &, Align) const override; /// IsEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. Targets which want to do tail call diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -2563,15 +2563,15 @@ /// and then confiscate the rest of the parameter registers to insure /// this. void ARMTargetLowering::HandleByVal(CCState *State, unsigned &Size, - unsigned Align) const { + Align Alignment) const { // Byval (as with any stack) slots are always at least 4 byte aligned. - Align = std::max(Align, 4U); + Alignment = std::max(Alignment, Align(4)); unsigned Reg = State->AllocateReg(GPRArgRegs); if (!Reg) return; - unsigned AlignInRegs = Align / 4; + unsigned AlignInRegs = Alignment.value() / 4; unsigned Waste = (ARM::R4 - Reg) % AlignInRegs; for (unsigned i = 0; i < Waste; ++i) Reg = State->AllocateReg(GPRArgRegs); diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -514,7 +514,7 @@ // Handle byval arguments if (ArgFlags.isByVal()) { - State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, 2, ArgFlags); + State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, Align(2), ArgFlags); continue; } diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -346,7 +346,7 @@ void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override; - void HandleByVal(CCState *, unsigned &, unsigned) const override; + void HandleByVal(CCState *, unsigned &, Align) const override; Register getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const override; diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -4522,12 +4522,12 @@ } void MipsTargetLowering::HandleByVal(CCState *State, unsigned &Size, - unsigned Align) const { + Align Alignment) const { const TargetFrameLowering *TFL = Subtarget.getFrameLowering(); assert(Size && "Byval argument's size shouldn't be 0."); - Align = std::min(Align, TFL->getStackAlignment()); + Alignment = std::min(Alignment, TFL->getStackAlign()); unsigned FirstReg = 0; unsigned NumRegs = 0; @@ -4541,17 +4541,17 @@ // We used to check the size as well but we can't do that anymore since // CCState::HandleByVal() rounds up the size after calling this function. - assert(!(Align % RegSizeInBytes) && - "Byval argument's alignment should be a multiple of" - "RegSizeInBytes."); + assert( + Alignment >= Align(RegSizeInBytes) && + "Byval argument's alignment should be a multiple of RegSizeInBytes."); FirstReg = State->getFirstUnallocated(IntArgRegs); - // If Align > RegSizeInBytes, the first arg register must be even. + // If Alignment > RegSizeInBytes, the first arg register must be even. // FIXME: This condition happens to do the right thing but it's not the // right way to test it. We want to check that the stack frame offset // of the register is aligned. - if ((Align > RegSizeInBytes) && (FirstReg % 2)) { + if ((Alignment > RegSizeInBytes) && (FirstReg % 2)) { State->AllocateReg(IntArgRegs[FirstReg], ShadowRegs[FirstReg]); ++FirstReg; } diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp b/llvm/utils/TableGen/CallingConvEmitter.cpp --- a/llvm/utils/TableGen/CallingConvEmitter.cpp +++ b/llvm/utils/TableGen/CallingConvEmitter.cpp @@ -275,9 +275,8 @@ } else if (Action->isSubClassOf("CCPassByVal")) { int Size = Action->getValueAsInt("Size"); int Align = Action->getValueAsInt("Align"); - O << IndentStr - << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " - << Size << ", " << Align << ", ArgFlags);\n"; + O << IndentStr << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " + << Size << ", Align(" << Align << "), ArgFlags);\n"; O << IndentStr << "return false;\n"; } else if (Action->isSubClassOf("CCCustom")) { O << IndentStr