diff options
author | Oliver Stannard <oliver.stannard@arm.com> | 2014-05-07 10:39:12 +0000 |
---|---|---|
committer | Oliver Stannard <oliver.stannard@arm.com> | 2014-05-07 10:39:12 +0000 |
commit | 39d26c98c53596dc800571ee2a62328ed681bed3 (patch) | |
tree | d2fa920380a52e2f5687de7391e35a865a07de7d | |
parent | 3dc2c016a6e7b5d57713a014cfae6ce45c2f652b (diff) | |
download | bcm5719-llvm-39d26c98c53596dc800571ee2a62328ed681bed3.tar.gz bcm5719-llvm-39d26c98c53596dc800571ee2a62328ed681bed3.zip |
ARM: Fix assertion caused by passing bitfield struct using ABIArgInfo::getExpandWithPadding
In cases where a struct must, according to the AAPCS, not be split between
general purpose and floating point registers, we use
ABIArgInfo::getExpandWithPadding to add the padding arguments. However,
ExpandWithPadding does not work if the struct contains bitfields, so we
instead must use ABIArgInfo::getDirect.
llvm-svn: 208185
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/arm-aapcs-vfp.c | 8 |
2 files changed, 8 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 32525e47001..300fb19f209 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -3926,7 +3926,8 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const { if (!IsCPRC && PreAllocationGPRs < NumGPRs && AllocatedGPRs > NumGPRs && StackUsed) { llvm::Type *PaddingTy = llvm::ArrayType::get( llvm::Type::getInt32Ty(getVMContext()), NumGPRs - PreAllocationGPRs); - I.info = ABIArgInfo::getExpandWithPadding(false, PaddingTy); + I.info = ABIArgInfo::getDirect(nullptr /* type */, 0 /* offset */, + PaddingTy); } } diff --git a/clang/test/CodeGen/arm-aapcs-vfp.c b/clang/test/CodeGen/arm-aapcs-vfp.c index 9972158bb96..c356d696ec9 100644 --- a/clang/test/CodeGen/arm-aapcs-vfp.c +++ b/clang/test/CodeGen/arm-aapcs-vfp.c @@ -125,8 +125,12 @@ typedef struct { long long x; int y; } struct_long_long_int; // CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_1(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, i64 %k, i32 %l) void test_vfp_stack_gpr_split_1(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, long long k, int l) {} -// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_2(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, [3 x i32], i64 %k.0, i32 %k.1) +// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_2(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, [3 x i32], i64 %k.coerce0, i32 %k.coerce1) void test_vfp_stack_gpr_split_2(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_long_long_int k) {} -// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_3(%struct.struct_long_long_int* noalias sret %agg.result, double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, [3 x i32], i64 %k.0, i32 %k.1) +// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_3(%struct.struct_long_long_int* noalias sret %agg.result, double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, [3 x i32], i64 %k.coerce0, i32 %k.coerce1) struct_long_long_int test_vfp_stack_gpr_split_3(double a, double b, double c, double d, double e, double f, double g, double h, double i, struct_long_long_int k) {} + +typedef struct { int a; int b:4; int c; } struct_int_bitfield_int; +// CHECK: define arm_aapcs_vfpcc void @test_test_vfp_stack_gpr_split_bitfield(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, i32 %k, [2 x i32], i32 %l.coerce0, i8 %l.coerce1, i32 %l.coerce2) +void test_test_vfp_stack_gpr_split_bitfield(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, int k, struct_int_bitfield_int l) {} |