mirror of
https://github.com/intel/llvm.git
synced 2026-02-08 08:57:43 +08:00
[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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -target-feature +3dnowa -emit-llvm -o - -Werror | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -target-feature +3dnowa -emit-llvm -o - -Werror | FileCheck %s -check-prefix=GCC -check-prefix=CHECK
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-scei-ps4 -target-feature +3dnowa -emit-llvm -o - -Werror | FileCheck %s -check-prefix=PS4 -check-prefix=CHECK
|
||||
|
||||
// Don't include mm_malloc.h, it's system specific.
|
||||
#define __MM_MALLOC_H
|
||||
@@ -6,151 +7,176 @@
|
||||
#include <x86intrin.h>
|
||||
|
||||
__m64 test_m_pavgusb(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pavgusb
|
||||
// PS4-LABEL: define i64 @test_m_pavgusb
|
||||
// GCC-LABEL: define double @test_m_pavgusb
|
||||
// CHECK: @llvm.x86.3dnow.pavgusb
|
||||
return _m_pavgusb(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pf2id(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pf2id
|
||||
// PS4-LABEL: define i64 @test_m_pf2id
|
||||
// GCC-LABEL: define double @test_m_pf2id
|
||||
// CHECK: @llvm.x86.3dnow.pf2id
|
||||
return _m_pf2id(m);
|
||||
}
|
||||
|
||||
__m64 test_m_pfacc(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfacc
|
||||
// PS4-LABEL: define i64 @test_m_pfacc
|
||||
// GCC-LABEL: define double @test_m_pfacc
|
||||
// CHECK: @llvm.x86.3dnow.pfacc
|
||||
return _m_pfacc(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfadd(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfadd
|
||||
// PS4-LABEL: define i64 @test_m_pfadd
|
||||
// GCC-LABEL: define double @test_m_pfadd
|
||||
// CHECK: @llvm.x86.3dnow.pfadd
|
||||
return _m_pfadd(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfcmpeq(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfcmpeq
|
||||
// PS4-LABEL: define i64 @test_m_pfcmpeq
|
||||
// GCC-LABEL: define double @test_m_pfcmpeq
|
||||
// CHECK: @llvm.x86.3dnow.pfcmpeq
|
||||
return _m_pfcmpeq(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfcmpge(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfcmpge
|
||||
// PS4-LABEL: define i64 @test_m_pfcmpge
|
||||
// GCC-LABEL: define double @test_m_pfcmpge
|
||||
// CHECK: @llvm.x86.3dnow.pfcmpge
|
||||
return _m_pfcmpge(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfcmpgt(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfcmpgt
|
||||
// PS4-LABEL: define i64 @test_m_pfcmpgt
|
||||
// GCC-LABEL: define double @test_m_pfcmpgt
|
||||
// CHECK: @llvm.x86.3dnow.pfcmpgt
|
||||
return _m_pfcmpgt(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfmax(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfmax
|
||||
// PS4-LABEL: define i64 @test_m_pfmax
|
||||
// GCC-LABEL: define double @test_m_pfmax
|
||||
// CHECK: @llvm.x86.3dnow.pfmax
|
||||
return _m_pfmax(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfmin(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfmin
|
||||
// PS4-LABEL: define i64 @test_m_pfmin
|
||||
// GCC-LABEL: define double @test_m_pfmin
|
||||
// CHECK: @llvm.x86.3dnow.pfmin
|
||||
return _m_pfmin(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfmul(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfmul
|
||||
// PS4-LABEL: define i64 @test_m_pfmul
|
||||
// GCC-LABEL: define double @test_m_pfmul
|
||||
// CHECK: @llvm.x86.3dnow.pfmul
|
||||
return _m_pfmul(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfrcp(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfrcp
|
||||
// PS4-LABEL: define i64 @test_m_pfrcp
|
||||
// GCC-LABEL: define double @test_m_pfrcp
|
||||
// CHECK: @llvm.x86.3dnow.pfrcp
|
||||
return _m_pfrcp(m);
|
||||
}
|
||||
|
||||
__m64 test_m_pfrcpit1(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfrcpit1
|
||||
// PS4-LABEL: define i64 @test_m_pfrcpit1
|
||||
// GCC-LABEL: define double @test_m_pfrcpit1
|
||||
// CHECK: @llvm.x86.3dnow.pfrcpit1
|
||||
return _m_pfrcpit1(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfrcpit2(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfrcpit2
|
||||
// PS4-LABEL: define i64 @test_m_pfrcpit2
|
||||
// GCC-LABEL: define double @test_m_pfrcpit2
|
||||
// CHECK: @llvm.x86.3dnow.pfrcpit2
|
||||
return _m_pfrcpit2(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfrsqrt(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfrsqrt
|
||||
// PS4-LABEL: define i64 @test_m_pfrsqrt
|
||||
// GCC-LABEL: define double @test_m_pfrsqrt
|
||||
// CHECK: @llvm.x86.3dnow.pfrsqrt
|
||||
return _m_pfrsqrt(m);
|
||||
}
|
||||
|
||||
__m64 test_m_pfrsqrtit1(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfrsqrtit1
|
||||
// PS4-LABEL: define i64 @test_m_pfrsqrtit1
|
||||
// GCC-LABEL: define double @test_m_pfrsqrtit1
|
||||
// CHECK: @llvm.x86.3dnow.pfrsqit1
|
||||
return _m_pfrsqrtit1(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfsub(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfsub
|
||||
// PS4-LABEL: define i64 @test_m_pfsub
|
||||
// GCC-LABEL: define double @test_m_pfsub
|
||||
// CHECK: @llvm.x86.3dnow.pfsub
|
||||
return _m_pfsub(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfsubr(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfsubr
|
||||
// PS4-LABEL: define i64 @test_m_pfsubr
|
||||
// GCC-LABEL: define double @test_m_pfsubr
|
||||
// CHECK: @llvm.x86.3dnow.pfsubr
|
||||
return _m_pfsubr(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pi2fd(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pi2fd
|
||||
// PS4-LABEL: define i64 @test_m_pi2fd
|
||||
// GCC-LABEL: define double @test_m_pi2fd
|
||||
// CHECK: @llvm.x86.3dnow.pi2fd
|
||||
return _m_pi2fd(m);
|
||||
}
|
||||
|
||||
__m64 test_m_pmulhrw(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pmulhrw
|
||||
// PS4-LABEL: define i64 @test_m_pmulhrw
|
||||
// GCC-LABEL: define double @test_m_pmulhrw
|
||||
// CHECK: @llvm.x86.3dnow.pmulhrw
|
||||
return _m_pmulhrw(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pf2iw(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pf2iw
|
||||
// PS4-LABEL: define i64 @test_m_pf2iw
|
||||
// GCC-LABEL: define double @test_m_pf2iw
|
||||
// CHECK: @llvm.x86.3dnowa.pf2iw
|
||||
return _m_pf2iw(m);
|
||||
}
|
||||
|
||||
__m64 test_m_pfnacc(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfnacc
|
||||
// PS4-LABEL: define i64 @test_m_pfnacc
|
||||
// GCC-LABEL: define double @test_m_pfnacc
|
||||
// CHECK: @llvm.x86.3dnowa.pfnacc
|
||||
return _m_pfnacc(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pfpnacc(__m64 m1, __m64 m2) {
|
||||
// CHECK-LABEL: define i64 @test_m_pfpnacc
|
||||
// PS4-LABEL: define i64 @test_m_pfpnacc
|
||||
// GCC-LABEL: define double @test_m_pfpnacc
|
||||
// CHECK: @llvm.x86.3dnowa.pfpnacc
|
||||
return _m_pfpnacc(m1, m2);
|
||||
}
|
||||
|
||||
__m64 test_m_pi2fw(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pi2fw
|
||||
// PS4-LABEL: define i64 @test_m_pi2fw
|
||||
// GCC-LABEL: define double @test_m_pi2fw
|
||||
// CHECK: @llvm.x86.3dnowa.pi2fw
|
||||
return _m_pi2fw(m);
|
||||
}
|
||||
|
||||
__m64 test_m_pswapdsf(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pswapdsf
|
||||
// PS4-LABEL: define i64 @test_m_pswapdsf
|
||||
// GCC-LABEL: define double @test_m_pswapdsf
|
||||
// CHECK: @llvm.x86.3dnowa.pswapd
|
||||
return _m_pswapdsf(m);
|
||||
}
|
||||
|
||||
__m64 test_m_pswapdsi(__m64 m) {
|
||||
// CHECK-LABEL: define i64 @test_m_pswapdsi
|
||||
// PS4-LABEL: define i64 @test_m_pswapdsi
|
||||
// GCC-LABEL: define double @test_m_pswapdsi
|
||||
// CHECK: @llvm.x86.3dnowa.pswapd
|
||||
return _m_pswapdsi(m);
|
||||
}
|
||||
|
||||
@@ -261,12 +261,12 @@ void f33(va_list X) {
|
||||
typedef unsigned long long v1i64 __attribute__((__vector_size__(8)));
|
||||
|
||||
// rdar://8359248
|
||||
// CHECK-LABEL: define i64 @f34(i64 %arg.coerce)
|
||||
// CHECK-LABEL: define double @f34(double %arg.coerce)
|
||||
v1i64 f34(v1i64 arg) { return arg; }
|
||||
|
||||
|
||||
// rdar://8358475
|
||||
// CHECK-LABEL: define i64 @f35(i64 %arg.coerce)
|
||||
// CHECK-LABEL: define double @f35(double %arg.coerce)
|
||||
typedef unsigned long v1i64_2 __attribute__((__vector_size__(8)));
|
||||
v1i64_2 f35(v1i64_2 arg) { return arg+arg; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user