aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/TargetInfo.cpp15
-rw-r--r--test/CodeGen/x86_64-arguments.c10
2 files changed, 23 insertions, 2 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 7321ba148c..e8e4c5c462 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -1185,9 +1185,20 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty) const {
/// full vector XMM register. Pick an LLVM IR type that will be passed as a
/// vector register.
const llvm::Type *X86_64ABIInfo::Get16ByteVectorType(QualType Ty) const {
+ const llvm::Type *IRType = CGT.ConvertTypeRecursive(Ty);
+
+ // Wrapper structs that just contain vectors are passed just like vectors,
+ // strip them off if present.
+ const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType);
+ while (STy && STy->getNumElements() == 1) {
+ IRType = STy->getElementType(0);
+ STy = dyn_cast<llvm::StructType>(IRType);
+ }
+
+
+
// If the preferred type is a 16-byte vector, prefer to pass it.
- if (const llvm::VectorType *VT =
- dyn_cast<llvm::VectorType>(CGT.ConvertTypeRecursive(Ty))){
+ if (const llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){
const llvm::Type *EltTy = VT->getElementType();
if (VT->getBitWidth() == 128 &&
(EltTy->isFloatTy() || EltTy->isDoubleTy() ||
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
index ed1c9f165a..04447c12d9 100644
--- a/test/CodeGen/x86_64-arguments.c
+++ b/test/CodeGen/x86_64-arguments.c
@@ -168,3 +168,13 @@ struct foo26 f26(struct foo26 *P) {
// CHECK: define %struct.foo26 @f26(%struct.foo26* %P)
return *P;
}
+
+
+struct v4f32wrapper {
+ v4f32 v;
+};
+
+struct v4f32wrapper f27(struct v4f32wrapper X) {
+ // CHECK: define <4 x float> @f27(<4 x float> %X.coerce)
+ return X;
+} \ No newline at end of file