r262688 - [X86] Pass __m64 types via SSE registers for GCC compatibility

James Y Knight via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 4 07:49:06 PST 2016


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 at lists.llvm.org> wrote:
>> To: cfe-commits at 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 at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list