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 | f37bd2f2f1dbea7328d4faacd8040399913f44c1 (patch) | |
| tree | 1b79f69ccce03dcf07f1c1d599815bccfb64526b /clang/lib | |
| parent | d61887dd0a2b20dd7a013b0fe2c195266407cedb (diff) | |
| download | llvm-f37bd2f2f1dbea7328d4faacd8040399913f44c1.zip llvm-f37bd2f2f1dbea7328d4faacd8040399913f44c1.tar.gz llvm-f37bd2f2f1dbea7328d4faacd8040399913f44c1.tar.bz2 | |
Don't use a varargs convention for calls unprototyped functions where one of the arguments is an AVX vector.
llvm-svn: 145574
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 29 | ||||
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.h | 3 |
3 files changed, 27 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 2b24f59..60e0121 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2458,7 +2458,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, // call. The way we make this work is to cast to the exact type // of the promoted arguments. if (isa<FunctionNoProtoType>(FnType) && - !getTargetHooks().isNoProtoCallVariadic(FnType->getCallConv())) { + !getTargetHooks().isNoProtoCallVariadic(FnInfo)) { assert(cast<llvm::FunctionType>(Callee->getType()->getContainedType(0)) ->isVarArg()); llvm::Type *CalleeTy = getTypes().GetFunctionType(FnInfo, false); diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 944eae8..77c4c9b 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/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); } }; diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 8f90c7b..eabc37b 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -32,6 +32,7 @@ namespace clang { namespace CodeGen { class CodeGenModule; class CodeGenFunction; + class CGFunctionInfo; } /// TargetCodeGenInfo - This class organizes various target-specific @@ -160,7 +161,7 @@ namespace clang { /// same way and some out-of-band information is passed for the /// benefit of variadic callees, as is the case for x86-64. /// In this case the ABI should be consulted. - virtual bool isNoProtoCallVariadic(CallingConv CC) const; + virtual bool isNoProtoCallVariadic(const CodeGen::CGFunctionInfo &) const; }; } |
