summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorPengfei Wang <pengfei.wang@intel.com>2019-06-12 01:52:23 +0000
committerPengfei Wang <pengfei.wang@intel.com>2019-06-12 01:52:23 +0000
commitfbfee60c32636a5dec6acceca401a78a1b024025 (patch)
treeed36880708cf422ad5732fc727505fd2a373df17 /clang/lib/CodeGen/TargetInfo.cpp
parentdd4bed3d7a8555db26c256489791bb6c78d5272b (diff)
downloadbcm5719-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.cpp56
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));
}
}
OpenPOWER on IntegriCloud