Add avx10.2nvl family of targets (Intel Nova Lake)
Add the avx10.2nvl-x{4,8,16,32,64} x86 target family for Intel Nova Lake
(NVL). NVL implements AVX10.2 but, unlike Diamond Rapids (DMR), has no AMX.
It is therefore modeled as "DMR without AMX": its target hierarchy inherits
from ICL (avx512icl) rather than DMR/GNR, and none of the AMX capabilities
(AmxTile/AmxInt8/AmxBf16/AmxFp16) are advertised. The half-precision
rcp/rsqrt builtins are reused from the shared target-avx512fp16-x*-common.ll
files. The targets require LLVM >= 22 and are gated accordingly throughout.
This commit is contained in:
committed by
aneshlya
parent
1112f68241
commit
4bfe359a35
@@ -46,7 +46,8 @@ jobs:
|
||||
"avx512icl-x4", "avx512icl-x8", "avx512icl-x16", "avx512icl-x64", "avx512icl-x32",
|
||||
"avx512spr-x4", "avx512spr-x8", "avx512spr-x16", "avx512spr-x64", "avx512spr-x32",
|
||||
"avx512gnr-x4", "avx512gnr-x8", "avx512gnr-x16", "avx512gnr-x64", "avx512gnr-x32",
|
||||
"avx10.2dmr-x4", "avx10.2dmr-x8", "avx10.2dmr-x16", "avx10.2dmr-x64", "avx10.2dmr-x32"]
|
||||
"avx10.2dmr-x4", "avx10.2dmr-x8", "avx10.2dmr-x16", "avx10.2dmr-x64", "avx10.2dmr-x32",
|
||||
"avx10.2nvl-x4", "avx10.2nvl-x8", "avx10.2nvl-x16", "avx10.2nvl-x64", "avx10.2nvl-x32"]
|
||||
llvm_sha: ${{ steps.get-llvm-sha.outputs.llvm_sha }}
|
||||
steps:
|
||||
- name: Get LLVM SHA
|
||||
|
||||
@@ -38,7 +38,8 @@ jobs:
|
||||
"avx512icl-x4", "avx512icl-x8", "avx512icl-x16", "avx512icl-x64", "avx512icl-x32",
|
||||
"avx512spr-x4", "avx512spr-x8", "avx512spr-x16", "avx512spr-x64", "avx512spr-x32",
|
||||
"avx512gnr-x4", "avx512gnr-x8", "avx512gnr-x16", "avx512gnr-x64", "avx512gnr-x32",
|
||||
"avx10.2dmr-x4", "avx10.2dmr-x8", "avx10.2dmr-x16", "avx10.2dmr-x64", "avx10.2dmr-x32"]
|
||||
"avx10.2dmr-x4", "avx10.2dmr-x8", "avx10.2dmr-x16", "avx10.2dmr-x64", "avx10.2dmr-x32",
|
||||
"avx10.2nvl-x4", "avx10.2nvl-x8", "avx10.2nvl-x16", "avx10.2nvl-x64", "avx10.2nvl-x32"]
|
||||
steps:
|
||||
- run: echo "Defining targets"
|
||||
|
||||
|
||||
@@ -401,6 +401,10 @@ if (${LLVM_VERSION_NUMBER} VERSION_GREATER_EQUAL "20.1.2")
|
||||
list(APPEND X86_TARGETS avx10_2dmr-x4 avx10_2dmr-x8 avx10_2dmr-x16 avx10_2dmr-x32 avx10_2dmr-x64)
|
||||
endif()
|
||||
|
||||
if (${LLVM_VERSION_NUMBER} VERSION_GREATER_EQUAL "22.0.0")
|
||||
list(APPEND X86_TARGETS avx10_2nvl-x4 avx10_2nvl-x8 avx10_2nvl-x16 avx10_2nvl-x32 avx10_2nvl-x64)
|
||||
endif()
|
||||
|
||||
list(APPEND ARM_TARGETS neon-i8x16 neon-i16x8 neon-i32x4 neon-i32x8 neon-i8x32 neon-i16x16)
|
||||
list(APPEND PPC64_TARGETS vsx-i8x16 vsx-i8x32 vsx-i16x8 vsx-i16x16 vsx-i32x4 vsx-i32x8)
|
||||
list(APPEND RISCV_TARGETS rvv-x4)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
;; Copyright (c) 2026, Intel Corporation
|
||||
;;
|
||||
;; SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
define(`WIDTH',`16')
|
||||
define(`ISA',`NVL_AVX10_2')
|
||||
include(`target-avx10_2-x16-common.ll')
|
||||
include(`target-avx512fp16-x16-common.ll')
|
||||
@@ -0,0 +1,8 @@
|
||||
;; Copyright (c) 2026, Intel Corporation
|
||||
;;
|
||||
;; SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
define(`WIDTH',`32')
|
||||
define(`ISA',`NVL_AVX10_2')
|
||||
include(`target-avx10_2-x32-common.ll')
|
||||
include(`target-avx512fp16-x32-common.ll')
|
||||
@@ -0,0 +1,8 @@
|
||||
;; Copyright (c) 2026, Intel Corporation
|
||||
;;
|
||||
;; SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
define(`WIDTH',`4')
|
||||
define(`ISA',`NVL_AVX10_2')
|
||||
include(`target-avx10_2-x4-common.ll')
|
||||
include(`target-avx512fp16-x4-common.ll')
|
||||
@@ -0,0 +1,8 @@
|
||||
;; Copyright (c) 2026, Intel Corporation
|
||||
;;
|
||||
;; SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
define(`WIDTH',`64')
|
||||
define(`ISA',`NVL_AVX10_2')
|
||||
include(`target-avx10_2-x64-common.ll')
|
||||
include(`target-avx512fp16-x64-common.ll')
|
||||
@@ -0,0 +1,8 @@
|
||||
;; Copyright (c) 2026, Intel Corporation
|
||||
;;
|
||||
;; SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
define(`WIDTH',`8')
|
||||
define(`ISA',`NVL_AVX10_2')
|
||||
include(`target-avx10_2-x8-common.ll')
|
||||
include(`target-avx512fp16-x8-common.ll')
|
||||
@@ -41,6 +41,13 @@ function(define_stdlib_families)
|
||||
list(APPEND AVX10_X32 "avx10_2dmr-x32")
|
||||
list(APPEND AVX10_X64 "avx10_2dmr-x64")
|
||||
endif()
|
||||
if (${LLVM_VERSION_NUMBER} VERSION_GREATER_EQUAL "22.0.0")
|
||||
list(APPEND AVX10_X4 "avx10_2nvl-x4")
|
||||
list(APPEND AVX10_X8 "avx10_2nvl-x8")
|
||||
list(APPEND AVX10_X16 "avx10_2nvl-x16")
|
||||
list(APPEND AVX10_X32 "avx10_2nvl-x32")
|
||||
list(APPEND AVX10_X64 "avx10_2nvl-x64")
|
||||
endif()
|
||||
# Convert lists to comma-separated strings with leading comma
|
||||
foreach(width IN ITEMS X4 X8 X16 X32 X64)
|
||||
if (AVX10_${width})
|
||||
|
||||
+16
-1
@@ -46,6 +46,7 @@ Contents:
|
||||
|
||||
* `Recent Changes to ISPC`_
|
||||
|
||||
+ `Updating ISPC Programs For Changes In ISPC 1.31.0`_
|
||||
+ `Updating ISPC Programs For Changes In ISPC 1.30.0`_
|
||||
+ `Updating ISPC Programs For Changes In ISPC 1.29.0`_
|
||||
+ `Updating ISPC Programs For Changes In ISPC 1.28.0`_
|
||||
@@ -282,6 +283,19 @@ New Architecture Support:
|
||||
* The hyperbolic functions ``sinh``, ``cosh`` and ``tanh`` have also been added
|
||||
to the standard library.
|
||||
|
||||
ISPC Targets:
|
||||
|
||||
* New ``avx10.2nvl-x4``, ``avx10.2nvl-x8``, ``avx10.2nvl-x16``,
|
||||
``avx10.2nvl-x32``, and ``avx10.2nvl-x64`` targets have been added for Intel
|
||||
Nova Lake processors. These targets implement AVX10.2 with full AVX-512
|
||||
support but, unlike the ``avx10.2dmr`` (Diamond Rapids) targets, they do not
|
||||
include AMX. The corresponding predefined macro is ``ISPC_TARGET_AVX10_2NVL``.
|
||||
* The multi-target runtime dispatcher now selects an AMX-bearing server target
|
||||
variant (``avx512spr``, ``avx512gnr``, ``avx10.2dmr``) only when the system
|
||||
supports AMX, instead of relying solely on the ISA ordering. AMX support is
|
||||
checked the same way AVX-512 already is: the CPU must advertise the feature in
|
||||
CPUID and the OS must manage its XSAVE state.
|
||||
|
||||
Updating ISPC Programs For Changes In ISPC 1.30.0
|
||||
-------------------------------------------------
|
||||
|
||||
@@ -1316,6 +1330,7 @@ avx512icl AVX-512 Intel Icelake (2019), AMD Zen4 (2022)
|
||||
avx512spr AVX-512 + AMX Intel Sapphire Rapids (2023)
|
||||
avx512gnr AVX-512 + AMX FP16 Intel Granite Rapids (2024)
|
||||
avx10.2dmr AVX10.2 + AMX Intel Diamond Rapids (2026+)
|
||||
avx10.2nvl AVX10.2 Intel Nova Lake (2026+)
|
||||
neon ARMv8 NEON ARM Cortex-A35/A53/A57 (2012-2015)
|
||||
============= ========================= ===========================================================
|
||||
|
||||
@@ -1479,7 +1494,7 @@ preprocessor runs:
|
||||
* - ISPC
|
||||
- 1
|
||||
- Enables detecting that the ``ispc`` compiler is processing the file
|
||||
* - ISPC_TARGET_{NEON, SSE2, SSE4, AVX, AVX2, AVX512SKX, AVX512ICL, AVX512SPR, AVX512GNR, AVX10_2DMR}
|
||||
* - ISPC_TARGET_{NEON, SSE2, SSE4, AVX, AVX2, AVX512SKX, AVX512ICL, AVX512SPR, AVX512GNR, AVX10_2DMR, AVX10_2NVL}
|
||||
- 1
|
||||
- One of these will be set, depending on the compilation target
|
||||
* - ISPC_POINTER_SIZE
|
||||
|
||||
+13
-5
@@ -360,10 +360,16 @@ def build_LLVM(version_LLVM, folder, debug, selfbuild, extra, openmp, from_valid
|
||||
|
||||
|
||||
def unsupported_llvm_targets(LLVM_VERSION):
|
||||
prohibited_list = {"6.0":["avx512skx-x8", "avx512skx-x4", "avx512skx-x64", "avx512skx-x32"],
|
||||
"7.0":["avx512skx-x8", "avx512skx-x4", "avx512skx-x64", "avx512skx-x32"],
|
||||
"8.0":["avx512skx-x64", "avx512skx-x32"],
|
||||
"9.0":["avx512skx-x64", "avx512skx-x32"]
|
||||
# NVL (Nova Lake) targets are only parsed by ISPC under LLVM 22.0+.
|
||||
nvl_targets = ["avx10.2nvl-x16", "avx10.2nvl-x8", "avx10.2nvl-x4", "avx10.2nvl-x64", "avx10.2nvl-x32"]
|
||||
prohibited_list = {"6.0":["avx512skx-x8", "avx512skx-x4", "avx512skx-x64", "avx512skx-x32"] + nvl_targets,
|
||||
"7.0":["avx512skx-x8", "avx512skx-x4", "avx512skx-x64", "avx512skx-x32"] + nvl_targets,
|
||||
"8.0":["avx512skx-x64", "avx512skx-x32"] + nvl_targets,
|
||||
"9.0":["avx512skx-x64", "avx512skx-x32"] + nvl_targets,
|
||||
"10.0":nvl_targets, "11.0":nvl_targets, "12.0":nvl_targets,
|
||||
"13.0":nvl_targets, "14.0":nvl_targets, "15.0":nvl_targets,
|
||||
"16.0":nvl_targets, "17.0":nvl_targets, "18.1":nvl_targets,
|
||||
"19.1":nvl_targets, "20.1":nvl_targets, "21.1":nvl_targets,
|
||||
}
|
||||
if LLVM_VERSION in prohibited_list:
|
||||
return prohibited_list[LLVM_VERSION]
|
||||
@@ -428,7 +434,9 @@ def check_targets():
|
||||
("GNR", [["avx512gnr-x16", "avx512gnr-x8", "avx512gnr-x4", "avx512gnr-x64", "avx512gnr-x32"],
|
||||
["SSE2", "SSE4.1", "SSE4.2", "AVX", "AVX1.1", "AVX2", "AVX2VNNI", "SKX", "ICL", "SPR", "GNR"], "-gnr", False]),
|
||||
("DMR", [["avx10.2dmr-x16", "avx10.2dmr-x8", "avx10.2dmr-x4", "avx10.2dmr-x64", "avx10.2dmr-x32"],
|
||||
["SSE2", "SSE4.1", "SSE4.2", "AVX", "AVX1.1", "AVX2", "AVX2VNNI", "SKX", "ICL", "SPR", "GNR", "DMR"], "-dmr", False])
|
||||
["SSE2", "SSE4.1", "SSE4.2", "AVX", "AVX1.1", "AVX2", "AVX2VNNI", "SKX", "ICL", "SPR", "GNR", "DMR"], "-dmr", False]),
|
||||
("NVL", [["avx10.2nvl-x16", "avx10.2nvl-x8", "avx10.2nvl-x4", "avx10.2nvl-x64", "avx10.2nvl-x32"],
|
||||
["SSE2", "SSE4.1", "SSE4.2", "AVX", "AVX1.1", "AVX2", "AVX2VNNI", "SKX", "ICL", "NVL"], "-nvl", False])
|
||||
])
|
||||
|
||||
hw_arch = take_lines(check_isa, "first").split()[1]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2025, Intel Corporation
|
||||
# Copyright (c) 2025-2026, Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
@@ -163,13 +163,20 @@ class ISPCTarget:
|
||||
'neon-i32x4': 'generic-i32x4',
|
||||
'neon-i32x8': 'generic-i32x8',
|
||||
|
||||
# AVX10.2 targets
|
||||
# AVX10.2 DMR targets
|
||||
'avx10.2dmr-x4': 'avx512gnr-x4',
|
||||
'avx10.2dmr-x8': 'avx512gnr-x8',
|
||||
'avx10.2dmr-x16': 'avx512gnr-x16',
|
||||
'avx10.2dmr-x32': 'avx512gnr-x32',
|
||||
'avx10.2dmr-x64': 'avx512gnr-x64',
|
||||
|
||||
# AVX10.2 NVL targets (NVL doesn't have AMX, so inherit it from ICL)
|
||||
'avx10.2nvl-x4': 'avx512icl-x4',
|
||||
'avx10.2nvl-x8': 'avx512icl-x8',
|
||||
'avx10.2nvl-x16': 'avx512icl-x16',
|
||||
'avx10.2nvl-x32': 'avx512icl-x32',
|
||||
'avx10.2nvl-x64': 'avx512icl-x64',
|
||||
|
||||
# AVX512 hierarchy
|
||||
'avx512gnr-x4': 'avx512spr-x4',
|
||||
'avx512spr-x4': 'avx512icl-x4',
|
||||
@@ -238,7 +245,7 @@ class ISPCTarget:
|
||||
|
||||
@classmethod
|
||||
def normalize_target_name(cls, target: str) -> str:
|
||||
"""Normalize target name format (e.g., avx512spr-x4 -> avx512spr_x4, avx10.2dmr-x4 -> avx10_2dmr_x4)"""
|
||||
"""Normalize target name format (e.g., avx512spr-x4 -> avx512spr_x4, avx10.2dmr-x4 -> avx10_2dmr_x4, avx10.2nvl-x4 -> avx10_2nvl_x4)"""
|
||||
return target.replace('-', '_').replace('.', '_')
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -492,6 +492,14 @@ std::unordered_map<ISPCTarget, ISPCTarget> targetParentMap = {
|
||||
{ISPCTarget::avx10_2dmr_x32, ISPCTarget::avx512gnr_x32},
|
||||
{ISPCTarget::avx10_2dmr_x64, ISPCTarget::avx512gnr_x64},
|
||||
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
{ISPCTarget::avx10_2nvl_x4, ISPCTarget::avx512icl_x4},
|
||||
{ISPCTarget::avx10_2nvl_x8, ISPCTarget::avx512icl_x8},
|
||||
{ISPCTarget::avx10_2nvl_x16, ISPCTarget::avx512icl_x16},
|
||||
{ISPCTarget::avx10_2nvl_x32, ISPCTarget::avx512icl_x32},
|
||||
{ISPCTarget::avx10_2nvl_x64, ISPCTarget::avx512icl_x64},
|
||||
#endif
|
||||
|
||||
{ISPCTarget::avx512gnr_x4, ISPCTarget::avx512spr_x4},
|
||||
{ISPCTarget::avx512spr_x4, ISPCTarget::avx512icl_x4},
|
||||
{ISPCTarget::avx512icl_x4, ISPCTarget::avx512skx_x4},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2025, Intel Corporation
|
||||
Copyright (c) 2025-2026, Intel Corporation
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@@ -22,7 +22,8 @@ enum ISA {
|
||||
ICL_AVX512 = 9,
|
||||
SPR_AVX512 = 10,
|
||||
GNR_AVX512 = 11,
|
||||
DMR_AVX10_2 = 12,
|
||||
NVL_AVX10_2 = 12,
|
||||
DMR_AVX10_2 = 13,
|
||||
|
||||
COUNT
|
||||
};
|
||||
@@ -193,10 +194,14 @@ UNUSED_ATTR static enum ISA get_x86_isa() {
|
||||
UNUSED_ATTR int cpx = clx && avx512_bf16;
|
||||
int icl =
|
||||
clx && avx512_vbmi2 && avx512_gfni && avx512_vaes && avx512_vpclmulqdq && avx512_bitalg && avx512_vpopcntdq;
|
||||
// Server platforms
|
||||
UNUSED_ATTR int tgl = icl && avx512_vp2intersect;
|
||||
int spr =
|
||||
icl && avx512_bf16 && avx512_amx_bf16 && avx512_amx_tile && avx512_amx_int8 && avx_vnni && avx512_fp16;
|
||||
int gnr = spr && amxfp16 && prefetchi;
|
||||
// Client platforms
|
||||
UNUSED_ATTR int arl =
|
||||
icl && avxvnniint8 && avxvnniint16 && avxneconvert && sha512 && sm3 && sm4 && avxifma && cmpccxadd;
|
||||
|
||||
int avx10 = (info3[3] & (1 << 19)) != 0;
|
||||
|
||||
@@ -212,13 +217,15 @@ UNUSED_ATTR static enum ISA get_x86_isa() {
|
||||
// clang-format on
|
||||
|
||||
// Diamond Rapids: DMR = GNR + AVX10_2 + APX + ... (For the whole list see x86TargetParser.cpp)
|
||||
// TODO: according to spec the presence of avx10.2 should cover the whole set of features, but let's keep it
|
||||
// now aligned with LLVM logic
|
||||
int dmr = gnr && avx10_2 && apx && cmpccxadd && avxneconvert && avxifma && avxvnniint8 && avxvnniint16 &&
|
||||
amxcomplex && sha512 && sm3 && sm4;
|
||||
// Nova Lake: NVL = ARL + AVX10_2 + APX + ...
|
||||
int nvl = arl && avx10_2 && apx && avx512_fp16;
|
||||
|
||||
if (dmr) {
|
||||
return DMR_AVX10_2;
|
||||
} else if (nvl) {
|
||||
return NVL_AVX10_2;
|
||||
}
|
||||
}
|
||||
if (gnr) {
|
||||
|
||||
+131
-22
@@ -257,6 +257,16 @@ static ISPCTarget lGetSystemISA() {
|
||||
return ISPCTarget::avx512spr_x16;
|
||||
case Target::ISA::GNR_AVX512:
|
||||
return ISPCTarget::avx512gnr_x16;
|
||||
case Target::ISA::NVL_AVX10_2:
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
return ISPCTarget::avx10_2nvl_x8;
|
||||
#else
|
||||
// NVL targets are only available under LLVM 22.0+. On older LLVM we
|
||||
// still detect NVL hardware (lGetSystemISA), but cannot emit an NVL
|
||||
// target, so fall back to ICL: NVL is a superset of ICL (full AVX-512
|
||||
// without AMX), so an ICL build runs correctly on NVL hardware.
|
||||
return ISPCTarget::avx512icl_x8;
|
||||
#endif
|
||||
case Target::ISA::DMR_AVX10_2:
|
||||
return ISPCTarget::avx10_2dmr_x16;
|
||||
default:
|
||||
@@ -355,6 +365,9 @@ typedef enum {
|
||||
CPU_ARL,
|
||||
CPU_LNL,
|
||||
CPU_DMR,
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
CPU_NVL,
|
||||
#endif
|
||||
// Zen1 to Zen5
|
||||
CPU_ZNVER1,
|
||||
CPU_ZNVER2,
|
||||
@@ -470,10 +483,14 @@ std::map<DeviceType, std::set<std::string>> CPUFeatures = {
|
||||
{"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2", "avx512", "avx_vnni", "avx512_vnni", "amxtile",
|
||||
"amxint8", "amxfp16"}},
|
||||
{CPU_DMR,
|
||||
{"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2", "avx512", "avx_vnni", "avx512_vnni", "amxtile",
|
||||
"amxint8", "amxfp16"}},
|
||||
{"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2", "avx512", "avx10", "avx_vnni", "avx512_vnni",
|
||||
"amxtile", "amxint8", "amxfp16"}},
|
||||
{CPU_ARL, {"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2", "avx_vnni"}},
|
||||
{CPU_LNL, {"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2", "avx_vnni"}},
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
{CPU_NVL,
|
||||
{"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2", "avx512", "avx10", "avx_vnni", "avx512_vnni"}},
|
||||
#endif
|
||||
{CPU_ZNVER1, {"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2"}},
|
||||
{CPU_ZNVER2, {"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2"}},
|
||||
{CPU_ZNVER3, {"mmx", "sse", "sse2", "ssse3", "sse41", "sse42", "avx", "avx2"}},
|
||||
@@ -598,6 +615,10 @@ class AllCPUs {
|
||||
names[CPU_LNL].push_back("lnl");
|
||||
names[CPU_DMR].push_back("diamondrapids");
|
||||
names[CPU_DMR].push_back("dmr");
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
names[CPU_NVL].push_back("novalake");
|
||||
names[CPU_NVL].push_back("nvl");
|
||||
#endif
|
||||
names[CPU_ZNVER1].push_back("znver1");
|
||||
names[CPU_ZNVER2].push_back("znver2");
|
||||
names[CPU_ZNVER2].push_back("ps5");
|
||||
@@ -676,6 +697,14 @@ class AllCPUs {
|
||||
compat[CPU_LNL] =
|
||||
Set(CPU_LNL, CPU_x86_64, CPU_Bonnell, CPU_Penryn, CPU_Core2, CPU_Nehalem, CPU_Silvermont, CPU_SandyBridge,
|
||||
CPU_IvyBridge, CPU_Haswell, CPU_Broadwell, CPU_Skylake, CPU_ADL, CPU_ARL, CPU_None);
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
// NVL has full AVX-512 but no AMX, so it is backward-compatible with the
|
||||
// non-AMX AVX-512 CPUs (SKX, ICL, ICX, TGL) and the client lineage, but
|
||||
// not with the AMX-capable server CPUs (SPR, GNR, DMR).
|
||||
compat[CPU_NVL] = Set(CPU_NVL, CPU_x86_64, CPU_Bonnell, CPU_Penryn, CPU_Core2, CPU_Nehalem, CPU_Silvermont,
|
||||
CPU_SandyBridge, CPU_IvyBridge, CPU_Haswell, CPU_Broadwell, CPU_Skylake, CPU_SKX, CPU_ICL,
|
||||
CPU_ICX, CPU_TGL, CPU_ADL, CPU_ARL, CPU_LNL, CPU_None);
|
||||
#endif
|
||||
compat[CPU_TGL] =
|
||||
Set(CPU_TGL, CPU_x86_64, CPU_Bonnell, CPU_Penryn, CPU_Core2, CPU_Nehalem, CPU_Silvermont, CPU_SandyBridge,
|
||||
CPU_IvyBridge, CPU_Haswell, CPU_Broadwell, CPU_Skylake, CPU_SKX, CPU_ICL, CPU_ICX, CPU_None);
|
||||
@@ -1057,11 +1086,14 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
case CPU_LNL:
|
||||
m_ispc_target = ISPCTarget::avx2vnni_i32x8;
|
||||
break;
|
||||
|
||||
case CPU_DMR:
|
||||
m_ispc_target = ISPCTarget::avx10_2dmr_x16;
|
||||
break;
|
||||
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
case CPU_NVL:
|
||||
m_ispc_target = ISPCTarget::avx10_2nvl_x8;
|
||||
break;
|
||||
#endif
|
||||
case CPU_ZNVER1:
|
||||
case CPU_ZNVER2:
|
||||
case CPU_ZNVER3:
|
||||
@@ -1676,7 +1708,10 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
CPUfromISA = (m_ispc_target == ISPCTarget::avx512gnr_x32) ? CPU_GNR : CPU_SPR;
|
||||
break;
|
||||
case ISPCTarget::avx10_2dmr_x4:
|
||||
this->m_isa = Target::DMR_AVX10_2;
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
case ISPCTarget::avx10_2nvl_x4:
|
||||
#endif
|
||||
this->m_isa = (m_ispc_target == ISPCTarget::avx10_2dmr_x4) ? Target::DMR_AVX10_2 : Target::NVL_AVX10_2;
|
||||
this->m_nativeVectorWidth = 16;
|
||||
this->m_nativeVectorAlignment = 64;
|
||||
this->m_dataTypeWidth = 32;
|
||||
@@ -1687,14 +1722,25 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
setCapabilities({TargetCapability::HalfConverts, TargetCapability::HalfFullSupport, TargetCapability::Rand,
|
||||
TargetCapability::Fp16Support, TargetCapability::IntelVNNI, TargetCapability::IntelVNNI_Int8,
|
||||
TargetCapability::IntelVNNI_Int16, TargetCapability::ConflictDetection,
|
||||
TargetCapability::Rsqrtd, TargetCapability::Rcpd, TargetCapability::AmxTile,
|
||||
TargetCapability::AmxInt8, TargetCapability::AmxBf16, TargetCapability::AmxFp16});
|
||||
TargetCapability::Rsqrtd, TargetCapability::Rcpd});
|
||||
// DMR has AMX capabilities, NVL does not (under LLVM < 22 only DMR reaches this case).
|
||||
setCapability(TargetCapability::AmxTile, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxInt8, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxBf16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxFp16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
CPUfromISA = (this->m_isa == Target::DMR_AVX10_2) ? CPU_DMR : CPU_NVL;
|
||||
#else
|
||||
CPUfromISA = CPU_DMR;
|
||||
#endif
|
||||
this->m_funcAttributes.push_back(std::make_pair("prefer-vector-width", "256"));
|
||||
this->m_funcAttributes.push_back(std::make_pair("min-legal-vector-width", "256"));
|
||||
break;
|
||||
case ISPCTarget::avx10_2dmr_x8:
|
||||
this->m_isa = Target::DMR_AVX10_2;
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
case ISPCTarget::avx10_2nvl_x8:
|
||||
#endif
|
||||
this->m_isa = (m_ispc_target == ISPCTarget::avx10_2dmr_x8) ? Target::DMR_AVX10_2 : Target::NVL_AVX10_2;
|
||||
this->m_nativeVectorWidth = 16;
|
||||
this->m_nativeVectorAlignment = 64;
|
||||
this->m_dataTypeWidth = 32;
|
||||
@@ -1705,14 +1751,25 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
setCapabilities({TargetCapability::HalfConverts, TargetCapability::HalfFullSupport, TargetCapability::Rand,
|
||||
TargetCapability::Fp16Support, TargetCapability::IntelVNNI, TargetCapability::IntelVNNI_Int8,
|
||||
TargetCapability::IntelVNNI_Int16, TargetCapability::ConflictDetection,
|
||||
TargetCapability::Rsqrtd, TargetCapability::Rcpd, TargetCapability::AmxTile,
|
||||
TargetCapability::AmxInt8, TargetCapability::AmxBf16, TargetCapability::AmxFp16});
|
||||
TargetCapability::Rsqrtd, TargetCapability::Rcpd});
|
||||
// DMR has AMX capabilities, NVL does not (under LLVM < 22 only DMR reaches this case).
|
||||
setCapability(TargetCapability::AmxTile, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxInt8, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxBf16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxFp16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
CPUfromISA = (this->m_isa == Target::DMR_AVX10_2) ? CPU_DMR : CPU_NVL;
|
||||
#else
|
||||
CPUfromISA = CPU_DMR;
|
||||
#endif
|
||||
this->m_funcAttributes.push_back(std::make_pair("prefer-vector-width", "256"));
|
||||
this->m_funcAttributes.push_back(std::make_pair("min-legal-vector-width", "256"));
|
||||
break;
|
||||
case ISPCTarget::avx10_2dmr_x16:
|
||||
this->m_isa = Target::DMR_AVX10_2;
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
case ISPCTarget::avx10_2nvl_x16:
|
||||
#endif
|
||||
this->m_isa = (m_ispc_target == ISPCTarget::avx10_2dmr_x16) ? Target::DMR_AVX10_2 : Target::NVL_AVX10_2;
|
||||
this->m_nativeVectorWidth = 16;
|
||||
this->m_nativeVectorAlignment = 64;
|
||||
this->m_dataTypeWidth = 32;
|
||||
@@ -1723,14 +1780,25 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
setCapabilities({TargetCapability::HalfConverts, TargetCapability::HalfFullSupport, TargetCapability::Rand,
|
||||
TargetCapability::Fp16Support, TargetCapability::IntelVNNI, TargetCapability::IntelVNNI_Int8,
|
||||
TargetCapability::IntelVNNI_Int16, TargetCapability::ConflictDetection,
|
||||
TargetCapability::Rsqrtd, TargetCapability::Rcpd, TargetCapability::AmxTile,
|
||||
TargetCapability::AmxInt8, TargetCapability::AmxBf16, TargetCapability::AmxFp16});
|
||||
TargetCapability::Rsqrtd, TargetCapability::Rcpd});
|
||||
// DMR has AMX capabilities, NVL does not (under LLVM < 22 only DMR reaches this case).
|
||||
setCapability(TargetCapability::AmxTile, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxInt8, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxBf16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxFp16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
CPUfromISA = (this->m_isa == Target::DMR_AVX10_2) ? CPU_DMR : CPU_NVL;
|
||||
#else
|
||||
CPUfromISA = CPU_DMR;
|
||||
#endif
|
||||
this->m_funcAttributes.push_back(std::make_pair("prefer-vector-width", "512"));
|
||||
this->m_funcAttributes.push_back(std::make_pair("min-legal-vector-width", "512"));
|
||||
break;
|
||||
case ISPCTarget::avx10_2dmr_x32:
|
||||
this->m_isa = Target::DMR_AVX10_2;
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
case ISPCTarget::avx10_2nvl_x32:
|
||||
#endif
|
||||
this->m_isa = (m_ispc_target == ISPCTarget::avx10_2dmr_x32) ? Target::DMR_AVX10_2 : Target::NVL_AVX10_2;
|
||||
this->m_nativeVectorWidth = 64;
|
||||
this->m_nativeVectorAlignment = 64;
|
||||
this->m_dataTypeWidth = 16;
|
||||
@@ -1740,13 +1808,23 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
this->m_hasGather = this->m_hasScatter = true;
|
||||
setCapabilities({TargetCapability::HalfConverts, TargetCapability::HalfFullSupport, TargetCapability::Rand,
|
||||
TargetCapability::Fp16Support, TargetCapability::IntelVNNI, TargetCapability::IntelVNNI_Int8,
|
||||
TargetCapability::IntelVNNI_Int16, TargetCapability::ConflictDetection,
|
||||
TargetCapability::AmxTile, TargetCapability::AmxInt8, TargetCapability::AmxBf16,
|
||||
TargetCapability::AmxFp16});
|
||||
TargetCapability::IntelVNNI_Int16, TargetCapability::ConflictDetection});
|
||||
// DMR has AMX capabilities, NVL does not (under LLVM < 22 only DMR reaches this case).
|
||||
setCapability(TargetCapability::AmxTile, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxInt8, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxBf16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxFp16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
CPUfromISA = (this->m_isa == Target::DMR_AVX10_2) ? CPU_DMR : CPU_NVL;
|
||||
#else
|
||||
CPUfromISA = CPU_DMR;
|
||||
#endif
|
||||
break;
|
||||
case ISPCTarget::avx10_2dmr_x64:
|
||||
this->m_isa = Target::DMR_AVX10_2;
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
case ISPCTarget::avx10_2nvl_x64:
|
||||
#endif
|
||||
this->m_isa = (m_ispc_target == ISPCTarget::avx10_2dmr_x64) ? Target::DMR_AVX10_2 : Target::NVL_AVX10_2;
|
||||
this->m_nativeVectorWidth = 64;
|
||||
this->m_nativeVectorAlignment = 64;
|
||||
this->m_dataTypeWidth = 8;
|
||||
@@ -1756,11 +1834,28 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
this->m_hasGather = this->m_hasScatter = true;
|
||||
setCapabilities({TargetCapability::HalfConverts, TargetCapability::HalfFullSupport, TargetCapability::Rand,
|
||||
TargetCapability::Fp16Support, TargetCapability::IntelVNNI, TargetCapability::IntelVNNI_Int8,
|
||||
TargetCapability::IntelVNNI_Int16, TargetCapability::ConflictDetection,
|
||||
TargetCapability::AmxTile, TargetCapability::AmxInt8, TargetCapability::AmxBf16,
|
||||
TargetCapability::AmxFp16});
|
||||
TargetCapability::IntelVNNI_Int16, TargetCapability::ConflictDetection});
|
||||
// DMR has AMX capabilities, NVL does not (under LLVM < 22 only DMR reaches this case).
|
||||
setCapability(TargetCapability::AmxTile, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxInt8, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxBf16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
setCapability(TargetCapability::AmxFp16, (this->m_isa == Target::DMR_AVX10_2));
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
CPUfromISA = (this->m_isa == Target::DMR_AVX10_2) ? CPU_DMR : CPU_NVL;
|
||||
#else
|
||||
CPUfromISA = CPU_DMR;
|
||||
#endif
|
||||
break;
|
||||
#if ISPC_LLVM_VERSION < ISPC_LLVM_22_0
|
||||
// For LLVM 20-21, NVL targets are not supported yet
|
||||
case ISPCTarget::avx10_2nvl_x4:
|
||||
case ISPCTarget::avx10_2nvl_x8:
|
||||
case ISPCTarget::avx10_2nvl_x16:
|
||||
case ISPCTarget::avx10_2nvl_x32:
|
||||
case ISPCTarget::avx10_2nvl_x64:
|
||||
unsupported_target = true;
|
||||
break;
|
||||
#endif
|
||||
#ifdef ISPC_ARM_ENABLED
|
||||
case ISPCTarget::neon_i8x16:
|
||||
this->m_isa = Target::NEON;
|
||||
@@ -2233,7 +2328,11 @@ Target::Target(Arch arch, const char *cpu, ISPCTarget ispc_target, PICLevel picL
|
||||
|
||||
if ((m_ispc_target == ISPCTarget::generic_i32x16 || m_ispc_target == ISPCTarget::generic_i1x16 ||
|
||||
m_ispc_target == ISPCTarget::generic_i1x32 || m_ispc_target == ISPCTarget::generic_i1x64) &&
|
||||
(CPUID == CPU_SKX || CPUID == CPU_ICL || CPUID == CPU_SPR || CPUID == CPU_GNR || CPUID == CPU_DMR)) {
|
||||
(CPUID == CPU_SKX || CPUID == CPU_ICL || CPUID == CPU_SPR || CPUID == CPU_GNR || CPUID == CPU_DMR
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
|| CPUID == CPU_NVL
|
||||
#endif
|
||||
)) {
|
||||
// Support --opt=disable-zmm for generic targets when CPU with avx512 support is specified.
|
||||
if (g->opt.disableZMM) {
|
||||
this->m_funcAttributes.push_back(std::make_pair("prefer-vector-width", "256"));
|
||||
@@ -2790,6 +2889,8 @@ const char *Target::ISAToString(ISA isa) {
|
||||
return "avx512gnr";
|
||||
case Target::DMR_AVX10_2:
|
||||
return "avx10_2dmr";
|
||||
case Target::NVL_AVX10_2:
|
||||
return "avx10_2nvl";
|
||||
#ifdef ISPC_XE_ENABLED
|
||||
case Target::XELP:
|
||||
return "xelp";
|
||||
@@ -2863,6 +2964,8 @@ const char *Target::ISAToTargetString(ISA isa) {
|
||||
return "avx512gnr-x16";
|
||||
case Target::DMR_AVX10_2:
|
||||
return "avx10.2dmr-x16";
|
||||
case Target::NVL_AVX10_2:
|
||||
return "avx10.2nvl-x8";
|
||||
default:
|
||||
FATAL("Unhandled target in ISAToTargetString()");
|
||||
}
|
||||
@@ -2934,6 +3037,12 @@ Target::ISA Target::TargetToISA(ISPCTarget target) {
|
||||
case ISPCTarget::avx10_2dmr_x32:
|
||||
case ISPCTarget::avx10_2dmr_x64:
|
||||
return Target::ISA::DMR_AVX10_2;
|
||||
case ISPCTarget::avx10_2nvl_x4:
|
||||
case ISPCTarget::avx10_2nvl_x8:
|
||||
case ISPCTarget::avx10_2nvl_x16:
|
||||
case ISPCTarget::avx10_2nvl_x32:
|
||||
case ISPCTarget::avx10_2nvl_x64:
|
||||
return Target::ISA::NVL_AVX10_2;
|
||||
#ifdef ISPC_ARM_ENABLED
|
||||
case ISPCTarget::neon_i8x16:
|
||||
case ISPCTarget::neon_i8x32:
|
||||
|
||||
@@ -256,6 +256,7 @@ class Target {
|
||||
ICL_AVX512 = dispatch::ISA::ICL_AVX512,
|
||||
SPR_AVX512 = dispatch::ISA::SPR_AVX512,
|
||||
GNR_AVX512 = dispatch::ISA::GNR_AVX512,
|
||||
NVL_AVX10_2 = dispatch::ISA::NVL_AVX10_2,
|
||||
DMR_AVX10_2 = dispatch::ISA::DMR_AVX10_2,
|
||||
#ifdef ISPC_ARM_ENABLED
|
||||
NEON,
|
||||
|
||||
+28
-5
@@ -1952,6 +1952,29 @@ static llvm::FunctionType *lGetVaryingDispatchType(FunctionTargetVariants &funcs
|
||||
return resultFuncTy;
|
||||
}
|
||||
|
||||
/** Emit the predicate deciding whether a system reporting @p systemISA may run
|
||||
the @p candidate variant.
|
||||
|
||||
The base test is the linear "systemISA >= candidate", which assumes the
|
||||
Target::ISA enumerant is a total order in which each ISA is a superset of all
|
||||
lower-numbered ones. Nova Lake (NVL) breaks that: it implements AVX10.2 (so it
|
||||
sorts above SPR/GNR) but, unlike SPR/GNR/DMR, has no AMX. So an NVL system must
|
||||
not select the AMX-bearing SPR/GNR variants -- it falls back to an ICL-or-lower
|
||||
variant (NVL has full AVX-512) or to a present NVL/AVX10.2 variant. DMR (a
|
||||
higher enumerant than NVL) is already excluded from SPR/GNR by the ">=" test,
|
||||
and NVL selecting its own variant is fine. */
|
||||
static llvm::Value *lEmitISACompatibilityTest(int candidate, llvm::Value *systemISA, llvm::BasicBlock *bblock) {
|
||||
// "is the system's ISA enumerant value >= the enumerant value of the current candidate?"
|
||||
llvm::Value *ok = llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE, systemISA,
|
||||
LLVMInt32(candidate), "isa_ok", bblock);
|
||||
if (candidate == Target::SPR_AVX512 || candidate == Target::GNR_AVX512) {
|
||||
llvm::Value *notNVL = llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, systemISA,
|
||||
LLVMInt32(Target::NVL_AVX10_2), "not_nvl", bblock);
|
||||
ok = llvm::BinaryOperator::Create(llvm::Instruction::And, ok, notNVL, "isa_ok_nvl", bblock);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/** Create the dispatch function for an exported ispc function.
|
||||
This function checks to see which vector ISAs the system the
|
||||
code is running on supports and calls out to the best available
|
||||
@@ -2068,12 +2091,12 @@ static void lCreateDispatchFunction(llvm::Module *module, llvm::Function *getBes
|
||||
continue;
|
||||
}
|
||||
|
||||
// Emit code to see if the system can run the current candidate
|
||||
// variant successfully--"is the system's ISA enumerant value >=
|
||||
// the enumerant value of the current candidate?"
|
||||
// Emit code to see if the system can run the current candidate variant
|
||||
// successfully. The base test is the linear "systemISA >= candidate", with
|
||||
// an extra guard for NVL on the AMX-bearing SPR/GNR variants (see the
|
||||
// helper for details).
|
||||
llvm::Value *ok = lEmitISACompatibilityTest(i, systemISA, bblock);
|
||||
|
||||
llvm::Value *ok = llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGE, systemISA,
|
||||
LLVMInt32(i), "isa_ok", bblock);
|
||||
llvm::BasicBlock *callBBlock = llvm::BasicBlock::Create(*g->ctx, "do_call", dispatchFunc);
|
||||
llvm::BasicBlock *nextBBlock = llvm::BasicBlock::Create(*g->ctx, "next_try", dispatchFunc);
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_23_0
|
||||
|
||||
+43
-1
@@ -220,9 +220,24 @@ ISPCTarget operator++(ISPCTarget &target, int dummy) {
|
||||
static_assert(static_cast<underlying>(ISPCTarget::avx10_2dmr_x64) ==
|
||||
static_cast<underlying>(ISPCTarget::avx10_2dmr_x32) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
static_assert(static_cast<underlying>(ISPCTarget::neon_i8x16) ==
|
||||
static_assert(static_cast<underlying>(ISPCTarget::avx10_2nvl_x4) ==
|
||||
static_cast<underlying>(ISPCTarget::avx10_2dmr_x64) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
static_assert(static_cast<underlying>(ISPCTarget::avx10_2nvl_x8) ==
|
||||
static_cast<underlying>(ISPCTarget::avx10_2nvl_x4) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
static_assert(static_cast<underlying>(ISPCTarget::avx10_2nvl_x16) ==
|
||||
static_cast<underlying>(ISPCTarget::avx10_2nvl_x8) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
static_assert(static_cast<underlying>(ISPCTarget::avx10_2nvl_x32) ==
|
||||
static_cast<underlying>(ISPCTarget::avx10_2nvl_x16) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
static_assert(static_cast<underlying>(ISPCTarget::avx10_2nvl_x64) ==
|
||||
static_cast<underlying>(ISPCTarget::avx10_2nvl_x32) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
static_assert(static_cast<underlying>(ISPCTarget::neon_i8x16) ==
|
||||
static_cast<underlying>(ISPCTarget::avx10_2nvl_x64) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
static_assert(static_cast<underlying>(ISPCTarget::neon_i8x32) ==
|
||||
static_cast<underlying>(ISPCTarget::neon_i8x16) + 1,
|
||||
"Enum ISPCTarget is not sequential");
|
||||
@@ -487,6 +502,18 @@ ISPCTarget ParseISPCTarget(std::string target) {
|
||||
return ISPCTarget::avx10_2dmr_x32;
|
||||
} else if (target == "avx10.2dmr-x64") {
|
||||
return ISPCTarget::avx10_2dmr_x64;
|
||||
#if ISPC_LLVM_VERSION >= ISPC_LLVM_22_0
|
||||
} else if (target == "avx10.2nvl-x4") {
|
||||
return ISPCTarget::avx10_2nvl_x4;
|
||||
} else if (target == "avx10.2nvl-x8") {
|
||||
return ISPCTarget::avx10_2nvl_x8;
|
||||
} else if (target == "avx10.2nvl-x16") {
|
||||
return ISPCTarget::avx10_2nvl_x16;
|
||||
} else if (target == "avx10.2nvl-x32") {
|
||||
return ISPCTarget::avx10_2nvl_x32;
|
||||
} else if (target == "avx10.2nvl-x64") {
|
||||
return ISPCTarget::avx10_2nvl_x64;
|
||||
#endif
|
||||
} else if (target == "neon-i8x16") {
|
||||
return ISPCTarget::neon_i8x16;
|
||||
} else if (target == "neon-i8x32") {
|
||||
@@ -702,6 +729,16 @@ std::string ISPCTargetToString(ISPCTarget target) {
|
||||
return "avx10.2dmr-x32";
|
||||
case ISPCTarget::avx10_2dmr_x64:
|
||||
return "avx10.2dmr-x64";
|
||||
case ISPCTarget::avx10_2nvl_x4:
|
||||
return "avx10.2nvl-x4";
|
||||
case ISPCTarget::avx10_2nvl_x8:
|
||||
return "avx10.2nvl-x8";
|
||||
case ISPCTarget::avx10_2nvl_x16:
|
||||
return "avx10.2nvl-x16";
|
||||
case ISPCTarget::avx10_2nvl_x32:
|
||||
return "avx10.2nvl-x32";
|
||||
case ISPCTarget::avx10_2nvl_x64:
|
||||
return "avx10.2nvl-x64";
|
||||
case ISPCTarget::neon_i8x16:
|
||||
return "neon-i8x16";
|
||||
case ISPCTarget::neon_i8x32:
|
||||
@@ -842,6 +879,11 @@ bool ISPCTargetIsX86(ISPCTarget target) {
|
||||
case ISPCTarget::avx10_2dmr_x16:
|
||||
case ISPCTarget::avx10_2dmr_x32:
|
||||
case ISPCTarget::avx10_2dmr_x64:
|
||||
case ISPCTarget::avx10_2nvl_x4:
|
||||
case ISPCTarget::avx10_2nvl_x8:
|
||||
case ISPCTarget::avx10_2nvl_x16:
|
||||
case ISPCTarget::avx10_2nvl_x32:
|
||||
case ISPCTarget::avx10_2nvl_x64:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -85,6 +85,11 @@ enum class ISPCTarget {
|
||||
avx10_2dmr_x16,
|
||||
avx10_2dmr_x32,
|
||||
avx10_2dmr_x64,
|
||||
avx10_2nvl_x4,
|
||||
avx10_2nvl_x8,
|
||||
avx10_2nvl_x16,
|
||||
avx10_2nvl_x32,
|
||||
avx10_2nvl_x64,
|
||||
neon_i8x16,
|
||||
neon_i8x32,
|
||||
neon_i16x8,
|
||||
|
||||
@@ -183,7 +183,9 @@ static ISPCTarget lCanonicalizeTarget(ISPCTarget target, TargetOS os, bool apply
|
||||
target == ISPCTarget::avx512gnr_x32 || target == ISPCTarget::avx512gnr_x64 ||
|
||||
target == ISPCTarget::avx10_2dmr_x4 || target == ISPCTarget::avx10_2dmr_x8 ||
|
||||
target == ISPCTarget::avx10_2dmr_x16 || target == ISPCTarget::avx10_2dmr_x32 ||
|
||||
target == ISPCTarget::avx10_2dmr_x64)) {
|
||||
target == ISPCTarget::avx10_2dmr_x64 || target == ISPCTarget::avx10_2nvl_x4 ||
|
||||
target == ISPCTarget::avx10_2nvl_x8 || target == ISPCTarget::avx10_2nvl_x16 ||
|
||||
target == ISPCTarget::avx10_2nvl_x32 || target == ISPCTarget::avx10_2nvl_x64)) {
|
||||
return ISPCTarget::none;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ static const int32 programIndex = {ISPC_PROGRAM_INDEX_INITIALIZER};
|
||||
#endif
|
||||
|
||||
#if defined(ISPC_TARGET_AVX512SKX) || defined(ISPC_TARGET_AVX512ICL) || defined(ISPC_TARGET_AVX512SPR) || \
|
||||
defined(ISPC_TARGET_AVX512GNR) || defined(ISPC_TARGET_AVX10_2DMR)
|
||||
defined(ISPC_TARGET_AVX512GNR) || defined(ISPC_TARGET_AVX10_2DMR) || defined(ISPC_TARGET_AVX10_2NVL)
|
||||
#define ISPC_TARGET_HAS_ROTATE_VIA_SHUFFLE_8_VAL 1
|
||||
#define ISPC_TARGET_HAS_ROTATE_VIA_SHUFFLE_16_VAL 1
|
||||
#if TARGET_WIDTH <= 32
|
||||
@@ -197,7 +197,7 @@ static const int32 programIndex = {ISPC_PROGRAM_INDEX_INITIALIZER};
|
||||
#endif
|
||||
|
||||
#if defined(ISPC_TARGET_AVX512SKX) || defined(ISPC_TARGET_AVX512ICL) || defined(ISPC_TARGET_AVX512SPR) || \
|
||||
defined(ISPC_TARGET_AVX512GNR) || defined(ISPC_TARGET_AVX10_2DMR)
|
||||
defined(ISPC_TARGET_AVX512GNR) || defined(ISPC_TARGET_AVX10_2DMR) || defined(ISPC_TARGET_AVX10_2NVL)
|
||||
#define ISPC_TARGET_HAS_SHIFT_VIA_SHUFFLE_8_VAL 1
|
||||
#define ISPC_TARGET_HAS_SHIFT_VIA_SHUFFLE_16_VAL 1
|
||||
#if TARGET_WIDTH < 64
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Verifies that the "avx10" entry in ISPC's CPUFeatures map lets an AVX10
|
||||
// LLVM intrinsic be used from ISPC source on the diamondrapids (DMR) and
|
||||
// novalake (NVL) CPUs. Without the "avx10" CPUFeatures entry for these CPUs,
|
||||
// Target::checkIntrinsticSupport rejects @llvm.x86.avx10.* with
|
||||
// "Target specific LLVM intrinsic ... not supported on ... CPU".
|
||||
// The @llvm.x86.avx10.mask.vminmaxps256 intrinsic exists in LLVM 22 and
|
||||
// lowers to the vminmaxps instruction, proving the intrinsic is both accepted
|
||||
// (feature gate works) and selected by the backend.
|
||||
|
||||
// RUN: %{ispc} %s --target=avx10.2dmr-x16 --enable-llvm-intrinsics --nowrap --emit-asm -o - | FileCheck %s
|
||||
// RUN: %{ispc} %s --target=avx10.2nvl-x16 --enable-llvm-intrinsics --nowrap --emit-asm -o - | FileCheck %s
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// CHECK-LABEL: f___
|
||||
// CHECK: vminmaxps
|
||||
export void f(uniform float a[8], uniform float b[8], uniform float passthru[8], uniform float out[8]) {
|
||||
uniform float<8> va = {a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]};
|
||||
uniform float<8> vb = {b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]};
|
||||
uniform float<8> vp = {passthru[0], passthru[1], passthru[2], passthru[3],
|
||||
passthru[4], passthru[5], passthru[6], passthru[7]};
|
||||
uniform float<8> r = @llvm.x86.avx10.mask.vminmaxps256(va, vb, (uniform int)0, vp, (uniform int8)-1);
|
||||
for (uniform int i = 0; i < 8; i++)
|
||||
out[i] = r[i];
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Case 1: Checks avx10.2nvl-x16 assembly output for zmm registers.
|
||||
//; RUN: %{ispc} %s --target=avx10.2nvl-x16 --emit-asm -o - | FileCheck %s -check-prefix=CHECK_ZMM_32x16
|
||||
// Case 2a: Checks avx10.2nvl-x4 assembly output to ensure there are no zmm registers.
|
||||
//; RUN: %{ispc} %s --target=avx10.2nvl-x4 --emit-asm -o - | FileCheck %s --implicit-check-not "zmm"
|
||||
// Case 2b: Checks avx10.2nvl-x8 assembly output to ensure there are no zmm registers.
|
||||
//; RUN: %{ispc} %s --target=avx10.2nvl-x8 --emit-asm -o - | FileCheck %s --implicit-check-not "zmm"
|
||||
// Case 3: Checks avx10.2nvl-x16 LLVM IR to ensure avx10.2nvl-x8 func attributes are not present.
|
||||
//; RUN: %{ispc} %s --target=avx10.2nvl-x16 --emit-llvm -o %t_8.bc
|
||||
//; RUN: llvm-dis %t_8.bc -o - | FileCheck %s --implicit-check-not ""min-legal-vector-width"="256"" --implicit-check-not ""prefer-vector-width"="256""
|
||||
// Case 4a: Checks avx10.2nvl-x4 LLVM IR to ensure avx10.2nvl-x4 func attributes are present (same as for x8).
|
||||
//; RUN: %{ispc} %s --target=avx10.2nvl-x4 --emit-llvm -o %t_4.bc
|
||||
//; RUN: llvm-dis %t_4.bc -o - | FileCheck %s -check-prefix=CHECK_ATTR_8
|
||||
// Case 4b: Checks avx10.2nvl-x8 LLVM IR to ensure avx10.2nvl-x8 func attributes are present.
|
||||
//; RUN: %{ispc} %s --target=avx10.2nvl-x8 --emit-llvm -o %t_8.bc
|
||||
//; RUN: llvm-dis %t_8.bc -o - | FileCheck %s -check-prefix=CHECK_ATTR_8
|
||||
|
||||
// REQUIRES: X86_ENABLED && !MACOS_HOST && LLVM_22_0+
|
||||
|
||||
double ret_round(double val)
|
||||
{
|
||||
//; CHECK_ZMM_32x16: zmm
|
||||
return round(val+.49999);
|
||||
}
|
||||
|
||||
double foo(double val1, double val2)
|
||||
{
|
||||
//; CHECK_ZMM_32x16: zmm
|
||||
double sub_val = val1 - val2;
|
||||
return ret_round(sub_val);
|
||||
}
|
||||
|
||||
export void infoo(uniform double afoo1[], uniform double afoo2[], uniform double afoo3[])
|
||||
{
|
||||
double a = afoo1[programIndex];
|
||||
double b = afoo2[programIndex];
|
||||
double c = foo(a, b);
|
||||
//; CHECK_ZMM_32x16: zmm
|
||||
afoo3[programIndex] = c;
|
||||
}
|
||||
// The avx10.2-x8 specific function attribute list will be present at 2 places.
|
||||
// Once where function attributes for exported functions are aggregated and
|
||||
// again where function attributes for non-exported functions are aggregated.
|
||||
//; CHECK_ATTR_8: "min-legal-vector-width"="256"
|
||||
//; CHECK_ATTR_8: "prefer-vector-width"="256"
|
||||
//; CHECK_ATTR_8: "min-legal-vector-width"="256"
|
||||
//; CHECK_ATTR_8: "prefer-vector-width"="256"
|
||||
@@ -0,0 +1,19 @@
|
||||
// This test checks that AMX FP16 (amxfp16) builtins are correctly handled by ISPC on NVL target
|
||||
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x4 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x8 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x16 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x32 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x64 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// CHECK_NVL_ERROR: Error: Some AMX functions used in the source are not supported on the current target
|
||||
|
||||
#include <amx.isph>
|
||||
|
||||
__attribute__((external_only))
|
||||
export void test_amx_fp16() {
|
||||
// require amxfp16 feature (GNR+)
|
||||
amx_dpfp16ps(2, 0, 1);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// This test checks that AMX INT8 (amxint8) and BF16 builtins are correctly handled by ISPC on NVL target
|
||||
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x4 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x8 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x16 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x32 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x64 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// CHECK_NVL_ERROR: Error: Some AMX functions used in the source are not supported on the current target
|
||||
|
||||
#include <amx.isph>
|
||||
|
||||
__attribute__((external_only))
|
||||
export void test_amx_int8() {
|
||||
// require amxint8 feature (SPR+)
|
||||
amx_dpbssd(2, 0, 1);
|
||||
amx_dpbsud(2, 0, 1);
|
||||
amx_dpbusd(2, 0, 1);
|
||||
amx_dpbuud(2, 0, 1);
|
||||
}
|
||||
|
||||
__attribute__((external_only))
|
||||
export void test_amx_bf16() {
|
||||
// require amxbf16 feature (SPR+)
|
||||
amx_dpbf16ps(2, 0, 1);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// This test checks that AMX tile (amxtile) builtins are correctly handled by ISPC on NVL target
|
||||
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x4 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x8 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x16 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x32 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x64 --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// CHECK_NVL_ERROR: Error: Some AMX functions used in the source are not supported on the current target
|
||||
|
||||
#include <amx.isph>
|
||||
|
||||
__attribute__((external_only))
|
||||
export void test_amx_tile(uniform int8* uniform config, uniform int8* uniform data) {
|
||||
// Base AMX tile operations - require amxtile feature
|
||||
amx_tile_loadconfig(config);
|
||||
amx_tile_storeconfig(config);
|
||||
amx_tile_zero(2);
|
||||
amx_tile_load(0, data, (uniform int64)64);
|
||||
amx_tile_load_t1(1, data, (uniform int64)64);
|
||||
amx_tile_store(0, data, (uniform int64)64);
|
||||
amx_tile_release();
|
||||
}
|
||||
@@ -37,6 +37,9 @@ int main() {
|
||||
case 11:
|
||||
printf("AVX10_2DMR\n");
|
||||
break;
|
||||
case 12:
|
||||
printf("AVX10_2NVL\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown ISA\n");
|
||||
break;
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
// RUN: sde -mrm -- %t.exe | FileCheck %s -check-prefix=CHECK_SSE2
|
||||
// RUN: sde -dmr -- %t.exe | FileCheck %s -check-prefix=CHECK_DMR
|
||||
|
||||
// REQUIRES: X86_ENABLED && SDE_INSTALLED && LLVM_20_0+
|
||||
// REQUIRES: X86_ENABLED && SDE_INSTALLED && LLVM_20_0+ && !LLVM_22_0+
|
||||
|
||||
// CHECK_SSE2: SSE2
|
||||
// CHECK_DMR: AVX10_2DMR
|
||||
|
||||
export uniform int detect_isa() {
|
||||
#if defined(ISPC_TARGET_AVX10_2DMR)
|
||||
#if defined(ISPC_TARGET_AVX10_2NVL)
|
||||
return 12;
|
||||
#elif defined(ISPC_TARGET_AVX10_2DMR)
|
||||
return 11;
|
||||
#elif defined(ISPC_TARGET_AVX512GNR)
|
||||
return 10;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Compile the test for different x86 targets available with LLVM_22+ with auto-dispatch enabled and run the test under SDE to verify that correct platform was picked in runtime.
|
||||
|
||||
// RUN: %{ispc} %s --target=sse2-i32x4,avx10.2nvl-x16 -o %t_ispc0.o --nostdlib
|
||||
// RUN: %{cc} -O2 %S/check_dispatch.c %t_ispc0*.o -o %t.exe
|
||||
// RUN: sde -mrm -- %t.exe | FileCheck %s -check-prefix=CHECK_SSE2
|
||||
// RUN: sde -nvl -- %t.exe | FileCheck %s -check-prefix=CHECK_NVL
|
||||
|
||||
// REQUIRES: X86_ENABLED && SDE_INSTALLED && LLVM_22_0+
|
||||
|
||||
// CHECK_SSE2: SSE2
|
||||
// CHECK_NVL: AVX10_2NVL
|
||||
|
||||
export uniform int detect_isa() {
|
||||
#if defined(ISPC_TARGET_AVX10_2NVL)
|
||||
return 12;
|
||||
#elif defined(ISPC_TARGET_AVX10_2DMR)
|
||||
return 11;
|
||||
#elif defined(ISPC_TARGET_AVX512GNR)
|
||||
return 10;
|
||||
#elif defined(ISPC_TARGET_AVX512SPR)
|
||||
return 9;
|
||||
#elif defined(ISPC_TARGET_AVX512ICL)
|
||||
return 8;
|
||||
#elif defined(ISPC_TARGET_AVX512SKX)
|
||||
return 7;
|
||||
#elif defined(ISPC_TARGET_AVX2VNNI)
|
||||
return 5;
|
||||
#elif defined(ISPC_TARGET_AVX2)
|
||||
return 4;
|
||||
#elif defined(ISPC_TARGET_AVX)
|
||||
return 3;
|
||||
#elif defined(ISPC_TARGET_SSE4)
|
||||
return 2;
|
||||
#elif defined(ISPC_TARGET_SSE2)
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// The test checks that cpu definitions (including all synonyms) are successfully consumed by compiler.
|
||||
|
||||
//; RUN: %{ispc} %s -o %t.o --nostdlib --target=sse2-i32x4 --cpu=nvl
|
||||
//; RUN: %{ispc} %s -o %t.o --nostdlib --target=sse2-i32x4 --cpu=novalake
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+
|
||||
|
||||
uniform int i;
|
||||
|
||||
void foo() {}
|
||||
@@ -0,0 +1,39 @@
|
||||
// The multi-target runtime dispatcher selects a variant via a linear ">="
|
||||
// (ICMP_SGE) walk over the Target::ISA enumerant, assuming each ISA is a
|
||||
// superset of all lower-numbered ones. Nova Lake (NVL=12) breaks that: it has
|
||||
// AVX10.2 (sorts above SPR=9/GNR=11) but, unlike SPR/GNR/DMR, has no AMX. So an
|
||||
// AMX-bearing SPR/GNR candidate must carry an extra "system_isa != NVL" guard,
|
||||
// otherwise an NVL system would select it and fault on AMX instructions.
|
||||
//
|
||||
// This test verifies that the guard is emitted for SPR and GNR candidates, and
|
||||
// is NOT emitted for non-AMX candidates (e.g. avx2). DMR (13) is already
|
||||
// excluded by the ">=" test and needs no guard.
|
||||
|
||||
// RUN: %{ispc} %s -O0 --target=sse2-i32x4,avx512gnr-x16 --emit-llvm-text -o %t.ll --nostdlib
|
||||
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=GNR
|
||||
// RUN: %{ispc} %s -O0 --target=sse2-i32x4,avx512spr-x16 --emit-llvm-text -o %t.ll --nostdlib
|
||||
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=SPR
|
||||
// RUN: %{ispc} %s -O0 --target=sse2-i32x4,avx2-i32x8 --emit-llvm-text -o %t.ll --nostdlib
|
||||
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=AVX2
|
||||
|
||||
// REQUIRES: X86_ENABLED && !MACOS_HOST
|
||||
|
||||
// GNR: %system_isa = call i32 @__get_system_best_isa()
|
||||
// GNR-NEXT: %isa_ok = icmp sge i32 %system_isa, 11
|
||||
// GNR-NEXT: %not_nvl = icmp ne i32 %system_isa, 12
|
||||
// GNR-NEXT: %isa_ok_nvl = and i1 %isa_ok, %not_nvl
|
||||
// GNR-NEXT: br i1 %isa_ok_nvl, label %do_call, label %next_try
|
||||
|
||||
// SPR: %system_isa = call i32 @__get_system_best_isa()
|
||||
// SPR-NEXT: %isa_ok = icmp sge i32 %system_isa, 10
|
||||
// SPR-NEXT: %not_nvl = icmp ne i32 %system_isa, 12
|
||||
// SPR-NEXT: %isa_ok_nvl = and i1 %isa_ok, %not_nvl
|
||||
// SPR-NEXT: br i1 %isa_ok_nvl, label %do_call, label %next_try
|
||||
|
||||
// A non-AMX candidate (avx2) must not get the NVL guard.
|
||||
// AVX2: %system_isa = call i32 @__get_system_best_isa()
|
||||
// AVX2-NEXT: %isa_ok = icmp sge i32 %system_isa, {{[0-9]+}}
|
||||
// AVX2-NEXT: br i1 %isa_ok, label %do_call, label %next_try
|
||||
// AVX2-NOT: not_nvl
|
||||
|
||||
export uniform int which() { return 0; }
|
||||
@@ -0,0 +1,33 @@
|
||||
// Companion to dispatch-nvl-amx-guard.ispc, exercising target sets that
|
||||
// include the LLVM-22+ avx10.2nvl / avx10.2dmr targets. Verifies that:
|
||||
// - when an NVL variant IS present, the NVL candidate (i=12) itself is
|
||||
// selected by the plain ">=" test and does NOT carry the not_nvl guard
|
||||
// (the guard is keyed on the candidate index, not on target-set membership),
|
||||
// while a co-present SPR candidate still carries the guard;
|
||||
// - the DMR candidate (i=13) carries no guard, since it is already excluded
|
||||
// for an NVL system by the ">=" test (12 >= 13 is false).
|
||||
|
||||
// RUN: %{ispc} %s -O0 --target=avx512spr-x16,avx10.2nvl-x16 --emit-llvm-text -o %t.ll --nostdlib
|
||||
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=SPRNVL
|
||||
// RUN: %{ispc} %s -O0 --target=sse2-i32x4,avx10.2dmr-x16 --emit-llvm-text -o %t.ll --nostdlib
|
||||
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=DMR
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// NVL candidate (12) is selected by ">=" and must NOT get the not_nvl guard.
|
||||
// SPRNVL: %isa_ok = icmp sge i32 %{{.*}}, 12
|
||||
// SPRNVL-NEXT: br i1 %isa_ok, label %do_call, label %next_try
|
||||
// SPRNVL: store atomic ptr @which_avx10_2nvl
|
||||
// The co-present SPR candidate (10) still gets the guard.
|
||||
// SPRNVL: %isa_ok1 = icmp sge i32 %{{.*}}, 10
|
||||
// SPRNVL-NEXT: %not_nvl = icmp ne i32 %{{.*}}, 12
|
||||
// SPRNVL-NEXT: %isa_ok_nvl = and i1 %isa_ok1, %not_nvl
|
||||
// SPRNVL-NEXT: br i1 %isa_ok_nvl, label %do_call2, label %next_try3
|
||||
// SPRNVL: store atomic ptr @which_avx512spr
|
||||
|
||||
// DMR candidate (13) is already excluded for NVL by ">="; no guard needed.
|
||||
// DMR: %isa_ok = icmp sge i32 %system_isa, 13
|
||||
// DMR-NEXT: br i1 %isa_ok, label %do_call, label %next_try
|
||||
// DMR-NOT: not_nvl
|
||||
|
||||
export uniform int which() { return 0; }
|
||||
@@ -0,0 +1,54 @@
|
||||
// RUN: %{ispc} --pic --target=sse2-i32x4,avx512icl-x4,avx512spr-x4,avx512gnr-x4,avx10.2dmr-x4,avx10.2nvl-x4 -h %t.h %s -o %t.o -g
|
||||
// RUN: %{cc} -x c -c %s -o %t.c.o --include %t.h -g
|
||||
// RUN: %{cc} %t.c.o -o %t.c.bin -g -rdynamic %t.o %t_sse2.o %t_avx512icl.o %t_avx512spr.o %t_avx512gnr.o %t_avx10_2dmr.o %t_avx10_2nvl.o
|
||||
|
||||
// RUN: sde -mrm -- %t.c.bin | FileCheck %s --check-prefix=CHECK-SSE2
|
||||
// RUN: sde -icl -- %t.c.bin | FileCheck %s --check-prefix=CHECK-ICL
|
||||
// RUN: sde -spr -- %t.c.bin | FileCheck %s --check-prefix=CHECK-SPR
|
||||
// RUN: sde -gnr -- %t.c.bin | FileCheck %s --check-prefix=CHECK-GNR
|
||||
// RUN: sde -dmr -- %t.c.bin | FileCheck %s --check-prefix=CHECK-DMR
|
||||
// RUN: sde -nvl -- %t.c.bin | FileCheck %s --check-prefix=CHECK-NVL
|
||||
|
||||
// REQUIRES: LINUX_HOST && X86_ENABLED && SDE_INSTALLED && LLVM_22_0+
|
||||
|
||||
// CHECK-SSE2: ispc_foo_sse2
|
||||
// CHECK-ICL: ispc_foo_avx512icl
|
||||
// CHECK-SPR: ispc_foo_avx512spr
|
||||
// CHECK-GNR: ispc_foo_avx512gnr
|
||||
// CHECK-DMR: ispc_foo_avx10_2dmr
|
||||
// CHECK-NVL: ispc_foo_avx10_2nvl
|
||||
|
||||
#ifdef ISPC
|
||||
extern "C" void print_stack_trace();
|
||||
void check_isa() {
|
||||
print_stack_trace();
|
||||
print("check_isa");
|
||||
}
|
||||
export void ispc_foo() {
|
||||
check_isa();
|
||||
}
|
||||
#else
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
void print_stack_trace() {
|
||||
const int max_frames = 64;
|
||||
void *buffer[max_frames];
|
||||
int num_frames = backtrace(buffer, max_frames);
|
||||
char **symbols = backtrace_symbols(buffer, num_frames);
|
||||
if (symbols == NULL) {
|
||||
perror("backtrace_symbols");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("Stack trace:\n");
|
||||
for (int i = 0; i < num_frames; i++) {
|
||||
printf("%s\n", symbols[i]);
|
||||
}
|
||||
free(symbols);
|
||||
}
|
||||
extern void ispc_foo();
|
||||
int main() {
|
||||
ispc_foo();
|
||||
return 0;
|
||||
}
|
||||
#endif // ISPC
|
||||
@@ -0,0 +1,14 @@
|
||||
//; RUN: %{ispc} %s --target=avx2-i32x8 --enable-llvm-intrinsics
|
||||
//; RUN: %{ispc} %s --cpu=ps4 --target=avx1-i32x8 --enable-llvm-intrinsics
|
||||
//; RUN: %{ispc} %s --nowrap --cpu=spr --target=avx512spr-x8 --enable-llvm-intrinsics
|
||||
//; RUN: %{ispc} %s --nowrap --cpu=gnr --target=avx512spr-x8 --enable-llvm-intrinsics
|
||||
//; RUN: %{ispc} %s --nowrap --cpu=nvl --target=avx10.2nvl-x8 --enable-llvm-intrinsics
|
||||
//; RUN: not %{ispc} %s --target=sse2-i32x8 --enable-llvm-intrinsics --nowrap 2>&1 | FileCheck %s -check-prefix=CHECK_SSE2
|
||||
|
||||
//; REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
//; CHECK_SSE2: Error: Target specific LLVM intrinsic "avx.addsub.ps.256" not supported
|
||||
float foo(float a, float b) {
|
||||
float c = @llvm.x86.avx.addsub.ps.256(a, b);
|
||||
return c;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// This test checks that AMX FP16 (amxfp16) intrinsics are correctly handled by ISPC
|
||||
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx512spr-x4 --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_SPR_ERROR
|
||||
// RUN: %{ispc} --nowrap %s --target=avx512spr-x4 --cpu=gnr --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_GNR_SUCCESS
|
||||
// RUN: %{ispc} --nowrap %s --target=avx10.2dmr-x4 --cpu=dmr --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_DMR_SUCCESS
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x4 --cpu=nvl --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// CHECK_SPR_ERROR: Target specific LLVM intrinsic "tdpfp16ps" requires feature "amxfp16" not supported on "sapphirerapids" CPU
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tdpfp16ps
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tdpfp16ps
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tdpfp16ps" requires feature "amxfp16" not supported on "novalake" CPU
|
||||
|
||||
__attribute__((external_only))
|
||||
export void test_amx_fp16() {
|
||||
// require amxfp16 feature (GNR+)
|
||||
@llvm.x86.tdpfp16ps((uniform int8)2, (uniform int8)0, (uniform int8)1);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// This test checks that AMX INT8 (amxint8) intrinsics are correctly handled by ISPC
|
||||
|
||||
// RUN: %{ispc} --nowrap %s --target=avx512spr-x4 --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_SPR_SUCCESS
|
||||
// RUN: %{ispc} --nowrap %s --target=avx512spr-x4 --cpu=gnr --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_GNR_SUCCESS
|
||||
// RUN: %{ispc} --nowrap %s --target=avx10.2dmr-x4 --cpu=dmr --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_DMR_SUCCESS
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x4 --cpu=nvl --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tdpbssd
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tdpbsud
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tdpbusd
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tdpbuud
|
||||
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tdpbssd
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tdpbsud
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tdpbusd
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tdpbuud
|
||||
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tdpbssd
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tdpbsud
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tdpbusd
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tdpbuud
|
||||
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tdpbssd" requires feature "amxint8" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tdpbsud" requires feature "amxint8" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tdpbusd" requires feature "amxint8" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tdpbuud" requires feature "amxint8" not supported on "novalake" CPU
|
||||
|
||||
__attribute__((external_only))
|
||||
export void test_amx_int8() {
|
||||
// require amxint8 feature (SPR+)
|
||||
@llvm.x86.tdpbssd((uniform int8)2, (uniform int8)0, (uniform int8)1);
|
||||
@llvm.x86.tdpbsud((uniform int8)2, (uniform int8)0, (uniform int8)1);
|
||||
@llvm.x86.tdpbusd((uniform int8)2, (uniform int8)0, (uniform int8)1);
|
||||
@llvm.x86.tdpbuud((uniform int8)2, (uniform int8)0, (uniform int8)1);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// This test checks that AMX tile (amxtile) intrinsics are correctly handled by ISPC
|
||||
|
||||
// RUN: %{ispc} --nowrap %s --target=avx512spr-x4 --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_SPR_SUCCESS
|
||||
// RUN: %{ispc} --nowrap %s --target=avx512spr-x4 --cpu=gnr --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_GNR_SUCCESS
|
||||
// RUN: %{ispc} --nowrap %s --target=avx10.2dmr-x4 --cpu=dmr --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_DMR_SUCCESS
|
||||
// RUN: not %{ispc} --nowrap %s --target=avx10.2nvl-x4 --cpu=nvl --enable-llvm-intrinsics --emit-llvm-text -O2 -o - 2>&1 | FileCheck %s -check-prefix=CHECK_NVL_ERROR
|
||||
|
||||
// REQUIRES: X86_ENABLED && LLVM_22_0+ && !MACOS_HOST
|
||||
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.ldtilecfg
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.sttilecfg
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tilezero
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tileloadd64
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tileloaddt164
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tilestored64
|
||||
// CHECK_SPR_SUCCESS: call void @llvm.x86.tilerelease
|
||||
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.ldtilecfg
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.sttilecfg
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tilezero
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tileloadd64
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tileloaddt164
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tilestored64
|
||||
// CHECK_GNR_SUCCESS: call void @llvm.x86.tilerelease
|
||||
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.ldtilecfg
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.sttilecfg
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tilezero
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tileloadd64
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tileloaddt164
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tilestored64
|
||||
// CHECK_DMR_SUCCESS: call void @llvm.x86.tilerelease
|
||||
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "ldtilecfg" requires feature "amxtile" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "sttilecfg" requires feature "amxtile" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tilezero" requires feature "amxtile" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tileloadd64" requires feature "amxtile" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tileloaddt164" requires feature "amxtile" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tilestored64" requires feature "amxtile" not supported on "novalake" CPU
|
||||
// CHECK_NVL_ERROR: Target specific LLVM intrinsic "tilerelease" requires feature "amxtile" not supported on "novalake" CPU
|
||||
|
||||
__attribute__((external_only))
|
||||
export void test_amx_tile(uniform int8* uniform config, uniform int8* uniform data) {
|
||||
// Base AMX tile operations - require amxtile feature
|
||||
@llvm.x86.ldtilecfg(config);
|
||||
@llvm.x86.sttilecfg(config);
|
||||
@llvm.x86.tilezero((uniform int8)2);
|
||||
@llvm.x86.tileloadd64((uniform int8)0, data, (uniform int64)64);
|
||||
@llvm.x86.tileloaddt164((uniform int8)1, data, (uniform int64)64);
|
||||
@llvm.x86.tilestored64((uniform int8)0, data, (uniform int64)64);
|
||||
@llvm.x86.tilerelease();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// The test checks that target definitions for AVX10.2 NVL are not accepted on macOS.
|
||||
|
||||
//; RUN: not %{ispc} %s -o %t.o --nostdlib --target-os=macos --arch=x86-64 --nowrap --target=avx10.2nvl-x4 2>&1 | FileCheck %s
|
||||
//; RUN: not %{ispc} %s -o %t.o --nostdlib --target-os=macos --arch=x86-64 --nowrap --target=avx10.2nvl-x8 2>&1 | FileCheck %s
|
||||
//; RUN: not %{ispc} %s -o %t.o --nostdlib --target-os=macos --arch=x86-64 --nowrap --target=avx10.2nvl-x16 2>&1 | FileCheck %s
|
||||
//; RUN: not %{ispc} %s -o %t.o --nostdlib --target-os=macos --arch=x86-64 --nowrap --target=avx10.2nvl-x32 2>&1 | FileCheck %s
|
||||
//; RUN: not %{ispc} %s -o %t.o --nostdlib --target-os=macos --arch=x86-64 --nowrap --target=avx10.2nvl-x64 2>&1 | FileCheck %s
|
||||
|
||||
// REQUIRES: X86_ENABLED && MACOS_HOST && LLVM_22_0+
|
||||
|
||||
// CHECK: Error: avx10.2nvl-x{{.*}} target for x86-64 on macOS is not supported in current build.
|
||||
|
||||
uniform int j;
|
||||
|
||||
int foo(int i) { return i + 1; }
|
||||
@@ -0,0 +1,14 @@
|
||||
// The test checks that avx10.2nvl-x* targets are not recognized before LLVM 22.
|
||||
|
||||
// RUN: not %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x4 2>&1 | FileCheck %s
|
||||
// RUN: not %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x8 2>&1 | FileCheck %s
|
||||
// RUN: not %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x16 2>&1 | FileCheck %s
|
||||
// RUN: not %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x32 2>&1 | FileCheck %s
|
||||
// RUN: not %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x64 2>&1 | FileCheck %s
|
||||
|
||||
// REQUIRES: X86_ENABLED && !MACOS_HOST && LLVM_20_0+ && !LLVM_22_0+
|
||||
|
||||
// CHECK: Error: Incorrect targets: avx10.2nvl
|
||||
uniform int j;
|
||||
|
||||
int foo(int i) { return i + 1; }
|
||||
@@ -0,0 +1,13 @@
|
||||
// The test checks that target definitions (including all synonyms) are successfully consumed by compiler.
|
||||
|
||||
//; RUN: %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x4
|
||||
//; RUN: %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x8
|
||||
//; RUN: %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x16
|
||||
//; RUN: %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x32
|
||||
//; RUN: %{ispc} %s -o %t.o --nostdlib --target=avx10.2nvl-x64
|
||||
|
||||
// REQUIRES: X86_ENABLED && !MACOS_HOST && LLVM_22_0+
|
||||
|
||||
uniform int j;
|
||||
|
||||
int foo(int i) { return i + 1; }
|
||||
@@ -12,7 +12,7 @@
|
||||
// CHECK_XMM: vpdpbssd {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpbssd {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpbssd {{.*}} %zmm
|
||||
// CEHCK_ZMMX2-COUNT-2: vpdpbssd {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpbssd {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpbssd {{.*}} %zmm
|
||||
unmasked void dot4add_i8i8(uniform uint a[], uniform uint b[], uniform int dst[]) {
|
||||
dst[programIndex] = dot4add_i8i8packed(a[programIndex], b[programIndex], programIndex);
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// Test checks emitted code for VNNI dot product instructions.
|
||||
|
||||
// RUN: %{ispc} %s --target=avx10.2nvl-x4 --emit-asm -o - | FileCheck %s -check-prefixes=CHECK_ALL,CHECK_XMM
|
||||
// RUN: %{ispc} %s --target=avx10.2nvl-x8 --emit-asm -o - | FileCheck %s -check-prefixes=CHECK_ALL,CHECK_YMM
|
||||
// RUN: %{ispc} %s --target=avx10.2nvl-x16 --emit-asm -o - | FileCheck %s -check-prefixes=CHECK_ALL,CHECK_ZMM
|
||||
// RUN: %{ispc} %s --target=avx10.2nvl-x32 --emit-asm -o - | FileCheck %s -check-prefixes=CHECK_ALL,CHECK_ZMMX2
|
||||
// RUN: %{ispc} %s --target=avx10.2nvl-x64 --emit-asm -o - | FileCheck %s -check-prefixes=CHECK_ALL,CHECK_ZMMX4
|
||||
|
||||
// REQUIRES: X86_ENABLED && !MACOS_HOST && LLVM_22_0+
|
||||
|
||||
// CHECK_ALL-LABEL: dot4add_i8i8
|
||||
// CHECK_XMM: vpdpbssd {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpbssd {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpbssd {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpbssd {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpbssd {{.*}} %zmm
|
||||
unmasked void dot4add_i8i8(uniform uint a[], uniform uint b[], uniform int dst[]) {
|
||||
dst[programIndex] = dot4add_i8i8packed(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
|
||||
// CHECK_ALL-LABEL: dot4add_i8i8_sat
|
||||
// CHECK_XMM: vpdpbssds {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpbssds {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpbssds {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpbssds {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpbssds {{.*}} %zmm
|
||||
unmasked void dot4add_i8i8_sat(uniform uint a[], uniform uint b[], uniform int dst[]) {
|
||||
dst[programIndex] = dot4add_i8i8packed_sat(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
|
||||
// CHECK_ALL-LABEL: dot4add_u8u8
|
||||
// CHECK_XMM: vpdpbuud {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpbuud {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpbuud {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpbuud {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpbuud {{.*}} %zmm
|
||||
unmasked void dot4add_u8u8(uniform uint a[], uniform uint b[], uniform int dst[]) {
|
||||
dst[programIndex] = dot4add_u8u8packed(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
|
||||
// CHECK_ALL-LABEL: dot4add_u8u8_sat
|
||||
// CHECK_XMM: vpdpbuuds {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpbuuds {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpbuuds {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpbuuds {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpbuuds {{.*}} %zmm
|
||||
unmasked void dot4add_u8u8_sat(uniform uint a[], uniform uint b[], uniform int dst[]) {
|
||||
dst[programIndex] = dot4add_u8u8packed_sat(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
|
||||
// CHECK_ALL-LABEL: dot2add_u16u16
|
||||
// CHECK_XMM: vpdpwuud {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpwuud {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpwuud {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpwuud {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpwuud {{.*}} %zmm
|
||||
unmasked void dot2add_u16u16(uniform uint a[], uniform uint b[], uniform uint dst[]) {
|
||||
dst[programIndex] = dot2add_u16u16packed(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
|
||||
// CHECK_ALL-LABEL: dot2add_u16u16_sat
|
||||
// CHECK_XMM: vpdpwuuds {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpwuuds {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpwuuds {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpwuuds {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpwuuds {{.*}} %zmm
|
||||
unmasked void dot2add_u16u16_sat(uniform uint a[], uniform uint b[], uniform uint dst[]) {
|
||||
dst[programIndex] = dot2add_u16u16packed_sat(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
|
||||
// CHECK_ALL-LABEL: dot2add_u16i16
|
||||
// CHECK_XMM: vpdpwusd {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpwusd {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpwusd {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpwusd {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpwusd {{.*}} %zmm
|
||||
unmasked void dot2add_u16i16(uniform uint a[], uniform uint b[], uniform int dst[]) {
|
||||
dst[programIndex] = dot2add_u16i16packed(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
|
||||
// CHECK_ALL-LABEL: dot2add_u16i16_sat
|
||||
// CHECK_XMM: vpdpwusds {{.*}} %xmm
|
||||
// CHECK_YMM: vpdpwusds {{.*}} %ymm
|
||||
// CHECK_ZMM: vpdpwusds {{.*}} %zmm
|
||||
// CHECK_ZMMX2-COUNT-2: vpdpwusds {{.*}} %zmm
|
||||
// CHECK_ZMMX4-COUNT-4: vpdpwusds {{.*}} %zmm
|
||||
unmasked void dot2add_u16i16_sat(uniform uint a[], uniform uint b[], uniform int dst[]) {
|
||||
dst[programIndex] = dot2add_u16i16packed_sat(a[programIndex], b[programIndex], programIndex);
|
||||
}
|
||||
+3
-1
@@ -48,6 +48,7 @@ const char *const isa_strings[] = {
|
||||
"ICL",
|
||||
"SPR",
|
||||
"GNR",
|
||||
"NVL",
|
||||
"DMR",
|
||||
};
|
||||
|
||||
@@ -61,7 +62,8 @@ static const char *lGetSystemISA() {
|
||||
return "Unknown x86 ISA";
|
||||
}
|
||||
const char *isa = isa_strings[isa_id];
|
||||
if (isa_id >= SPR_AVX512) {
|
||||
// Only show AMX status for AMX-capable ISAs (SPR, GNR, DMR - not NVL)
|
||||
if (isa_id == SPR_AVX512 || isa_id == GNR_AVX512 || isa_id == DMR_AVX10_2) {
|
||||
snprintf(amx_isa_string, sizeof(amx_isa_string), "%s (AMX %s)", isa,
|
||||
__os_enabled_amx_support() ? "on" : "off");
|
||||
return amx_isa_string;
|
||||
|
||||
Reference in New Issue
Block a user