diff options
author | Chris Lattner <sabre@nondot.org> | 2010-07-28 23:47:21 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-07-28 23:47:21 +0000 |
commit | ab5722e67794b3954c874a369086fc5f41ac46a5 (patch) | |
tree | e710dce69fbd23a61ee409dedaf11114380e79e4 /lib/CodeGen/TargetInfo.cpp | |
parent | 2eb9cdd5922c6fe48af185bee1988dabb5bd644e (diff) |
pass argument vectors in a type that corresponds to the user type if
possible. This improves the example to pass <4 x float> instead of
<2 x double> but we still get awful code, and still don't get the
return value right.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109700 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 613e2f6281..fc5e91fb7d 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -1432,10 +1432,22 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the // eightbyte is passed in the upper half of the last used SSE - // register. + // register. This only happens when 128-bit vectors are passed. case SSEUp: - assert(Lo == SSE && "Unexpected SSEUp classification."); + assert(Lo == SSE && "Unexpected SSEUp classification"); ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(VMContext), 2); + + // If the preferred type is a 16-byte vector, prefer to pass it. + if (const llvm::VectorType *VT = + dyn_cast_or_null<llvm::VectorType>(PrefType)) { + const llvm::Type *EltTy = VT->getElementType(); + if (VT->getBitWidth() == 128 && + (EltTy->isFloatTy() || EltTy->isDoubleTy() || + EltTy->isIntegerTy(8) || EltTy->isIntegerTy(16) || + EltTy->isIntegerTy(32) || EltTy->isIntegerTy(64) || + EltTy->isIntegerTy(128))) + ResType = PrefType; + } break; } |