From b199310f56d6695780b146baf2b823b8676e4525 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Tue, 23 Jul 2013 22:15:57 +0000 Subject: [PATCH] [PowerPC64] Fix passing of single-vector-member structs to match ABI. The 64-bit PowerPC ELF ABI requires a struct that contains a single vector member to be passed in a vector register as though the wrapping struct were not present. Instead we were passing this as a byval struct. The same logic was already present for floating-point arguments, so this patch just extends the logic to handle vector types. The new test case verifies that clang coerces the parameter and annotates it as inreg. Thanks, Bill git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186993 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TargetInfo.cpp | 4 ++-- test/CodeGen/ppc64-struct-onevect.c | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/ppc64-struct-onevect.c diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index a3b092d687..a8861cf450 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -2801,11 +2801,11 @@ public: it != ie; ++it) { // We rely on the default argument classification for the most part. // One exception: An aggregate containing a single floating-point - // item must be passed in a register if one is available. + // or vector item must be passed in a register if one is available. const Type *T = isSingleElementStruct(it->type, getContext()); if (T) { const BuiltinType *BT = T->getAs(); - if (BT && BT->isFloatingPoint()) { + if (T->isVectorType() || (BT && BT->isFloatingPoint())) { QualType QT(T, 0); it->info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT)); continue; diff --git a/test/CodeGen/ppc64-struct-onevect.c b/test/CodeGen/ppc64-struct-onevect.c new file mode 100644 index 0000000000..6d1c3374c3 --- /dev/null +++ b/test/CodeGen/ppc64-struct-onevect.c @@ -0,0 +1,13 @@ +// REQUIRES: ppc64-registered-target +// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +typedef float v4sf __attribute__ ((vector_size (16))); + +struct s { v4sf v; }; + +v4sf foo (struct s a) { + return a.v; +} + +// CHECK: define <4 x float> @foo(<4 x float> inreg %a.coerce) +// CHECK: ret <4 x float> %a.coerce -- 2.40.0