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

David Majnemer via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 3 21:26:16 PST 2016


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.

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=262688&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; }
 




More information about the cfe-commits mailing list