diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-12-01 04:53:19 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-12-01 04:53:19 +0000 |
commit | 3ed7903d27f0e7e0cd3a61c165d39eca70f3cff5 (patch) | |
tree | ee4cb54618b682abe19d91844ce620feadcc901e /lib/CodeGen/TargetInfo.cpp | |
parent | 996e6e564af7483e2d5e0b70df5fdb9f79ec4b5a (diff) |
Don't use a varargs convention for calls unprototyped functions where one of the arguments is an AVX vector.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145574 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 944eae85d5..77c4c9b07e 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -98,7 +98,8 @@ unsigned TargetCodeGenInfo::getSizeOfUnwindException() const { return 32; } -bool TargetCodeGenInfo::isNoProtoCallVariadic(CallingConv CC) const { +bool TargetCodeGenInfo::isNoProtoCallVariadic( + const CodeGen::CGFunctionInfo &) const { // The following conventions are known to require this to be false: // x86_stdcall // MIPS @@ -978,13 +979,31 @@ public: return X86AdjustInlineAsmType(CGF, Constraint, Ty); } - bool isNoProtoCallVariadic(CallingConv CC) const { + bool isNoProtoCallVariadic(const CodeGen::CGFunctionInfo &FI) const { // The default CC on x86-64 sets %al to the number of SSA // registers used, and GCC sets this when calling an unprototyped - // function, so we override the default behavior. - if (CC == CC_Default || CC == CC_C) return true; + // function, so we override the default behavior. However, don't do + // that when AVX types are involved. + if (FI.getCallingConvention() == llvm::CallingConv::C) { + bool HasAVXType = false; + for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(), + ie = FI.arg_end(); + it != ie; ++it) { + if (it->info.isDirect()) { + llvm::Type *Ty = it->info.getCoerceToType(); + if (llvm::VectorType *VTy = dyn_cast_or_null<llvm::VectorType>(Ty)) { + if (VTy->getBitWidth() > 128) { + HasAVXType = true; + break; + } + } + } + } + if (!HasAVXType) + return true; + } - return TargetCodeGenInfo::isNoProtoCallVariadic(CC); + return TargetCodeGenInfo::isNoProtoCallVariadic(FI); } }; |