[clang] 661881d - [X86] Add AMX-FP16 instructions.
Xiang1 Zhang via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 21 17:05:49 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 cfe-commits
mailing list