diff options
| author | Pengfei Wang <pengfei.wang@intel.com> | 2019-06-12 01:52:23 +0000 |
|---|---|---|
| committer | Pengfei Wang <pengfei.wang@intel.com> | 2019-06-12 01:52:23 +0000 |
| commit | fbfee60c32636a5dec6acceca401a78a1b024025 (patch) | |
| tree | ed36880708cf422ad5732fc727505fd2a373df17 /clang/lib/CodeGen/TargetInfo.cpp | |
| parent | dd4bed3d7a8555db26c256489791bb6c78d5272b (diff) | |
| download | bcm5719-llvm-fbfee60c32636a5dec6acceca401a78a1b024025.tar.gz bcm5719-llvm-fbfee60c32636a5dec6acceca401a78a1b024025.zip | |
[X86] [ABI] Fix i386 ABI "__m64" type bug
According to System V i386 ABI: the __m64 type paramater and return
value are passed by MMX registers. But current implementation treats
__m64 as i64 which results in parameter passing by stack and returning
by EDX and EAX.
This patch fixes the bug (https://bugs.llvm.org/show_bug.cgi?id=41029)
for Linux and NetBSD.
Patch by Wei Xiao (wxiao3)
Differential Revision: https://reviews.llvm.org/D59744
llvm-svn: 363116
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 24b7b9f97f9..f39764d1a46 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -915,14 +915,6 @@ ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const { : ABIArgInfo::getDirect()); } -/// IsX86_MMXType - Return true if this is an MMX type. -bool IsX86_MMXType(llvm::Type *IRType) { - // Return true if the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>. - return IRType->isVectorTy() && IRType->getPrimitiveSizeInBits() == 64 && - cast<llvm::VectorType>(IRType)->getElementType()->isIntegerTy() && - IRType->getScalarSizeInBits() != 64; -} - static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, StringRef Constraint, llvm::Type* Ty) { @@ -1011,6 +1003,7 @@ class X86_32ABIInfo : public SwiftABIInfo { bool IsSoftFloatABI; bool IsMCUABI; unsigned DefaultNumRegisterParameters; + bool IsMMXEnabled; static bool isRegisterSize(unsigned Size) { return (Size == 8 || Size == 16 || Size == 32 || Size == 64); @@ -1070,13 +1063,15 @@ public: X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI, bool RetSmallStructInRegABI, bool Win32StructABI, - unsigned NumRegisterParameters, bool SoftFloatABI) + unsigned NumRegisterParameters, bool SoftFloatABI, + bool MMXEnabled) : SwiftABIInfo(CGT), IsDarwinVectorABI(DarwinVectorABI), IsRetSmallStructInRegABI(RetSmallStructInRegABI), IsWin32StructABI(Win32StructABI), IsSoftFloatABI(SoftFloatABI), IsMCUABI(CGT.getTarget().getTriple().isOSIAMCU()), - DefaultNumRegisterParameters(NumRegisterParameters) {} + DefaultNumRegisterParameters(NumRegisterParameters), + IsMMXEnabled(MMXEnabled) {} bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars, bool asReturnValue) const override { @@ -1091,16 +1086,30 @@ public: // x86-32 lowering does not support passing swifterror in a register. return false; } + + bool isPassInMMXRegABI() const { + // The System V i386 psABI requires __m64 to be passed in MMX registers. + // Clang historically had a bug where it failed to apply this rule, and + // some platforms (e.g. Darwin, PS4, and FreeBSD) have opted to maintain + // compatibility with the old Clang behavior, so we only apply it on + // platforms that have specifically requested it (currently just Linux and + // NetBSD). + const llvm::Triple &T = getTarget().getTriple(); + if (IsMMXEnabled && (T.isOSLinux() || T.isOSNetBSD())) + return true; + return false; + } }; class X86_32TargetCodeGenInfo : public TargetCodeGenInfo { public: X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI, bool RetSmallStructInRegABI, bool Win32StructABI, - unsigned NumRegisterParameters, bool SoftFloatABI) + unsigned NumRegisterParameters, bool SoftFloatABI, + bool MMXEnabled = false) : TargetCodeGenInfo(new X86_32ABIInfo( CGT, DarwinVectorABI, RetSmallStructInRegABI, Win32StructABI, - NumRegisterParameters, SoftFloatABI)) {} + NumRegisterParameters, SoftFloatABI, MMXEnabled)) {} static bool isStructReturnInRegABI( const llvm::Triple &Triple, const CodeGenOptions &Opts); @@ -1386,10 +1395,9 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, } if (const VectorType *VT = RetTy->getAs<VectorType>()) { + uint64_t Size = getContext().getTypeSize(RetTy); // On Darwin, some vectors are returned in registers. if (IsDarwinVectorABI) { - uint64_t Size = getContext().getTypeSize(RetTy); - // 128-bit vectors are a special case; they are returned in // registers and we need to make sure to pick a type the LLVM // backend will like. @@ -1407,6 +1415,10 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, return getIndirectReturnResult(RetTy, State); } + if (VT->getElementType()->isIntegerType() && Size == 64 && + isPassInMMXRegABI()) + return ABIArgInfo::getDirect(llvm::Type::getX86_MMXTy(getVMContext())); + return ABIArgInfo::getDirect(); } @@ -1701,23 +1713,26 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, } if (const VectorType *VT = Ty->getAs<VectorType>()) { + uint64_t Size = getContext().getTypeSize(Ty); // On Darwin, some vectors are passed in memory, we handle this by passing // it as an i8/i16/i32/i64. if (IsDarwinVectorABI) { - uint64_t Size = getContext().getTypeSize(Ty); if ((Size == 8 || Size == 16 || Size == 32) || (Size == 64 && VT->getNumElements() == 1)) return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); } - if (IsX86_MMXType(CGT.ConvertType(Ty))) - return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 64)); - + if (VT->getElementType()->isIntegerType() && Size == 64) { + if (isPassInMMXRegABI()) + return ABIArgInfo::getDirect(llvm::Type::getX86_MMXTy(getVMContext())); + else + return ABIArgInfo::getDirect( + llvm::IntegerType::get(getVMContext(), 64)); + } return ABIArgInfo::getDirect(); } - if (const EnumType *EnumTy = Ty->getAs<EnumType>()) Ty = EnumTy->getDecl()->getIntegerType(); @@ -9460,10 +9475,11 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { Types, IsDarwinVectorABI, RetSmallStructInRegABI, IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters)); } else { + bool EnableMMX = getContext().getTargetInfo().getABI() != "no-mmx"; return SetCGInfo(new X86_32TargetCodeGenInfo( Types, IsDarwinVectorABI, RetSmallStructInRegABI, IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters, - CodeGenOpts.FloatABI == "soft")); + CodeGenOpts.FloatABI == "soft", EnableMMX)); } } |

