It'd be nice to have a comment here that mentions that the clang behavior which is being preserved for Darwin, FreeBSD, and PS4 is a *bug* which is being intentionally left unfixed. The previous clang behavior directly contradicts the x86_64 ABI document, which I believe all of these platforms claim to follow. :)
On Fri, Mar 4, 2016 at 2:03 AM, Robinson, Paul via cfe-commits <cfe-commits@lists.llvm.org> wrote: >> To: cfe-commits@lists.llvm.org >> Subject: r262688 - [X86] Pass __m64 types via SSE registers for GCC >> compatibility >> >> Author: majnemer >> Date: Thu Mar 3 23:26:16 2016 >> New Revision: 262688 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=262688&view=rev >> Log: >> [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. > > Thank you very much for that! > --paulr > >> >> This fixes PR26832. >> >> Modified: >> cfe/trunk/lib/CodeGen/TargetInfo.cpp >> cfe/trunk/test/CodeGen/3dnow-builtins.c >> cfe/trunk/test/CodeGen/x86_64-arguments.c >> >> Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp >> URL: http://llvm.org/viewvc/llvm- >> project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=262688&r1=262687&r2=26268 >> 8&view=diff >> ========================================================================== >> ==== >> --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) >> +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Mar 3 23:26:16 2016 >> @@ -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 >> 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; >> >> Modified: cfe/trunk/test/CodeGen/3dnow-builtins.c >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/3dnow- >> builtins.c?rev=262688&r1=262687&r2=262688&view=diff >> ========================================================================== >> ==== >> --- cfe/trunk/test/CodeGen/3dnow-builtins.c (original) >> +++ cfe/trunk/test/CodeGen/3dnow-builtins.c Thu Mar 3 23:26:16 2016 >> @@ -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); >> } >> >> Modified: cfe/trunk/test/CodeGen/x86_64-arguments.c >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64- >> arguments.c?rev=262688&r1=262687&r2=262688&view=diff >> ========================================================================== >> ==== >> --- cfe/trunk/test/CodeGen/x86_64-arguments.c (original) >> +++ cfe/trunk/test/CodeGen/x86_64-arguments.c Thu Mar 3 23:26:16 2016 >> @@ -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; } >> >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits