summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-03-04 05:26:16 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-03-04 05:26:16 +0000
commite2ae228c7641ec01d29c74a71042f4b1a08f8e8b (patch)
tree43fae92aed76ea179cdf1e85668efc111a38c85f /clang/lib/CodeGen/TargetInfo.cpp
parent6a6206d440152b534b3e08e87b0ab3168573c438 (diff)
downloadbcm5719-llvm-e2ae228c7641ec01d29c74a71042f4b1a08f8e8b.tar.gz
bcm5719-llvm-e2ae228c7641ec01d29c74a71042f4b1a08f8e8b.zip
[X86] Pass __m64 types via SSE registers for GCC compatibility
For compatibility with GCC, classify __m64 as SSE. However, clang is a platform compiler for certain targets; retain our old behavior on those targets: classify __m64 as integer. This fixes PR26832. llvm-svn: 262688
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp28
1 files changed, 22 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index d9f4e7761ae..51949979ad9 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -1857,6 +1857,17 @@ class X86_64ABIInfo : public ABIInfo {
return !getTarget().getTriple().isOSDarwin();
}
+ /// GCC classifies <1 x long long> as SSE but compatibility with older clang
+ // compilers require us to classify it as INTEGER.
+ bool classifyIntegerMMXAsSSE() const {
+ const llvm::Triple &Triple = getTarget().getTriple();
+ if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::PS4)
+ return false;
+ if (Triple.isOSFreeBSD() && Triple.getOSMajorVersion() >= 10)
+ return false;
+ return true;
+ }
+
X86AVXABILevel AVXLevel;
// Some ABIs (e.g. X32 ABI and Native Client OS) use 32 bit pointers on
// 64-bit hardware.
@@ -2298,15 +2309,20 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,
if (EB_Lo != EB_Hi)
Hi = Lo;
} else if (Size == 64) {
+ QualType ElementType = VT->getElementType();
+
// gcc passes <1 x double> in memory. :(
- if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double))
+ if (ElementType->isSpecificBuiltinType(BuiltinType::Double))
return;
- // gcc passes <1 x long long> as INTEGER.
- if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::LongLong) ||
- VT->getElementType()->isSpecificBuiltinType(BuiltinType::ULongLong) ||
- VT->getElementType()->isSpecificBuiltinType(BuiltinType::Long) ||
- VT->getElementType()->isSpecificBuiltinType(BuiltinType::ULong))
+ // gcc passes <1 x long long> as SSE but clang used to unconditionally
+ // pass them as integer. For platforms where clang is the de facto
+ // platform compiler, we must continue to use integer.
+ if (!classifyIntegerMMXAsSSE() &&
+ (ElementType->isSpecificBuiltinType(BuiltinType::LongLong) ||
+ ElementType->isSpecificBuiltinType(BuiltinType::ULongLong) ||
+ ElementType->isSpecificBuiltinType(BuiltinType::Long) ||
+ ElementType->isSpecificBuiltinType(BuiltinType::ULong)))
Current = Integer;
else
Current = SSE;
OpenPOWER on IntegriCloud