diff --git a/docs/build/reference/arch-x64.md b/docs/build/reference/arch-x64.md index ada1bae0c0..02fe9eb27b 100644 --- a/docs/build/reference/arch-x64.md +++ b/docs/build/reference/arch-x64.md @@ -35,7 +35,7 @@ Enables Intel Advanced Vector Extensions 10 version 1. ## Remarks -The **`/arch`** option enables the use of certain instruction set extensions, particularly for vector calculation, available in processors from Intel and AMD. In general, more recently introduced processors may support extensions beyond the ones supported by older processors, although you should consult the documentation for a particular processor or test for instruction set extension support using [`__cpuid`](../../intrinsics/cpuid-cpuidex.md) before executing code using an instruction set extension. +The **`/arch`** option enables the use of certain instruction set extensions, particularly for vector calculation, available in processors from Intel and AMD. In general, more recently introduced processors may support extensions beyond the ones supported by older processors, although you should consult the documentation for a particular processor or test for instruction set extension support using [`__cpuid`](../../intrinsics/cpuid-cpuidex.md) before executing code using an instruction set extension. You can also use the [`__check_isa_support`](../../intrinsics/check-isa-arch-support.md) intrinsic to check for more frequently used CPU features. **`/arch`** only affects code generation for native functions. When you use [`/clr`](clr-common-language-runtime-compilation.md) to compile, **`/arch`** has no effect on code generation for managed functions. diff --git a/docs/build/reference/arch-x86.md b/docs/build/reference/arch-x86.md index e4418aa273..e0806f08b8 100644 --- a/docs/build/reference/arch-x86.md +++ b/docs/build/reference/arch-x86.md @@ -38,7 +38,7 @@ Enables Intel Advanced Vector Extensions 10 version 1. ## Remarks -The **`/arch`** option enables or disables the use of certain instruction set extensions, particularly for vector calculation, available in processors from Intel and AMD. In general, more recently introduced processors may support extensions beyond the ones supported by older processors. You should consult the documentation for a particular processor or test for instruction set extension support using [`__cpuid`](../../intrinsics/cpuid-cpuidex.md) before executing code using an instruction set extension. +The **`/arch`** option enables or disables the use of certain instruction set extensions, particularly for vector calculation, available in processors from Intel and AMD. In general, more recently introduced processors may support extensions beyond the ones supported by older processors. You should consult the documentation for a particular processor or test for instruction set extension support using [`__cpuid`](../../intrinsics/cpuid-cpuidex.md) before executing code using an instruction set extension. You can also use the [`__check_isa_support`](../../intrinsics/check-isa-arch-support.md) intrinsic to check for more frequently used CPU features. **`/arch`** only affects code generation for native functions. When you use [`/clr`](clr-common-language-runtime-compilation.md) to compile, **`/arch`** has no effect on code generation for managed functions. diff --git a/docs/intrinsics/alphabetical-listing-of-intrinsic-functions.md b/docs/intrinsics/alphabetical-listing-of-intrinsic-functions.md index cf4ffa0393..f0fcca5fb3 100644 --- a/docs/intrinsics/alphabetical-listing-of-intrinsic-functions.md +++ b/docs/intrinsics/alphabetical-listing-of-intrinsic-functions.md @@ -7,7 +7,7 @@ ms.assetid: 178f88a2-7e8e-43ac-b55e-ef3298bef895 --- # Alphabetical listing of intrinsic functions -The following sections describe the Microsoft-specific intrinsic functions available on some or all architectures. Other supported intrinsics are documented by processor manufacturers, either in the header files or on their websites. For more information, and links to manufacturer documentation, see these articles: [ARM intrinsics](../intrinsics/arm-intrinsics.md), [ARM64 intrinsics](../intrinsics/arm64-intrinsics.md), [x86 intrinsics](../intrinsics/x86-intrinsics-list.md), and [x64 intrinsics](../intrinsics/x64-amd64-intrinsics-list.md). C Runtime Library (CRT) functions implemented as intrinsics aren't documented here. CRT intrinsic functions are documented in the [C Runtime Library Reference](../c-runtime-library/c-run-time-library-reference.md). +The following sections describe the Microsoft-specific intrinsic functions available on some or all architectures. Processor manufacturers document other supported intrinsics, either in the header files or on their websites. For more information, and links to manufacturer documentation, see these articles: [ARM intrinsics](../intrinsics/arm-intrinsics.md), [ARM64 intrinsics](../intrinsics/arm64-intrinsics.md), [x86 intrinsics](../intrinsics/x86-intrinsics-list.md), and [x64 intrinsics](../intrinsics/x64-amd64-intrinsics-list.md). C Runtime Library (CRT) functions implemented as intrinsics aren't documented here. CRT intrinsic functions are documented in the [C Runtime Library Reference](../c-runtime-library/c-run-time-library-reference.md). [`__addfsbyte`, `__addfsword`, `__addfsdword`](../intrinsics/addfsbyte-addfsword-addfsdword.md) @@ -29,6 +29,8 @@ The following sections describe the Microsoft-specific intrinsic functions avail [`_bittestandset`, `_bittestandset64`](../intrinsics/bittestandset-bittestandset64.md) +[`__check_isa_support`, `__check_arch_support`](../intrinsics/check-isa-arch-support.md) + [`__cpuid`, `__cpuidex`](../intrinsics/cpuid-cpuidex.md) [`_cvt_ftoi_fast`, `_cvt_ftoll_fast`, `_cvt_ftoui_fast`, `_cvt_ftoull_fast`, `_cvt_dtoi_fast`, `_cvt_dtoll_fast`, `_cvt_dtoui_fast`, `_cvt_dtoull_fast`](../intrinsics/fast-conversion-functions.md) diff --git a/docs/intrinsics/check-isa-arch-support.md b/docs/intrinsics/check-isa-arch-support.md new file mode 100644 index 0000000000..00b066b54b --- /dev/null +++ b/docs/intrinsics/check-isa-arch-support.md @@ -0,0 +1,143 @@ +--- +description: "Learn more about: __check_isa_support, __check_arch_support" +title: "__check_isa_support, __check_arch_support" +ms.date: "11/07/2024" +f1_keywords: ["__check_isa_support", "__check_arch_support"] +helpviewer_keywords: ["__check_isa_support intrinsic", "__check_arch_support intrinsic"] +--- +# __check_isa_support, __check_arch_support + +**Microsoft Specific** + +`__check_isa_support` - detects if the processor supports the specified ISA feature and AVX10 version at run time. +`__check_arch_support` - detects if the arch flag (see [`/arch` (x86)](..\build\reference\arch-x86.md), [`/arch` (x64)](..\build\reference\arch-x64.md)) supports the specified ISA feature and AVX10 version at compile time. + +## Syntax + +```C +_Bool __check_isa_support( + unsigned feature, + unsigned avx10_version +); + +_Bool __check_arch_support( + unsigned feature, + unsigned avx10_version +); +``` + +```cpp +bool __check_isa_support( + unsigned feature, + unsigned avx10_version +); + +bool __check_arch_support( + unsigned feature, + unsigned avx10_version +); +``` + +### Parameters + +*feature*\ +[in] ISA feature to check. + +*avx10_version*\ +[in] AVX10 version to check. 0 if AVX10 version check isn't required. + +## Return value + +`__check_isa_support` returns `true` if the processor supports `feature` and `avx10_version` at run time, `false` otherwise. +`__check_arch_support` returns `true` if the `/arch` flag supports `feature` and `avx10_version` at compile time, `false` otherwise. + +## Requirements + +|Intrinsic|Architecture| +|---------------|------------------| +|`__check_isa_support`|x86, x64| +|`__check_arch_support`|x86, x64| + +**Header file** `` + +## Remarks + +The `__check_isa_support` intrinsic provides a faster alternative to the [`__cpuid`](cpuid-cpuidex.md) intrinsic to dynamically check for most frequently used CPU features. The `__check_arch_support` intrinsic provides an alternative to the [`predefined macros`](..\preprocessor\predefined-macros.md) for compile time code selection based on ISA extensions. + +The following feature values can be used in these intrinsics. These values are defined in `isa_availability.h`. + +|Feature Value Name|Description| +|---------------|------------------| +|`__IA_SUPPORT_VECTOR128`|Vector instructions with lengths up to 128 bits. This feature is enabled for SSE2 or later extensions| +|`__IA_SUPPORT_VECTOR256`|Vector instructions with lengths up to 256 bits. This feature is enabled for AVX2 or later extensions| +|`__IA_SUPPORT_VECTOR512`|Vector instructions with lengths up to 512 bits. This feature is enabled for AVX-512 or later extensions| +|`__IA_SUPPORT_AVX10`|AVX10 support. This feature is enabled for AVX10.1 or later extensions| +|`__IA_SUPPORT_SSE42`|SSE4.2 support| +|`__IA_SUPPORT_SV128X`|AVX-512 instructions for scalar of 128 bits. Can be used to signal that certain useful AVX-512 instruction like conversions can be used in scalar code| +|`__IA_SUPPORT_AVX10_2`|AVX10.2 support| +|`__IA_SUPPORT_APX`|APX support| +|`__IA_SUPPORT_FP16`|Half-precision floating-point instruction support| + +Multiple feature values can be combined using the OR(|) operator. + +The `__check_arch_support` intrinsic can always be evaluated at compile time, so using it in optimized code adds no extra instructions to execute. +Support for these intrinsics was added in Visual Studio 2022 version 17.10. + +## Example + +This example uses 256-bit AVX-512 instructions to vectorize conversion of double-precision values to 64-bit signed integer values. The tail loop for converting any source values not handled by the vector code is also used in case the vector code can't be executed. The compile-time support is checked before runtime support so that a runtime check can be avoided if possible. + +```cpp +// Compile this test with: /EHsc /O2 +#include +#include +#include +#include +using namespace std; + +#define CHECK_INSTRUCTION_SUPPORT(a,v) \ + (__check_arch_support((a),(v)) || __check_isa_support((a),(v))) + +int main() +{ + vector input = {0.3, 1.4, 2.5, 3.6, 4.7, 5.8, 6.9, 8.0, 9.1, 11.14}; + vector<__int64> output(10, 0); + int i = 0; + + if (CHECK_INSTRUCTION_SUPPORT(__IA_SUPPORT_SV128X | __IA_SUPPORT_VECTOR256, 0)) + { + for (; i < input.size() - 4; i += 4) + { + __m256i values = _mm256_cvttpd_epi64(_mm256_load_pd(&input[i])); + _mm256_storeu_epi64((void*)&output[i], values); + } + } + for (; i < input.size(); i++) + { + output[i] = input[i]; + } + + for (i = 0; i < output.size(); i++) { + cout << "output[" << i << "] = " << output[i] << endl; + } +} +``` + +```Output +output[0] = 0 +output[1] = 1 +output[2] = 2 +output[3] = 3 +output[4] = 4 +output[5] = 5 +output[6] = 6 +output[7] = 8 +output[8] = 9 +output[9] = 11 +``` + +**END Microsoft Specific** + +## See also + +[Compiler intrinsics](../intrinsics/compiler-intrinsics.md) diff --git a/docs/intrinsics/toc.yml b/docs/intrinsics/toc.yml index cfbc51772b..eb04364ed4 100644 --- a/docs/intrinsics/toc.yml +++ b/docs/intrinsics/toc.yml @@ -39,6 +39,8 @@ items: href: ../intrinsics/bittestandreset-bittestandreset64.md - name: _bittestandset, _bittestandset64 href: ../intrinsics/bittestandset-bittestandset64.md + - name: __check_isa_support, __check_arch_support + href: ../intrinsics/check-isa-arch-support.md - name: __cpuid, __cpuidex href: ../intrinsics/cpuid-cpuidex.md - name: __debugbreak diff --git a/docs/intrinsics/x64-amd64-intrinsics-list.md b/docs/intrinsics/x64-amd64-intrinsics-list.md index 92f7c81f83..555087d4d5 100644 --- a/docs/intrinsics/x64-amd64-intrinsics-list.md +++ b/docs/intrinsics/x64-amd64-intrinsics-list.md @@ -84,6 +84,8 @@ The following table lists the intrinsics available on x64 processors. The Techno | [`_castf64_u64`](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_castf64_u64) | | immintrin.h | `unsigned __int64 _castf64_u64 (double);` | | [`_castu32_f32`](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_castu32_f32) | | immintrin.h | `float _castu32_f32 (unsigned __int32);` | | [`_castu64_f64`](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_castu64_f64) | | immintrin.h | `double _castu64_f64 (unsigned __int64 a);` | +| [`__check_isa_support`](check-isa-arch-support.md) | | immintrin.h | `bool __check_isa_support(unsigned int, unsigned int);` | +| [`__check_arch_support`](check-isa-arch-support.md) | | immintrin.h | `bool __check_arch_support(unsigned int, unsigned int);` | | `_clac` | SMAP | intrin.h | `void _clac(void);` | | [`__cpuid`](cpuid-cpuidex.md) | | intrin.h | `void __cpuid(int *, int);` | | [`__cpuidex`](cpuid-cpuidex.md) | | intrin.h | `void __cpuidex(int *, int, int);` | diff --git a/docs/intrinsics/x86-intrinsics-list.md b/docs/intrinsics/x86-intrinsics-list.md index 7dbe84d0b7..4c494efabc 100644 --- a/docs/intrinsics/x86-intrinsics-list.md +++ b/docs/intrinsics/x86-intrinsics-list.md @@ -61,6 +61,8 @@ The following table lists the intrinsics available on x86 processors. The Techno | [`_castf64_u64`](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_castf64_u64) | | immintrin.h | `unsigned __int64 _castf64_u64 (double);` | | [`_castu32_f32`](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_castu32_f32) | | immintrin.h | `float _castu32_f32 (unsigned __int32);` | | [`_castu64_f64`](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_castu64_f64) | | immintrin.h | `double _castu64_f64 (unsigned __int64 a);` | +| [`__check_isa_support`](check-isa-arch-support.md) | | immintrin.h | `bool __check_isa_support(unsigned int, unsigned int);` | +| [`__check_arch_support`](check-isa-arch-support.md) | | immintrin.h | `bool __check_arch_support(unsigned int, unsigned int);` | | `_clac` | SMAP | intrin.h | `void _clac(void);` | | [`__cpuid`](cpuid-cpuidex.md) | | intrin.h | `void __cpuid(int *, int);` | | [`__cpuidex`](cpuid-cpuidex.md) | | intrin.h | `void __cpuidex(int *, int, int);` |