[PowerPC64] Fix passing of single-vector-member structs to match ABI.
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Tue, 23 Jul 2013 22:15:57 +0000 (22:15 +0000)
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>
Tue, 23 Jul 2013 22:15:57 +0000 (22:15 +0000)
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

llvm-svn: 186993

clang/lib/CodeGen/TargetInfo.cpp
clang/test/CodeGen/ppc64-struct-onevect.c [new file with mode: 0644]

index a3b092d..a8861cf 100644 (file)
@@ -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<BuiltinType>();
-        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/clang/test/CodeGen/ppc64-struct-onevect.c b/clang/test/CodeGen/ppc64-struct-onevect.c
new file mode 100644 (file)
index 0000000..6d1c337
--- /dev/null
@@ -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