[llvm] 661881d - [X86] Add AMX-FP16 instructions.

Xiang1 Zhang via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 21 17:05:48 PDT 2022


Author: Xiang1 Zhang
Date: 2022-10-22T08:05:22+08:00
New Revision: 661881d43633c00e1ba2ec0ebbc1806d81ad9a11

URL: https://github.com/llvm/llvm-project/commit/661881d43633c00e1ba2ec0ebbc1806d81ad9a11
DIFF: https://github.com/llvm/llvm-project/commit/661881d43633c00e1ba2ec0ebbc1806d81ad9a11.diff

LOG: [X86] Add AMX-FP16 instructions.

Differential Revision: https://reviews.llvm.org/D135941

Added: 
    clang/lib/Headers/amxfp16intrin.h
    clang/test/CodeGen/amx_fp16.c
    llvm/test/CodeGen/X86/amx_fp16_intrinsics.ll
    llvm/test/MC/Disassembler/X86/AMX/x86-64-amx-tile-fp16.txt
    llvm/test/MC/X86/AMX/x86-64-amx-fp16-att.s
    llvm/test/MC/X86/AMX/x86-64-amx-fp16-intel.s

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/BuiltinsX86_64.def
    clang/include/clang/Driver/Options.td
    clang/lib/Basic/Targets/X86.cpp
    clang/lib/Basic/Targets/X86.h
    clang/lib/Headers/CMakeLists.txt
    clang/lib/Headers/cpuid.h
    clang/lib/Headers/immintrin.h
    clang/lib/Sema/SemaChecking.cpp
    clang/test/CodeGen/X86/amx_errors.c
    clang/test/Driver/x86-target-features.c
    clang/test/Preprocessor/x86_target_features.c
    llvm/docs/ReleaseNotes.rst
    llvm/include/llvm/IR/IntrinsicsX86.td
    llvm/include/llvm/Support/X86TargetParser.def
    llvm/lib/Support/Host.cpp
    llvm/lib/Support/X86TargetParser.cpp
    llvm/lib/Target/X86/X86.td
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/lib/Target/X86/X86InstrAMX.td
    llvm/lib/Target/X86/X86InstrInfo.td

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 79112e9420211..0dec5de56d38f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -595,6 +595,7 @@ X86 Support in Clang
 --------------------
 - Support ``-mindirect-branch-cs-prefix`` for call and jmp to indirect thunk.
 - Fix 32-bit ``__fastcall`` and ``__vectorcall`` ABI mismatch with MSVC.
+- Add ISA of ``AMX-FP16`` which support ``_tile_dpfp16ps``.
 - Switch ``AVX512-BF16`` intrinsics types from ``short`` to ``__bf16``.
 - Add support for ``PREFETCHI`` instructions.
 

diff  --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def
index 0a066136a1975..a1f6eb5a8e19f 100644
--- a/clang/include/clang/Basic/BuiltinsX86_64.def
+++ b/clang/include/clang/Basic/BuiltinsX86_64.def
@@ -135,6 +135,9 @@ TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vUOi", "n", "ptwrite")
 
 TARGET_BUILTIN(__builtin_ia32_prefetchi, "vvC*Ui", "nc", "prefetchi")
 
+// AMX_FP16 FP16
+TARGET_BUILTIN(__builtin_ia32_tdpfp16ps, "vIUcIUcIUc", "n", "amx-fp16")
+
 #undef BUILTIN
 #undef TARGET_BUILTIN
 #undef TARGET_HEADER_BUILTIN

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0819ab51c922d..b5b04de5eaafe 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4522,6 +4522,8 @@ def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
 def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
 def mamx_bf16 : Flag<["-"], "mamx-bf16">, Group<m_x86_Features_Group>;
 def mno_amx_bf16 : Flag<["-"], "mno-amx-bf16">, Group<m_x86_Features_Group>;
+def mamx_fp16 : Flag<["-"], "mamx-fp16">, Group<m_x86_Features_Group>;
+def mno_amx_fp16 : Flag<["-"], "mno-amx-fp16">, Group<m_x86_Features_Group>;
 def mamx_int8 : Flag<["-"], "mamx-int8">, Group<m_x86_Features_Group>;
 def mno_amx_int8 : Flag<["-"], "mno-amx-int8">, Group<m_x86_Features_Group>;
 def mamx_tile : Flag<["-"], "mamx-tile">, Group<m_x86_Features_Group>;

diff  --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 17a139a04c430..544fcad296bea 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -328,6 +328,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       HasHRESET = true;
     } else if (Feature == "+amx-bf16") {
       HasAMXBF16 = true;
+    } else if (Feature == "+amx-fp16") {
+      HasAMXFP16 = true;
     } else if (Feature == "+amx-int8") {
       HasAMXINT8 = true;
     } else if (Feature == "+amx-tile") {
@@ -778,6 +780,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
     Builder.defineMacro("__AMXINT8__");
   if (HasAMXBF16)
     Builder.defineMacro("__AMXBF16__");
+  if (HasAMXFP16)
+    Builder.defineMacro("__AMXFP16__");
   if (HasAVXVNNI)
     Builder.defineMacro("__AVXVNNI__");
   if (HasSERIALIZE)
@@ -881,6 +885,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
       .Case("adx", true)
       .Case("aes", true)
       .Case("amx-bf16", true)
+      .Case("amx-fp16", true)
       .Case("amx-int8", true)
       .Case("amx-tile", true)
       .Case("avx", true)
@@ -976,6 +981,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
       .Case("adx", HasADX)
       .Case("aes", HasAES)
       .Case("amx-bf16", HasAMXBF16)
+      .Case("amx-fp16", HasAMXFP16)
       .Case("amx-int8", HasAMXINT8)
       .Case("amx-tile", HasAMXTILE)
       .Case("avxvnni", HasAVXVNNI)

diff  --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index cb1c186a4ad54..5de6ffcbd07a5 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -137,6 +137,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
   bool HasPTWRITE = false;
   bool HasINVPCID = false;
   bool HasENQCMD = false;
+  bool HasAMXFP16 = false;
   bool HasKL = false;      // For key locker
   bool HasWIDEKL = false; // For wide key locker
   bool HasHRESET = false;

diff  --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index a095c938bdf36..1bdc24afd71fe 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -111,6 +111,7 @@ set(x86_files
 # Intrinsics
   adxintrin.h
   ammintrin.h
+  amxfp16intrin.h
   amxintrin.h
   avx2intrin.h
   avx512bf16intrin.h

diff  --git a/clang/lib/Headers/amxfp16intrin.h b/clang/lib/Headers/amxfp16intrin.h
new file mode 100644
index 0000000000000..84859a1ec1a39
--- /dev/null
+++ b/clang/lib/Headers/amxfp16intrin.h
@@ -0,0 +1,58 @@
+/*===------------- amxfp16intrin.h - AMX_FP16 intrinsics -*- C++ -*---------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===------------------------------------------------------------------------===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use <amxfp16intrin.h> directly; use <immintrin.h> instead."
+#endif /* __IMMINTRIN_H */
+
+#ifndef __AMX_FP16INTRIN_H
+#define __AMX_FP16INTRIN_H
+#ifdef __x86_64__
+
+/// Compute dot-product of FP16 (16-bit) floating-point pairs in tiles \a a
+///    and \a b, accumulating the intermediate single-precision (32-bit)
+///    floating-point elements with elements in \a dst, and store the 32-bit
+///    result back to tile \a dst.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// void _tile_dpfp16ps (__tile dst, __tile a, __tile b)
+/// \endcode
+///
+/// \code{.operation}
+/// FOR m := 0 TO dst.rows - 1
+///	tmp := dst.row[m]
+///	FOR k := 0 TO (a.colsb / 4) - 1
+///		FOR n := 0 TO (dst.colsb / 4) - 1
+///			tmp.fp32[n] += FP32(a.row[m].fp16[2*k+0]) *
+///					FP32(b.row[k].fp16[2*n+0])
+///			tmp.fp32[n] += FP32(a.row[m].fp16[2*k+1]) *
+///					FP32(b.row[k].fp16[2*n+1])
+///		ENDFOR
+///	ENDFOR
+///	write_row_and_zero(dst, m, tmp, dst.colsb)
+/// ENDFOR
+/// zero_upper_rows(dst, dst.rows)
+/// zero_tileconfig_start()
+/// \endcode
+///
+/// This intrinsic corresponds to the \c TDPFP16PS instruction.
+///
+/// \param dst
+///    The destination tile. Max size is 1024 Bytes.
+/// \param a
+///    The 1st source tile. Max size is 1024 Bytes.
+/// \param b
+///    The 2nd source tile. Max size is 1024 Bytes.
+#define _tile_dpfp16ps(dst, a, b)                                \
+  __builtin_ia32_tdpfp16ps(dst, a, b)
+
+#endif /* __x86_64__ */
+#endif /* __AMX_FP16INTRIN_H */

diff  --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h
index 7d823bab43187..d7ae800638460 100644
--- a/clang/lib/Headers/cpuid.h
+++ b/clang/lib/Headers/cpuid.h
@@ -202,6 +202,7 @@
 /* Features in %eax for leaf 7 sub-leaf 1 */
 #define bit_AVXVNNI       0x00000010
 #define bit_AVX512BF16    0x00000020
+#define bit_AMXFP16       0x00200000
 #define bit_HRESET        0x00400000
 
 /* Features in %edx for leaf 7 sub-leaf 1 */

diff  --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h
index f4e4ceaefb2e3..6e06277489214 100644
--- a/clang/lib/Headers/immintrin.h
+++ b/clang/lib/Headers/immintrin.h
@@ -508,6 +508,10 @@ _storebe_i64(void * __P, long long __D) {
     defined(__INVPCID__)
 #include <invpcidintrin.h>
 #endif
+#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
+    defined(__AMXFP16__)
+#include <amxfp16intrin.h>
+#endif
 
 #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
     defined(__KL__) || defined(__WIDEKL__)

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 662f0aee1a731..0727433fbc43c 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5026,6 +5026,7 @@ bool Sema::CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall) {
   case X86::BI__builtin_ia32_tdpbusd:
   case X86::BI__builtin_ia32_tdpbuud:
   case X86::BI__builtin_ia32_tdpbf16ps:
+  case X86::BI__builtin_ia32_tdpfp16ps:
     return CheckX86BuiltinTileRangeAndDuplicate(TheCall, {0, 1, 2});
   }
 }

diff  --git a/clang/test/CodeGen/X86/amx_errors.c b/clang/test/CodeGen/X86/amx_errors.c
index 13a2b33b5a0a2..52f54617a23a0 100644
--- a/clang/test/CodeGen/X86/amx_errors.c
+++ b/clang/test/CodeGen/X86/amx_errors.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-tile -target-feature +amx-int8 -target-feature +amx-bf16 -emit-llvm -fsyntax-only -verify
+// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-tile   \
+// RUN: -target-feature +amx-int8 -target-feature +amx-bf16 -target-feature +amx-fp16 -emit-llvm -fsyntax-only -verify
 
 #include <immintrin.h>
 
@@ -14,4 +15,7 @@ void test_amx(void *data) {
   _tile_dpbsud(7, 1, 7); // expected-error {{tile arguments must refer to 
diff erent tiles}}
   _tile_dpbsud(4, 3, 3); // expected-error {{tile arguments must refer to 
diff erent tiles}}
   _tile_dpbf16ps(4, 3, 3); // expected-error {{tile arguments must refer to 
diff erent tiles}}
+  _tile_dpfp16ps(1, 1, 3); // expected-error {{tile arguments must refer to 
diff erent tiles}}
+  _tile_dpfp16ps(1, 2, 1); // expected-error {{tile arguments must refer to 
diff erent tiles}}
+  _tile_dpfp16ps(1, 2, 2); // expected-error {{tile arguments must refer to 
diff erent tiles}}
 }

diff  --git a/clang/test/CodeGen/amx_fp16.c b/clang/test/CodeGen/amx_fp16.c
new file mode 100644
index 0000000000000..e22f853a7e6af
--- /dev/null
+++ b/clang/test/CodeGen/amx_fp16.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown \
+// RUN: -target-feature +amx-tile -target-feature +amx-int8 -target-feature +amx-bf16 -target-feature +amx-fp16 -emit-llvm -o - -Wall -Werror -pedantic \
+// RUN: -Wno-gnu-statement-expression| FileCheck %s
+
+#include <immintrin.h>
+#include <stddef.h>
+void test_tile_dpfp16ps(void) {
+  // CHECK-LABEL: @test_tile_dpfp16ps
+  // CHECK: call void @llvm.x86.tdpfp16ps(i8 1, i8 2, i8 3)
+  _tile_dpfp16ps(1, 2, 3);
+}

diff  --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c
index d113eeb39febd..69742f105cf98 100644
--- a/clang/test/Driver/x86-target-features.c
+++ b/clang/test/Driver/x86-target-features.c
@@ -290,6 +290,13 @@
 // AMX-INT8: "-target-feature" "+amx-int8"
 // NO-AMX-INT8: "-target-feature" "-amx-int8"
 
+// RUN: %clang --target=x86_64 -mamx-fp16 %s \
+// RUN: -### -o %t.o 2>&1 | FileCheck -check-prefix=AMX-FP16 %s
+// RUN: %clang --target=x86_64 -mno-amx-fp16 \
+// RUN: %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-AMX-FP16 %s
+// AMX-FP16: "-target-feature" "+amx-fp16"
+// NO-AMX-FP16: "-target-feature" "-amx-fp16"
+
 // RUN: %clang --target=i386 -march=i386 -mhreset %s -### 2>&1 | FileCheck -check-prefix=HRESET %s
 // RUN: %clang --target=i386 -march=i386 -mno-hreset %s -### 2>&1 | FileCheck -check-prefix=NO-HRESET %s
 // HRESET: "-target-feature" "+hreset"

diff  --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c
index c9258bd5fd1da..24d8819586655 100644
--- a/clang/test/Preprocessor/x86_target_features.c
+++ b/clang/test/Preprocessor/x86_target_features.c
@@ -545,6 +545,20 @@
 
 // NOUINTR-NOT: #define __UINTR__ 1
 
+// RUN: %clang -target x86_64-unknown-linux-gnu -march=atom -mamx-fp16 -x c \
+// RUN: -E -dM -o - %s | FileCheck  -check-prefix=AMX-FP16 %s
+
+// AMX-FP16: #define __AMXFP16__ 1
+// AMX-FP16: #define __AMXTILE__ 1
+
+// RUN: %clang -target x86_64-unknown-linux-gnu -march=atom -mno-amx-fp16 \
+// RUN: -x c -E -dM -o - %s | FileCheck  -check-prefix=NO-AMX-FP16 %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -march=atom -mamx-fp16 \
+// RUN: -mno-amx-tile -x c -E -dM -o - %s | FileCheck  -check-prefix=NO-AMX-FP16 %s
+
+// NO-AMX-FP16-NOT: #define __AMXFP16__ 1
+// NO-AMX-FP16-NOT: #define __AMXTILE__ 1
+
 // RUN: %clang -target i386-unknown-unknown -march=atom -mavxvnni -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVXVNNI %s
 
 // AVXVNNI: #define __AVX2__ 1

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 536d1c7cc3ef3..f8e9480f8ded9 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -138,6 +138,7 @@ Changes to the X86 Backend
 
 * Add support for the ``RDMSRLIST and WRMSRLIST`` instructions.
 * Add support for the ``WRMSRNS`` instruction.
+* Support ISA of ``AMX-FP16`` which contains ``tdpfp16ps`` instruction.
 
 Changes to the OCaml bindings
 -----------------------------

diff  --git a/llvm/include/llvm/IR/IntrinsicsX86.td b/llvm/include/llvm/IR/IntrinsicsX86.td
index a3ec128b75022..8b8e7c7fbee58 100644
--- a/llvm/include/llvm/IR/IntrinsicsX86.td
+++ b/llvm/include/llvm/IR/IntrinsicsX86.td
@@ -5115,6 +5115,14 @@ let TargetPrefix = "x86" in {
               Intrinsic<[llvm_anyvector_ty], [llvm_x86amx_ty], [IntrNoMem]>;
 }
 
+//===----------------------------------------------------------------------===//
+let TargetPrefix = "x86" in {
+// AMX_FP16 - Intel FP16 AMX extensions
+  def int_x86_tdpfp16ps : ClangBuiltin<"__builtin_ia32_tdpfp16ps">,
+                          Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
+                                    [ImmArg<ArgIndex<0>>,
+                                    ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+}
 //===----------------------------------------------------------------------===//
 // UINTR - User Level Interrupt
 

diff  --git a/llvm/include/llvm/Support/X86TargetParser.def b/llvm/include/llvm/Support/X86TargetParser.def
index a617d498746a6..39c5cff19a250 100644
--- a/llvm/include/llvm/Support/X86TargetParser.def
+++ b/llvm/include/llvm/Support/X86TargetParser.def
@@ -202,6 +202,7 @@ X86_FEATURE       (XSAVEOPT,        "xsaveopt")
 X86_FEATURE       (XSAVES,          "xsaves")
 X86_FEATURE       (HRESET,          "hreset")
 X86_FEATURE       (AVX512FP16,      "avx512fp16")
+X86_FEATURE       (AMX_FP16,        "amx-fp16")
 X86_FEATURE       (AVXVNNI,         "avxvnni")
 // These features aren't really CPU features, but the frontend can set them.
 X86_FEATURE       (RETPOLINE_EXTERNAL_THUNK,    "retpoline-external-thunk")

diff  --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp
index 1cf67aadea13e..03f0a6059dc19 100644
--- a/llvm/lib/Support/Host.cpp
+++ b/llvm/lib/Support/Host.cpp
@@ -1807,6 +1807,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
       MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
   Features["avxvnni"]    = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
   Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
+  Features["amxfp16"] =    HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave;
   Features["hreset"]     = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
   Features["prefetchi"]  = HasLeaf7Subleaf1 && ((EDX >> 14) & 1);
 

diff  --git a/llvm/lib/Support/X86TargetParser.cpp b/llvm/lib/Support/X86TargetParser.cpp
index 78cb0730a775d..6f22f78618c2e 100644
--- a/llvm/lib/Support/X86TargetParser.cpp
+++ b/llvm/lib/Support/X86TargetParser.cpp
@@ -578,6 +578,7 @@ constexpr FeatureBitset ImpliedFeaturesXOP = FeatureFMA4;
 // AMX Features
 constexpr FeatureBitset ImpliedFeaturesAMX_TILE = {};
 constexpr FeatureBitset ImpliedFeaturesAMX_BF16 = FeatureAMX_TILE;
+constexpr FeatureBitset ImpliedFeaturesAMX_FP16 = FeatureAMX_TILE;
 constexpr FeatureBitset ImpliedFeaturesAMX_INT8 = FeatureAMX_TILE;
 constexpr FeatureBitset ImpliedFeaturesHRESET = {};
 

diff  --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index c34d803d4fdc7..58d39a8d755cc 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -257,6 +257,10 @@ def FeatureAMXINT8     : SubtargetFeature<"amx-int8", "HasAMXINT8", "true",
 def FeatureAMXBF16     : SubtargetFeature<"amx-bf16", "HasAMXBF16", "true",
                                       "Support AMX-BF16 instructions",
                                       [FeatureAMXTILE]>;
+def FeatureAMXFP16     : SubtargetFeature<"amx-fp16", "HasAMXFP16", "true",
+                                      "Support AMX amx-fp16 instructions",
+                                      [FeatureAMXTILE]>;
+
 def FeatureINVPCID : SubtargetFeature<"invpcid", "HasINVPCID", "true",
                                       "Invalidate Process-Context Identifier">;
 def FeatureSGX     : SubtargetFeature<"sgx", "HasSGX", "true",

diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 4796c22f19080..769f85bda494b 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -36925,7 +36925,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
   case X86::PTDPBSUD:
   case X86::PTDPBUSD:
   case X86::PTDPBUUD:
-  case X86::PTDPBF16PS: {
+  case X86::PTDPBF16PS:
+  case X86::PTDPFP16PS: {
     unsigned Opc;
     switch (MI.getOpcode()) {
     default: llvm_unreachable("illegal opcode!");
@@ -36934,6 +36935,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
     case X86::PTDPBUSD: Opc = X86::TDPBUSD; break;
     case X86::PTDPBUUD: Opc = X86::TDPBUUD; break;
     case X86::PTDPBF16PS: Opc = X86::TDPBF16PS; break;
+    case X86::PTDPFP16PS: Opc = X86::TDPFP16PS; break;
     }
 
     MachineInstrBuilder MIB = BuildMI(*BB, MI, DL, TII->get(Opc));

diff  --git a/llvm/lib/Target/X86/X86InstrAMX.td b/llvm/lib/Target/X86/X86InstrAMX.td
index 5da06bc87b060..56722ded90d37 100644
--- a/llvm/lib/Target/X86/X86InstrAMX.td
+++ b/llvm/lib/Target/X86/X86InstrAMX.td
@@ -185,3 +185,21 @@ let Predicates = [HasAMXBF16, In64BitMode] in {
     }
   }
 } // HasAMXTILE, HasAMXBF16
+
+//AMX-FP16
+let Predicates = [HasAMXFP16, In64BitMode] in {
+  let SchedRW = [WriteSystem] in {
+    let Constraints = "$src1 = $dst" in {
+      def TDPFP16PS : I<0x5c, MRMSrcReg4VOp3, (outs TILE:$dst),
+                        (ins TILE:$src1, TILE:$src2, TILE:$src3),
+                        "tdpfp16ps\t{$src3, $src2, $src1|$src1, $src2, $src3}",
+                        []>, VEX_4V, T8XD;
+    }
+    let  usesCustomInserter = 1 in {
+      def PTDPFP16PS : PseudoI<(outs), (ins u8imm:$src1,
+                               u8imm:$src2, u8imm:$src3),
+                               [(int_x86_tdpfp16ps timm:$src1,
+                                 timm:$src2, timm:$src3)]>;
+    }
+  }
+} // HasAMXTILE, HasAMXFP16

diff  --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 9da87c44fb3d3..399208d67ed16 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -980,6 +980,7 @@ def HasCX8       : Predicate<"Subtarget->hasCX8()">;
 def HasCX16      : Predicate<"Subtarget->hasCX16()">;
 def HasPCONFIG   : Predicate<"Subtarget->hasPCONFIG()">;
 def HasENQCMD    : Predicate<"Subtarget->hasENQCMD()">;
+def HasAMXFP16   : Predicate<"Subtarget->hasAMXFP16()">;
 def HasKL        : Predicate<"Subtarget->hasKL()">;
 def HasWIDEKL    : Predicate<"Subtarget->hasWIDEKL()">;
 def HasHRESET    : Predicate<"Subtarget->hasHRESET()">;

diff  --git a/llvm/test/CodeGen/X86/amx_fp16_intrinsics.ll b/llvm/test/CodeGen/X86/amx_fp16_intrinsics.ll
new file mode 100644
index 0000000000000..0b7a3008594b2
--- /dev/null
+++ b/llvm/test/CodeGen/X86/amx_fp16_intrinsics.ll
@@ -0,0 +1,13 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+amx-tile,+amx-fp16 | FileCheck %s
+
+; CHECK-LABEL: test_amx:
+; CHECK:       # %bb.0:
+; CHECK:    tdpfp16ps       %tmm1, %tmm2, %tmm3
+
+define void @test_amx() {
+call void @llvm.x86.tdpfp16ps(i8 3, i8 2, i8 1)
+
+ret void
+}
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+declare void @llvm.x86.tdpfp16ps(i8 %tile3, i8 %tile2, i8 %tile1)

diff  --git a/llvm/test/MC/Disassembler/X86/AMX/x86-64-amx-tile-fp16.txt b/llvm/test/MC/Disassembler/X86/AMX/x86-64-amx-tile-fp16.txt
new file mode 100644
index 0000000000000..3bc0a9e875475
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/AMX/x86-64-amx-tile-fp16.txt
@@ -0,0 +1,6 @@
+# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck -check-prefix=ATT %s
+# RUN: llvm-mc --disassemble %s -triple=x86_64 -x86-asm-syntax=intel --output-asm-variant=1 | FileCheck -check-prefix=INTEL %s
+
+# ATT:   tdpfp16ps %tmm5, %tmm4, %tmm3
+# INTEL: tdpfp16ps tmm3, tmm4, tmm5
+0xc4,0xe2,0x53,0x5c,0xdc

diff  --git a/llvm/test/MC/X86/AMX/x86-64-amx-fp16-att.s b/llvm/test/MC/X86/AMX/x86-64-amx-fp16-att.s
new file mode 100644
index 0000000000000..7416fd65e96ef
--- /dev/null
+++ b/llvm/test/MC/X86/AMX/x86-64-amx-fp16-att.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding %s | FileCheck %s
+
+// CHECK:      tdpfp16ps       %tmm5, %tmm4, %tmm3
+// CHECK: encoding: [0xc4,0xe2,0x53,0x5c,0xdc]
+               tdpfp16ps       %tmm5, %tmm4, %tmm3

diff  --git a/llvm/test/MC/X86/AMX/x86-64-amx-fp16-intel.s b/llvm/test/MC/X86/AMX/x86-64-amx-fp16-intel.s
new file mode 100644
index 0000000000000..c0510f61cfcbc
--- /dev/null
+++ b/llvm/test/MC/X86/AMX/x86-64-amx-fp16-intel.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown -x86-asm-syntax=intel -output-asm-variant=1 --show-encoding %s | FileCheck %s
+
+// CHECK:      tdpfp16ps       tmm3, tmm4, tmm5
+// CHECK: encoding: [0xc4,0xe2,0x53,0x5c,0xdc]
+               tdpfp16ps       tmm3, tmm4, tmm5


        


More information about the llvm-commits mailing list