From 345032a7211a6f983d59c30c0b3fa2b96819532a Mon Sep 17 00:00:00 2001
From: Chandler Carruth <chandlerc@gmail.com>
Date: Mon, 20 Feb 2012 07:35:45 +0000
Subject: [PATCH] Add 3dNOW intrinsic header to x86intrin.h, conditioned on
 __3dNOW__ to match the behavior of GCC. Also add a test for these intrinsics,
 which apparently have *zero* tests. =[ Not surprisingly, Clang crashed when
 compiling these.

Fix the bug in CodeGen where we failed to bitcast the argument type to
x86mmx prior to calling the LLVM intrinsic. This fixes an assert on the
new 3dnow-builtins.c test.

This is one issue impacting the efforts to get Clang to emulate the
Microsoft intrinsics headers -- 3dnow intrinsics are implictitly made
available there.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150948 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGBuiltin.cpp     |   2 +
 lib/Headers/x86intrin.h       |   6 +-
 test/CodeGen/3dnow-builtins.c | 156 ++++++++++++++++++++++++++++++++++
 3 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 test/CodeGen/3dnow-builtins.c

diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 038631e5ca9..ff25609b67c 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -2240,6 +2240,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
       ID = Intrinsic::x86_3dnowa_pswapd;
       break;
     }
+    llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext());
+    Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast");
     llvm::Function *F = CGM.getIntrinsic(ID);
     return Builder.CreateCall(F, Ops, name);
   }
diff --git a/lib/Headers/x86intrin.h b/lib/Headers/x86intrin.h
index 5f9bea7107a..f5e4d883e8b 100644
--- a/lib/Headers/x86intrin.h
+++ b/lib/Headers/x86intrin.h
@@ -26,6 +26,10 @@
 
 #include <immintrin.h>
 
+#ifdef __3dNOW__
+#include <mm3dnow.h>
+#endif
+
 #ifdef __BMI__
 #include <bmiintrin.h>
 #endif
@@ -46,6 +50,6 @@
 #include <fma4intrin.h>
 #endif
 
-// FIXME: SSE4A, 3dNOW, XOP, LWP, ABM
+// FIXME: SSE4A, XOP, LWP, ABM
 
 #endif /* __X86INTRIN_H */
diff --git a/test/CodeGen/3dnow-builtins.c b/test/CodeGen/3dnow-builtins.c
new file mode 100644
index 00000000000..294fbc0579e
--- /dev/null
+++ b/test/CodeGen/3dnow-builtins.c
@@ -0,0 +1,156 @@
+// RUN: %clang_cc1 %s -O3 -triple=x86_64-unknown-unknown -target-feature +3dnow -emit-llvm -o - | FileCheck %s
+
+// Don't include mm_malloc.h, it's system specific.
+#define __MM_MALLOC_H
+
+#include <x86intrin.h>
+
+__m64 test_m_pavgusb(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pavgusb
+  // CHECK: @llvm.x86.3dnow.pavgusb
+  return _m_pavgusb(m1, m2);
+}
+
+__m64 test_m_pf2id(__m64 m) {
+  // CHECK: define i64 @test_m_pf2id
+  // CHECK: @llvm.x86.3dnow.pf2id
+  return _m_pf2id(m);
+}
+
+__m64 test_m_pfacc(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfacc
+  // CHECK: @llvm.x86.3dnow.pfacc
+  return _m_pfacc(m1, m2);
+}
+
+__m64 test_m_pfadd(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfadd
+  // CHECK: @llvm.x86.3dnow.pfadd
+  return _m_pfadd(m1, m2);
+}
+
+__m64 test_m_pfcmpeq(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfcmpeq
+  // CHECK: @llvm.x86.3dnow.pfcmpeq
+  return _m_pfcmpeq(m1, m2);
+}
+
+__m64 test_m_pfcmpge(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfcmpge
+  // CHECK: @llvm.x86.3dnow.pfcmpge
+  return _m_pfcmpge(m1, m2);
+}
+
+__m64 test_m_pfcmpgt(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfcmpgt
+  // CHECK: @llvm.x86.3dnow.pfcmpgt
+  return _m_pfcmpgt(m1, m2);
+}
+
+__m64 test_m_pfmax(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfmax
+  // CHECK: @llvm.x86.3dnow.pfmax
+  return _m_pfmax(m1, m2);
+}
+
+__m64 test_m_pfmin(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfmin
+  // CHECK: @llvm.x86.3dnow.pfmin
+  return _m_pfmin(m1, m2);
+}
+
+__m64 test_m_pfmul(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfmul
+  // CHECK: @llvm.x86.3dnow.pfmul
+  return _m_pfmul(m1, m2);
+}
+
+__m64 test_m_pfrcp(__m64 m) {
+  // CHECK: define i64 @test_m_pfrcp
+  // CHECK: @llvm.x86.3dnow.pfrcp
+  return _m_pfrcp(m);
+}
+
+__m64 test_m_pfrcpit1(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfrcpit1
+  // CHECK: @llvm.x86.3dnow.pfrcpit1
+  return _m_pfrcpit1(m1, m2);
+}
+
+__m64 test_m_pfrcpit2(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfrcpit2
+  // CHECK: @llvm.x86.3dnow.pfrcpit2
+  return _m_pfrcpit2(m1, m2);
+}
+
+__m64 test_m_pfrsqrt(__m64 m) {
+  // CHECK: define i64 @test_m_pfrsqrt
+  // CHECK: @llvm.x86.3dnow.pfrsqrt
+  return _m_pfrsqrt(m);
+}
+
+__m64 test_m_pfrsqrtit1(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfrsqrtit1
+  // CHECK: @llvm.x86.3dnow.pfrsqit1
+  return _m_pfrsqrtit1(m1, m2);
+}
+
+__m64 test_m_pfsub(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfsub
+  // CHECK: @llvm.x86.3dnow.pfsub
+  return _m_pfsub(m1, m2);
+}
+
+__m64 test_m_pfsubr(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfsubr
+  // CHECK: @llvm.x86.3dnow.pfsubr
+  return _m_pfsubr(m1, m2);
+}
+
+__m64 test_m_pi2fd(__m64 m) {
+  // CHECK: define i64 @test_m_pi2fd
+  // CHECK: @llvm.x86.3dnow.pi2fd
+  return _m_pi2fd(m);
+}
+
+__m64 test_m_pmulhrw(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pmulhrw
+  // CHECK: @llvm.x86.3dnow.pmulhrw
+  return _m_pmulhrw(m1, m2);
+}
+
+__m64 test_m_pf2iw(__m64 m) {
+  // CHECK: define i64 @test_m_pf2iw
+  // CHECK: @llvm.x86.3dnowa.pf2iw
+  return _m_pf2iw(m);
+}
+
+__m64 test_m_pfnacc(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfnacc
+  // CHECK: @llvm.x86.3dnowa.pfnacc
+  return _m_pfnacc(m1, m2);
+}
+
+__m64 test_m_pfpnacc(__m64 m1, __m64 m2) {
+  // CHECK: define i64 @test_m_pfpnacc
+  // CHECK: @llvm.x86.3dnowa.pfpnacc
+  return _m_pfpnacc(m1, m2);
+}
+
+__m64 test_m_pi2fw(__m64 m) {
+  // CHECK: define i64 @test_m_pi2fw
+  // CHECK: @llvm.x86.3dnowa.pi2fw
+  return _m_pi2fw(m);
+}
+
+__m64 test_m_pswapdsf(__m64 m) {
+  // CHECK: define i64 @test_m_pswapdsf
+  // CHECK: @llvm.x86.3dnowa.pswapd
+  return _m_pswapdsf(m);
+}
+
+__m64 test_m_pswapdsi(__m64 m) {
+  // CHECK: define i64 @test_m_pswapdsi
+  // CHECK: @llvm.x86.3dnowa.pswapd
+  return _m_pswapdsi(m);
+}
-- 
GitLab