From: Pete Cooper Date: Fri, 17 Apr 2015 22:16:24 +0000 (+0000) Subject: Change AArch64 i128 returns to use [2 x i64] when possible. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af3ab2bc511fdcfb18ca15eb52a9d9eb921121fd;p=clang Change AArch64 i128 returns to use [2 x i64] when possible. Something like { void*, void * } would be passed to a function as a [2 x i64], but returned as an i128. This patch unifies the 2 behaviours so that we also return it as a [2 x i64]. This is better for the quality of the IR, and the size of the final LLVM binary as we tend to want to insert/extract values from these types and do so with the insert/extract instructions is less IR than shifting, truncating, and or'ing values. Reviewed by Tim Northover. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235231 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 05529656d1..23d304731f 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -4044,7 +4044,15 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const { // Aggregates <= 16 bytes are returned directly in registers or on the stack. uint64_t Size = getContext().getTypeSize(RetTy); if (Size <= 128) { + unsigned Alignment = getContext().getTypeAlign(RetTy); Size = 64 * ((Size + 63) / 64); // round up to multiple of 8 bytes + + // We use a pair of i64 for 16-byte aggregate with 8-byte alignment. + // For aggregates with 16-byte alignment, we use i128. + if (Alignment < 128 && Size == 128) { + llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext()); + return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64)); + } return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); } diff --git a/test/CodeGen/arm64-arguments.c b/test/CodeGen/arm64-arguments.c index c276350da9..4486bb4b18 100644 --- a/test/CodeGen/arm64-arguments.c +++ b/test/CodeGen/arm64-arguments.c @@ -92,7 +92,7 @@ struct s21 f21(void) {} // CHECK: define i64 @f22() // CHECK: define i64 @f23() // CHECK: define i64 @f24() -// CHECK: define i128 @f25() +// CHECK: define [2 x i64] @f25() // CHECK: define { float, float } @f26() // CHECK: define { double, double } @f27() _Complex char f22(void) {}