Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -4054,7 +4054,7 @@ /// which have been allocated. It is valid for AllocatedGPRs to go above 4, /// this represents arguments being stored on the stack. void ARMABIInfo::markAllocatedGPRs(unsigned Alignment, - unsigned NumRequired) const { + unsigned NumRequired) const { assert((Alignment == 1 || Alignment == 2) && "Alignment must be 4 or 8 bytes"); if (Alignment == 2 && AllocatedGPRs & 0x1) @@ -4198,7 +4198,14 @@ ABIAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8); if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) { // Update Allocated GPRs - markAllocatedGPRs(1, 1); + unsigned NumRegs; + if (getContext().getTypeAlign(Ty) <= 32) { + NumRegs = (getContext().getTypeSize(Ty) + 31) / 32; + markAllocatedGPRs(1, NumRegs); + } else { + NumRegs = (getContext().getTypeSize(Ty) + 63) / 64; + markAllocatedGPRs(2, NumRegs * 2); + } return ABIArgInfo::getIndirect(TyAlign, /*ByVal=*/true, /*Realign=*/TyAlign > ABIAlign); } Index: test/CodeGen/arm-aapcs-vfp.c =================================================================== --- test/CodeGen/arm-aapcs-vfp.c +++ test/CodeGen/arm-aapcs-vfp.c @@ -139,3 +139,9 @@ typedef struct { int x; long long y; } struct_int_long_long; // CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_4(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, [3 x i32], { [2 x i64] } %k.coerce) void test_vfp_stack_gpr_split_4(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_int_long_long k) {} + +// This very large struct (passed byval) uses up the GPRs, so no padding is needed +typedef struct { int x[17]; } struct_seventeen_ints; +typedef struct { int x[4]; } struct_four_ints; +// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_5(%struct.struct_seventeen_ints* byval align 4 %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, double %j, { [4 x i32] } %k.coerce) +void test_vfp_stack_gpr_split_5(struct_seventeen_ints a, double b, double c, double d, double e, double f, double g, double h, double i, double j, struct_four_ints k) {}