Backport i386 backend enablement for AVXVNNIINT16, SM3, SM4 and SHA512 used by Arrow Lake target definitions.
The patch adds builtin and intrinsic headers, option gating, machine description patterns, target-support updates and dedicated tests so these ISA extensions are available with Arrow Lake target configurations in GCC 13. Signed-off-by: Jakit Liang <[email protected]> --- contrib/arrowlake-backport-gap-report.md | 141 ++++++++++++++ gcc/common/config/i386/i386-common.cc | 79 +++++++- gcc/config.gcc | 3 +- gcc/config/i386/avxvnniint16intrin.h | 138 ++++++++++++++ gcc/config/i386/i386-builtin-types.def | 6 + gcc/config/i386/i386-builtin.def | 30 +++ gcc/config/i386/i386-expand.cc | 3 + gcc/config/i386/i386-options.cc | 10 +- gcc/config/i386/immintrin.h | 8 + gcc/config/i386/sha512intrin.h | 64 +++++++ gcc/config/i386/sm3intrin.h | 72 +++++++ gcc/config/i386/sm4intrin.h | 70 +++++++ gcc/config/i386/sse.md | 180 ++++++++++++++++++ .../gcc.target/i386/avxvnniint16-1.c | 41 ++++ gcc/testsuite/gcc.target/i386/funcspec-56.inc | 8 + gcc/testsuite/gcc.target/i386/sha512-1.c | 18 ++ gcc/testsuite/gcc.target/i386/sm3-1.c | 17 ++ gcc/testsuite/gcc.target/i386/sm4-1.c | 20 ++ gcc/testsuite/lib/target-supports.exp | 55 ++++++ 19 files changed, 959 insertions(+), 4 deletions(-) create mode 100644 contrib/arrowlake-backport-gap-report.md create mode 100644 gcc/config/i386/avxvnniint16intrin.h create mode 100644 gcc/config/i386/sha512intrin.h create mode 100644 gcc/config/i386/sm3intrin.h create mode 100644 gcc/config/i386/sm4intrin.h create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sha512-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sm3-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sm4-1.c diff --git a/contrib/arrowlake-backport-gap-report.md b/contrib/arrowlake-backport-gap-report.md new file mode 100644 index 00000000000..44f3b58b0a9 --- /dev/null +++ b/contrib/arrowlake-backport-gap-report.md @@ -0,0 +1,141 @@ +# Arrow Lake / Arrow Lake-S Backport Completeness Report (GCC 13.4 vs GCC 14.4) + +Date: 2026-09-05 +Scope: x86 machine features + C/C++ programmable surface (target options, feature macros, builtin strings, intrinsic headers, umbrella include wiring, builtin hooks, backend patterns). + +## 1) Architecture-level feature decomposition + +Authoritative basis in GCC 13.4: +- `PTA_ARROWLAKE = PTA_ALDERLAKE + AVXIFMA + AVXVNNIINT8 + AVXNECONVERT + CMPCCXADD + UINTR` +- `PTA_ARROWLAKE_S = PTA_ARROWLAKE + AVXVNNIINT16 + SHA512 + SM3 + SM4` + +Source lines: +- `gcc/config/i386/i386.h:2378` +- `gcc/config/i386/i386.h:2379` +- `gcc/config/i386/i386.h:2380` +- `gcc/config/i386/i386.h:2381` + +Interpretation: +- Arrow Lake delta over Alder Lake: `avxifma`, `avxvnniint8`, `avxneconvert`, `cmpccxadd`, `uintr` +- Arrow Lake-S delta over Arrow Lake: `avxvnniint16`, `sha512`, `sm3`, `sm4` + +Note: +- `raoint` is **not** in `PTA_ARROWLAKE`/`PTA_ARROWLAKE_S` baseline composition, but can still be manually enabled via `-mraoint` and has its own intrinsic header. + +## 2) Full feature matrix for Arrow Lake-related programmable surface + +Legend: +- OK: present and wired +- GAP: missing in GCC 13.4 relative to GCC 14.4 +- N/A: not part of Arrow Lake baseline delta + +| Feature | In ARL | In ARL-S | Option in 13.4 | Macro in 13.4 | builtin_cpu_supports string in 13.4 | Intrinsic header file in 13.4 | Umbrella include in 13.4 | Builtin defs in 13.4 | Backend patterns in 13.4 | 13.4 vs 14.4 status | +|---|---|---|---|---|---|---|---|---|---|---| +| avxifma | Yes | Yes | OK (`mavxifma`) | OK (`__AVXIFMA__`) | OK (`"avxifma"`) | OK (`avxifmaintrin.h`) | OK (`immintrin.h`) | OK | OK | OK | +| avxvnniint8 | Yes | Yes | OK (`mavxvnniint8`) | OK (`__AVXVNNIINT8__`) | OK (`"avxvnniint8"`) | OK (`avxvnniint8intrin.h`) | OK (`immintrin.h`) | OK | OK | OK | +| avxneconvert | Yes | Yes | OK (`mavxneconvert`) | OK (`__AVXNECONVERT__`) | OK (`"avxneconvert"`) | OK (`avxneconvertintrin.h`) | OK (`immintrin.h`) | OK | OK | OK | +| cmpccxadd | Yes | Yes | OK (`mcmpccxadd`) | OK (`__CMPCCXADD__`) | OK (`"cmpccxadd"`) | OK (`cmpccxaddintrin.h`) | OK (`x86gprintrin.h`) | OK | OK | OK | +| uintr | Yes | Yes | OK (`muintr`) | macro path exists in header usage model | OK (`"uintr"`) | OK (`uintrintrin.h`) | OK (`x86gprintrin.h`) | OK | OK | OK | +| avxvnniint16 | No | Yes | OK (`mavxvnniint16`) | OK (`__AVXVNNIINT16__`) | OK (`"avxvnniint16"`) | **GAP** (missing file) | **GAP** (not included by `immintrin.h`) | **GAP** | **GAP** | **Needs backport** | +| sha512 | No | Yes | OK (`msha512`) | OK (`__SHA512__`) | OK (`"sha512"`) | **GAP** (missing file) | **GAP** (not included by `immintrin.h`) | **GAP** | **GAP** | **Needs backport** | +| sm3 | No | Yes | OK (`msm3`) | OK (`__SM3__`) | OK (`"sm3"`) | **GAP** (missing file) | **GAP** (not included by `immintrin.h`) | **GAP** | **GAP** | **Needs backport** | +| sm4 | No | Yes | OK (`msm4`) | OK (`__SM4__`) | OK (`"sm4"`) | **GAP** (missing file) | **GAP** (not included by `immintrin.h`) | **GAP** | **GAP** | **Needs backport** | +| raoint | N/A | N/A | OK (`mraoint`) | OK (`__RAOINT__`) | OK (`"raoint"`) | OK (`raointintrin.h`) | OK (`x86gprintrin.h`) | OK (existing feature family) | OK | Not an ARL/ARL-S baseline delta | + +## 3) Evidence snapshots + +### 3.1 GCC 13.4 header presence check (requested list) +Present: +- `avxvnniint8intrin.h` +- `avxneconvertintrin.h` +- `cmpccxaddintrin.h` +- `raointintrin.h` + +Missing: +- `avxvnniint16intrin.h` +- `sha512intrin.h` +- `sm3intrin.h` +- `sm4intrin.h` + +### 3.2 GCC 14.4 has all eight requested headers +Present in `gcc-14.4.0/gcc/config/i386`: +- `avxvnniint16intrin.h` +- `avxvnniint8intrin.h` +- `avxneconvertintrin.h` +- `cmpccxaddintrin.h` +- `raointintrin.h` +- `sha512intrin.h` +- `sm3intrin.h` +- `sm4intrin.h` + +### 3.3 Umbrella include wiring differences +GCC 13.4: +- `immintrin.h` includes `avxifmaintrin.h`, `avxvnniint8intrin.h`, `avxneconvertintrin.h` +- `immintrin.h` does **not** include `avxvnniint16intrin.h`, `sha512intrin.h`, `sm3intrin.h`, `sm4intrin.h` +- `x86gprintrin.h` includes `cmpccxaddintrin.h`, `raointintrin.h`, `uintrintrin.h` + +GCC 14.4 adds in `immintrin.h`: +- `#include <avxvnniint16intrin.h>` +- `#include <sm3intrin.h>` +- `#include <sha512intrin.h>` +- `#include <sm4intrin.h>` + +### 3.4 Builtin/backend gap is real (not only header files) +GCC 13.4: +- No `vpdpwusd/vpdpwsud/vpdpwuud` AVXVNNIINT16 builtin entries in `i386-builtin.def` +- No `vsm3*`, `vsha512*`, `vsm4*` builtin entries in `i386-builtin.def` + +GCC 14.4: +- Has AVXVNNIINT16 builtin entries around `i386-builtin.def:2764-2775` +- Has `vsm3*` around `i386-builtin.def:1663-1665` +- Has `vsm4*` around `i386-builtin.def:1668-1671` +- Has `vsha512*` around `i386-builtin.def:1674-1676` +- Has backend instruction patterns in `sse.md` for SM3/SM4/SHA512 family + +### 3.5 Target attribute glue gap (`__attribute__((target("...")))`) +GCC 13.4 `i386-options.cc`: +- Contains `avxifma/avxvnniint8/avxneconvert/cmpccxadd/raoint` +- Missing `avxvnniint16/sm3/sha512/sm4` + +GCC 14.4 `i386-options.cc`: +- Adds option table entries and `IX86_ATTR_ISA` mapping for + - `avxvnniint16` + - `sm3` + - `sha512` + - `sm4` + +## 4) Backport requirement decision + +Conclusion: +- For Arrow Lake: programmable surface is largely complete in current GCC 13.4 backport state. +- For Arrow Lake-S: current state is **machine name + option/macro bits present but intrinsics pipeline incomplete**. +- Therefore, to make C/C++ development truly usable (intrinsics + target attributes + builtins), GCC 14 code backport is required for at least AVXVNNIINT16/SHA512/SM3/SM4 full chain. + +## 5) Minimum practical backport file set + +At minimum (from GCC 14.4 to GCC 13.4): +- New headers: + - `gcc/config/i386/avxvnniint16intrin.h` + - `gcc/config/i386/sha512intrin.h` + - `gcc/config/i386/sm3intrin.h` + - `gcc/config/i386/sm4intrin.h` +- Umbrella header wiring: + - `gcc/config/i386/immintrin.h` +- Builtin registration: + - `gcc/config/i386/i386-builtin.def` +- Backend instruction patterns/expanders used by those builtins: + - `gcc/config/i386/sse.md` +- Option/target-attribute glue for `target("...")` usability: + - `gcc/config/i386/i386-options.cc` + +Potentially needed depending on merge conflicts/context: +- `gcc/config/i386/i386-builtins.cc` (mask2 exposure logic in some GCC14 snapshots) +- tests to add for the new intrinsic headers and builtins + +## 6) Practical implication for your include snippet + +For GCC 13.4 current tree: +- These currently can be satisfied: `avxvnniint8intrin.h`, `avxneconvertintrin.h`, `cmpccxaddintrin.h`, `raointintrin.h` +- These currently cannot be satisfied end-to-end without GCC14 backport: `avxvnniint16intrin.h`, `sha512intrin.h`, `sm3intrin.h`, `sm4intrin.h` + +This means your `#ifdef` include pattern is conceptually right, but four headers/features are still blocked by missing backported frontend/backend pieces in GCC 13.4. diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 2a51fa01224..b55c0b813d5 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -119,6 +119,10 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_RAOINT_SET OPTION_MASK_ISA2_RAOINT #define OPTION_MASK_ISA2_AMX_COMPLEX_SET \ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_COMPLEX) +#define OPTION_MASK_ISA2_AVXVNNIINT16_SET OPTION_MASK_ISA2_AVXVNNIINT16 +#define OPTION_MASK_ISA2_SM3_SET OPTION_MASK_ISA2_SM3 +#define OPTION_MASK_ISA2_SHA512_SET OPTION_MASK_ISA2_SHA512 +#define OPTION_MASK_ISA2_SM4_SET OPTION_MASK_ISA2_SM4 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same as -msse4.2. */ @@ -225,7 +229,8 @@ along with GCC; see the file COPYING3. If not see (OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX512F_UNSET) #define OPTION_MASK_ISA2_AVX2_UNSET \ (OPTION_MASK_ISA2_AVXIFMA_UNSET | OPTION_MASK_ISA2_AVXVNNI_UNSET \ - | OPTION_MASK_ISA2_AVXVNNIINT8_UNSET | OPTION_MASK_ISA2_AVXNECONVERT_UNSET \ + | OPTION_MASK_ISA2_AVXVNNIINT8_UNSET | OPTION_MASK_ISA2_AVXNECONVERT_UNSET \ + | OPTION_MASK_ISA2_AVXVNNIINT16_UNSET \ | OPTION_MASK_ISA2_AVX512F_UNSET) #define OPTION_MASK_ISA_AVX512F_UNSET \ (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX512CD_UNSET \ @@ -300,6 +305,10 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_PREFETCHI_UNSET OPTION_MASK_ISA2_PREFETCHI #define OPTION_MASK_ISA2_RAOINT_UNSET OPTION_MASK_ISA2_RAOINT #define OPTION_MASK_ISA2_AMX_COMPLEX_UNSET OPTION_MASK_ISA2_AMX_COMPLEX +#define OPTION_MASK_ISA2_AVXVNNIINT16_UNSET OPTION_MASK_ISA2_AVXVNNIINT16 +#define OPTION_MASK_ISA2_SM3_UNSET OPTION_MASK_ISA2_SM3 +#define OPTION_MASK_ISA2_SHA512_UNSET OPTION_MASK_ISA2_SHA512 +#define OPTION_MASK_ISA2_SM4_UNSET OPTION_MASK_ISA2_SM4 /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -346,7 +355,10 @@ along with GCC; see the file COPYING3. If not see | OPTION_MASK_ISA2_AVX512VP2INTERSECT_UNSET) #define OPTION_MASK_ISA2_GENERAL_REGS_ONLY_UNSET \ OPTION_MASK_ISA2_SSE_UNSET -#define OPTION_MASK_ISA2_AVX_UNSET OPTION_MASK_ISA2_AVX2_UNSET +#define OPTION_MASK_ISA2_AVX_UNSET \ + (OPTION_MASK_ISA2_AVX2_UNSET | OPTION_MASK_ISA2_VAES_UNSET \ + | OPTION_MASK_ISA2_SM3_UNSET | OPTION_MASK_ISA2_SHA512_UNSET \ + | OPTION_MASK_ISA2_SM4_UNSET) #define OPTION_MASK_ISA2_SSE4_2_UNSET OPTION_MASK_ISA2_AVX_UNSET #define OPTION_MASK_ISA2_SSE4_1_UNSET OPTION_MASK_ISA2_SSE4_2_UNSET #define OPTION_MASK_ISA2_SSE4_UNSET OPTION_MASK_ISA2_SSE4_1_UNSET @@ -1263,6 +1275,69 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_mavxvnniint16: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AVXVNNIINT16_SET; + opts->x_ix86_isa_flags2_explicit |= + OPTION_MASK_ISA2_AVXVNNIINT16_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX2_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX2_SET; + } + else + { + opts->x_ix86_isa_flags2 &= + ~OPTION_MASK_ISA2_AVXVNNIINT16_UNSET; + opts->x_ix86_isa_flags2_explicit |= + OPTION_MASK_ISA2_AVXVNNIINT16_UNSET; + } + return true; + + case OPT_msm3: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_SM3_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM3_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SM3_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM3_UNSET; + } + return true; + + case OPT_msha512: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_SHA512_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SHA512_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SHA512_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SHA512_UNSET; + } + return true; + + case OPT_msm4: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_SM4_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM4_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SM4_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM4_UNSET; + } + return true; + case OPT_mfma: if (value) { diff --git a/gcc/config.gcc b/gcc/config.gcc index e084f0831e1..a344fb9c83c 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -433,7 +433,8 @@ i[34567]86-*-* | x86_64-*-*) amxbf16intrin.h x86gprintrin.h uintrintrin.h hresetintrin.h keylockerintrin.h avxvnniintrin.h mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h - avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h + avxifmaintrin.h avxvnniint8intrin.h avxvnniint16intrin.h + avxneconvertintrin.h sm3intrin.h sha512intrin.h sm4intrin.h cmpccxaddintrin.h amxfp16intrin.h prfchiintrin.h raointintrin.h amxcomplexintrin.h" ;; diff --git a/gcc/config/i386/avxvnniint16intrin.h b/gcc/config/i386/avxvnniint16intrin.h new file mode 100644 index 00000000000..f26c3139355 --- /dev/null +++ b/gcc/config/i386/avxvnniint16intrin.h @@ -0,0 +1,138 @@ +/* Copyright (C) 2023-2024 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#if !defined _IMMINTRIN_H_INCLUDED +#error "Never use <avxvnniint16intrin.h> directly; include <immintrin.h> instead." +#endif + +#ifndef _AVXVNNIINT16INTRIN_H_INCLUDED +#define _AVXVNNIINT16INTRIN_H_INCLUDED + +#if !defined(__AVXVNNIINT16__) +#pragma GCC push_options +#pragma GCC target("avxvnniint16") +#define __DISABLE_AVXVNNIINT16__ +#endif /* __AVXVNNIINT16__ */ + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwsud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwsud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwsuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwsuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwusd_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwusd128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwusds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwusds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwuud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwuud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwuuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwuuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwsud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwsud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwsuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwsuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwusd_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwusd256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwusds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwusds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwuud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwuud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwuuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwuuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +#ifdef __DISABLE_AVXVNNIINT16__ +#undef __DISABLE_AVXVNNIINT16__ +#pragma GCC pop_options +#endif /* __DISABLE_AVXVNNIINT16__ */ + +#endif /* __AVXVNNIINT16INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index cb2d0cd56ed..e9463120eea 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -1416,3 +1416,9 @@ DEF_FUNCTION_TYPE (LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT) # PREFETCHI builtins DEF_FUNCTION_TYPE (VOID, PCVOID, INT) DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT) + +# SM3 builtins +DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, V4SI, INT) + +# SHA512 builtins +DEF_FUNCTION_TYPE (V4DI, V4DI, V4DI, V2DI) diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index 63861a6d832..690e0f49ee4 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -1659,6 +1659,22 @@ BDESC (OPTION_MASK_ISA_SSE2, 0, CODE_FOR_sha256msg1, 0, IX86_BUILTIN_SHA256MSG1, BDESC (OPTION_MASK_ISA_SSE2, 0, CODE_FOR_sha256msg2, 0, IX86_BUILTIN_SHA256MSG2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI) BDESC (OPTION_MASK_ISA_SSE2, 0, CODE_FOR_sha256rnds2, 0, IX86_BUILTIN_SHA256RNDS2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +/* SM3 */ +BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg1, "__builtin_ia32_vsm3msg1", IX86_BUILTIN_VSM3MSG1, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg2, "__builtin_ia32_vsm3msg2", IX86_BUILTIN_VSM3MSG2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3rnds2, "__builtin_ia32_vsm3rnds2", IX86_BUILTIN_VSM3RNDS2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT) + +/* SM4 */ +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4key4_v4si, "__builtin_ia32_vsm4key4128", IX86_BUILTIN_VSM4KEY4128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4key4_v8si, "__builtin_ia32_vsm4key4256", IX86_BUILTIN_VSM4KEY4256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4rnds4_v4si, "__builtin_ia32_vsm4rnds4128", IX86_BUILTIN_VSM4RNDS4128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4rnds4_v8si, "__builtin_ia32_vsm4rnds4256", IX86_BUILTIN_VSM4RNDS4256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI) + +/* SHA512 */ +BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512msg1, "__builtin_ia32_vsha512msg1", IX86_BUILTIN_VSHA512MSG1, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI) +BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512msg2, "__builtin_ia32_vsha512msg2", IX86_BUILTIN_VSHA512MSG2, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI) +BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512rnds2, "__builtin_ia32_vsha512rnds2", IX86_BUILTIN_VSHA512RNDS2, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V2DI) + /* AVX512VL. */ BDESC (OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_avx2_palignrv32qi_mask, "__builtin_ia32_palignr256_mask", IX86_BUILTIN_PALIGNR256_MASK, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT_V4DI_USI_CONVERT) BDESC (OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_ssse3_palignrv16qi_mask, "__builtin_ia32_palignr128_mask", IX86_BUILTIN_PALIGNR128_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT_V2DI_UHI_CONVERT) @@ -2744,6 +2760,20 @@ BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT8, CODE_FOR_vpdpbsuds_v4si, "__builtin_ia32 BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT8, CODE_FOR_vpdpbuud_v4si, "__builtin_ia32_vpdpbuud128", IX86_BUILTIN_VPDPBUUDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT8, CODE_FOR_vpdpbuuds_v4si, "__builtin_ia32_vpdpbuuds128", IX86_BUILTIN_VPDPBUUDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +/* AVXVNNIINT16 */ +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusd_v8si, "__builtin_ia32_vpdpwusd256", IX86_BUILTIN_VPDPWUSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusds_v8si, "__builtin_ia32_vpdpwusds256", IX86_BUILTIN_VPDPWUSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsud_v8si, "__builtin_ia32_vpdpwsud256", IX86_BUILTIN_VPDPWSUDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsuds_v8si, "__builtin_ia32_vpdpwsuds256", IX86_BUILTIN_VPDPWSUDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuud_v8si, "__builtin_ia32_vpdpwuud256", IX86_BUILTIN_VPDPWUUDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuuds_v8si, "__builtin_ia32_vpdpwuuds256", IX86_BUILTIN_VPDPWUUDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusd_v4si, "__builtin_ia32_vpdpwusd128", IX86_BUILTIN_VPDPWUSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusds_v4si, "__builtin_ia32_vpdpwusds128", IX86_BUILTIN_VPDPWUSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsud_v4si, "__builtin_ia32_vpdpwsud128", IX86_BUILTIN_VPDPWSUDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsuds_v4si, "__builtin_ia32_vpdpwsuds128", IX86_BUILTIN_VPDPWSUDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuud_v4si, "__builtin_ia32_vpdpwuud128", IX86_BUILTIN_VPDPWUUDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuuds_v4si, "__builtin_ia32_vpdpwuuds128", IX86_BUILTIN_VPDPWUUDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) + /* VPCLMULQDQ */ BDESC (OPTION_MASK_ISA_VPCLMULQDQ | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpclmulqdq_v2di, "__builtin_ia32_vpclmulqdq_v2di", IX86_BUILTIN_VPCLMULQDQ2, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT) BDESC (OPTION_MASK_ISA_VPCLMULQDQ | OPTION_MASK_ISA_AVX, 0, CODE_FOR_vpclmulqdq_v4di, "__builtin_ia32_vpclmulqdq_v4di", IX86_BUILTIN_VPCLMULQDQ4, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 3392a99c6d4..116d7c5a073 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -10705,6 +10705,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, case V16HI_FTYPE_V16HI_V16HI: case V8SI_FTYPE_V4DF_V4DF: case V8SI_FTYPE_V8SI_V8SI: + case V4DI_FTYPE_V4DI_V2DI: case V8SI_FTYPE_V16HI_V16HI: case V4DI_FTYPE_V4DI_V4DI: case V4DI_FTYPE_V8SI_V8SI: @@ -10977,6 +10978,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, case V8HI_FTYPE_V8DI_V8HI_UQI: case V8SI_FTYPE_V8DI_V8SI_UQI: case V4SI_FTYPE_V4SI_V4SI_V4SI: + case V4DI_FTYPE_V4DI_V4DI_V2DI: case V16SI_FTYPE_V16SI_V16SI_V16SI: case V8DI_FTYPE_V8DI_V8DI_V8DI: case V32HI_FTYPE_V32HI_V32HI_V32HI: @@ -11147,6 +11149,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, case V2DF_FTYPE_V2DF_V2DF_V2DI_INT: case V4DF_FTYPE_V4DF_V4DF_V4DI_INT: case V4SF_FTYPE_V4SF_V4SF_V4SI_INT: + case V4SI_FTYPE_V4SI_V4SI_V4SI_INT: case V8SF_FTYPE_V8SF_V8SF_V8SI_INT: case V16SF_FTYPE_V16SF_V16SF_V16SI_INT: nargs = 4; diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 19fb641f69d..149e45a6885 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -249,7 +249,11 @@ static struct ix86_target_opts isa2_opts[] = { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 }, { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI }, { "-mraoint", OPTION_MASK_ISA2_RAOINT }, - { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX } + { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX }, + { "-mavxvnniint16", OPTION_MASK_ISA2_AVXVNNIINT16 }, + { "-msm3", OPTION_MASK_ISA2_SM3 }, + { "-msha512", OPTION_MASK_ISA2_SHA512 }, + { "-msm4", OPTION_MASK_ISA2_SM4 } }; static struct ix86_target_opts isa_opts[] = { @@ -1105,6 +1109,10 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("prefetchi", OPT_mprefetchi), IX86_ATTR_ISA ("raoint", OPT_mraoint), IX86_ATTR_ISA ("amx-complex", OPT_mamx_complex), + IX86_ATTR_ISA ("avxvnniint16", OPT_mavxvnniint16), + IX86_ATTR_ISA ("sm3", OPT_msm3), + IX86_ATTR_ISA ("sha512", OPT_msha512), + IX86_ATTR_ISA ("sm4", OPT_msm4), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h index b220d871942..ea14354efbc 100644 --- a/gcc/config/i386/immintrin.h +++ b/gcc/config/i386/immintrin.h @@ -48,6 +48,8 @@ #include <avxvnniint8intrin.h> +#include <avxvnniint16intrin.h> + #include <avx2intrin.h> #include <avx512fintrin.h> @@ -106,6 +108,12 @@ #include <shaintrin.h> +#include <sm3intrin.h> + +#include <sha512intrin.h> + +#include <sm4intrin.h> + #include <fmaintrin.h> #include <f16cintrin.h> diff --git a/gcc/config/i386/sha512intrin.h b/gcc/config/i386/sha512intrin.h new file mode 100644 index 00000000000..b6816b7d087 --- /dev/null +++ b/gcc/config/i386/sha512intrin.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2023-2024 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use <sha512intrin.h> directly; include <immintrin.h> instead." +#endif + +#ifndef _SHA512INTRIN_H_INCLUDED +#define _SHA512INTRIN_H_INCLUDED + +#ifndef __SHA512__ +#pragma GCC push_options +#pragma GCC target("sha512") +#define __DISABLE_SHA512__ +#endif /* __SHA512__ */ + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512msg1_epi64 (__m256i __A, __m128i __B) +{ + return (__m256i) __builtin_ia32_vsha512msg1 ((__v4di) __A, (__v2di) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512msg2_epi64 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsha512msg2 ((__v4di) __A, (__v4di) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512rnds2_epi64 (__m256i __A, __m256i __B, __m128i __C) +{ + return (__m256i) __builtin_ia32_vsha512rnds2 ((__v4di) __A, (__v4di) __B, + (__v2di) __C); +} + +#ifdef __DISABLE_SHA512__ +#undef __DISABLE_SHA512__ +#pragma GCC pop_options +#endif /* __DISABLE_SHA512__ */ + +#endif /* _SHA512INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/sm3intrin.h b/gcc/config/i386/sm3intrin.h new file mode 100644 index 00000000000..7f7fc1e9179 --- /dev/null +++ b/gcc/config/i386/sm3intrin.h @@ -0,0 +1,72 @@ +/* Copyright (C) 2023-2024 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use <sm3intrin.h> directly; include <immintrin.h> instead." +#endif + +#ifndef _SM3INTRIN_H_INCLUDED +#define _SM3INTRIN_H_INCLUDED + +#ifndef __SM3__ +#pragma GCC push_options +#pragma GCC target("sm3") +#define __DISABLE_SM3__ +#endif /* __SM3__ */ + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3msg1_epi32 (__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i) __builtin_ia32_vsm3msg1 ((__v4si) __A, (__v4si) __B, + (__v4si) __C); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3msg2_epi32 (__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i) __builtin_ia32_vsm3msg2 ((__v4si) __A, (__v4si) __B, + (__v4si) __C); +} + +#ifdef __OPTIMIZE__ +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3rnds2_epi32 (__m128i __A, __m128i __B, __m128i __C, const int __D) +{ + return (__m128i) __builtin_ia32_vsm3rnds2 ((__v4si) __A, (__v4si) __B, + (__v4si) __C, __D); +} +#else +#define _mm_sm3rnds2_epi32(A, B, C, D) \ + ((__m128i) __builtin_ia32_vsm3rnds2 ((__v4si) (A), (__v4si) (B), \ + (__v4si) (C), (int) (D))) +#endif + +#ifdef __DISABLE_SM3__ +#undef __DISABLE_SM3__ +#pragma GCC pop_options +#endif /* __DISABLE_SM3__ */ + +#endif /* _SM3INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/sm4intrin.h b/gcc/config/i386/sm4intrin.h new file mode 100644 index 00000000000..4c212ccb566 --- /dev/null +++ b/gcc/config/i386/sm4intrin.h @@ -0,0 +1,70 @@ +/* Copyright (C) 2023-2024 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use <sm4intrin.h> directly; include <immintrin.h> instead." +#endif + +#ifndef _SM4INTRIN_H_INCLUDED +#define _SM4INTRIN_H_INCLUDED + +#ifndef __SM4__ +#pragma GCC push_options +#pragma GCC target("sm4") +#define __DISABLE_SM4__ +#endif /* __SM4__ */ + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm4key4_epi32 (__m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_vsm4key4128 ((__v4si) __A, (__v4si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sm4key4_epi32 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsm4key4256 ((__v8si) __A, (__v8si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm4rnds4_epi32 (__m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_vsm4rnds4128 ((__v4si) __A, (__v4si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sm4rnds4_epi32 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsm4rnds4256 ((__v8si) __A, (__v8si) __B); +} + +#ifdef __DISABLE_SM4__ +#undef __DISABLE_SM4__ +#pragma GCC pop_options +#endif /* __DISABLE_SM4__ */ + +#endif /* _SM4INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index e257b98ff65..d87d287228e 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -198,6 +198,11 @@ UNSPEC_COMPLEX_FCMUL UNSPEC_COMPLEX_MASK + ;; For SM3 support + UNSPEC_SM3MSG1 + UNSPEC_SM3MSG2 + UNSPEC_SM3RNDS2 + ;; For AVX-VNNI-INT8 support UNSPEC_VPDPBSSD UNSPEC_VPDPBSSDS @@ -205,6 +210,23 @@ UNSPEC_VPDPBSUDS UNSPEC_VPDPBUUD UNSPEC_VPDPBUUDS + + ;; For AVX-VNNI-INT16 support + UNSPEC_VPDPWUSD + UNSPEC_VPDPWUSDS + UNSPEC_VPDPWSUD + UNSPEC_VPDPWSUDS + UNSPEC_VPDPWUUD + UNSPEC_VPDPWUUDS + + ;; For SHA512 support + UNSPEC_SHA512MSG1 + UNSPEC_SHA512MSG2 + UNSPEC_SHA512RNDS2 + + ;; For SM4 support + UNSPEC_SM4KEY4 + UNSPEC_SM4RNDS4 ]) (define_c_enum "unspecv" [ @@ -527,6 +549,10 @@ (define_mode_iterator VI2_AVX2 [(V32HI "TARGET_AVX512BW") (V16HI "TARGET_AVX2") V8HI]) +;; AVXVNNIINT16 is only available in 128-bit and 256-bit forms. +(define_mode_iterator VI2_AVXVNNIINT16 + [(V16HI "TARGET_AVX2") V8HI]) + (define_mode_iterator VI2_AVX512F [(V32HI "TARGET_AVX512F") (V16HI "TARGET_AVX2") V8HI]) @@ -28009,6 +28035,100 @@ (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) +(define_insn "vsm3msg1" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (unspec:V4SI + [(match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 2 "register_operand" "x") + (match_operand:V4SI 3 "vector_operand" "xBm")] + UNSPEC_SM3MSG1))] + "TARGET_SM3" + "vsm3msg1\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "other") + (set_attr "mode" "TI")]) + +(define_insn "vsm3msg2" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (unspec:V4SI + [(match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 2 "register_operand" "x") + (match_operand:V4SI 3 "vector_operand" "xBm")] + UNSPEC_SM3MSG2))] + "TARGET_SM3" + "vsm3msg2\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "other") + (set_attr "mode" "TI")]) + +(define_insn "vsm3rnds2" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (unspec:V4SI + [(match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 2 "register_operand" "x") + (match_operand:V4SI 3 "vector_operand" "xBm") + (match_operand:SI 4 "const_0_to_255_operand" "n")] + UNSPEC_SM3RNDS2))] + "TARGET_SM3" + "vsm3rnds2\t{%4, %3, %2, %0|%0, %2, %3, %4}" + [(set_attr "type" "other") + (set_attr "mode" "TI") + (set_attr "length_immediate" "1")]) + +(define_insn "vsha512msg1" + [(set (match_operand:V4DI 0 "register_operand" "=x") + (unspec:V4DI + [(match_operand:V4DI 1 "register_operand" "0") + (match_operand:V2DI 2 "register_operand" "x")] + UNSPEC_SHA512MSG1))] + "TARGET_SHA512" + "vsha512msg1\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "mode" "OI")]) + +(define_insn "vsha512msg2" + [(set (match_operand:V4DI 0 "register_operand" "=x") + (unspec:V4DI + [(match_operand:V4DI 1 "register_operand" "0") + (match_operand:V4DI 2 "register_operand" "x")] + UNSPEC_SHA512MSG2))] + "TARGET_SHA512" + "vsha512msg2\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "mode" "OI")]) + +(define_insn "vsha512rnds2" + [(set (match_operand:V4DI 0 "register_operand" "=x") + (unspec:V4DI + [(match_operand:V4DI 1 "register_operand" "0") + (match_operand:V4DI 2 "register_operand" "x") + (match_operand:V2DI 3 "register_operand" "x")] + UNSPEC_SHA512RNDS2))] + "TARGET_SHA512" + "vsha512rnds2\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "sselog1") + (set_attr "mode" "OI")]) + +(define_insn "vsm4key4_<mode>" + [(set (match_operand:VI4_AVX 0 "register_operand" "=x") + (unspec:VI4_AVX + [(match_operand:VI4_AVX 1 "register_operand" "x") + (match_operand:VI4_AVX 2 "vector_operand" "xBm")] + UNSPEC_SM4KEY4))] + "TARGET_SM4" + "vsm4key4\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "other") + (set_attr "mode" "<sseinsnmode>")]) + +(define_insn "vsm4rnds4_<mode>" + [(set (match_operand:VI4_AVX 0 "register_operand" "=x") + (unspec:VI4_AVX + [(match_operand:VI4_AVX 1 "register_operand" "x") + (match_operand:VI4_AVX 2 "vector_operand" "xBm")] + UNSPEC_SM4RNDS4))] + "TARGET_SM4" + "vsm4rnds4\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "other") + (set_attr "mode" "<sseinsnmode>")]) + (define_insn_and_split "avx512f_<castmode><avxsizesuffix>_<castmode>" [(set (match_operand:AVX512MODE2P 0 "nonimmediate_operand" "=x,m") (vec_concat:AVX512MODE2P @@ -29629,3 +29749,63 @@ "vcvtneo<bf16_ph>2ps\t{%1, %0|%0, %1}" [(set_attr "prefix" "vex") (set_attr "mode" "<sseinsnmode>")]) + +(define_int_iterator VPDPWPROD + [UNSPEC_VPDPWUSD + UNSPEC_VPDPWUSDS + UNSPEC_VPDPWSUD + UNSPEC_VPDPWSUDS + UNSPEC_VPDPWUUD + UNSPEC_VPDPWUUDS]) + +(define_int_attr vpdpwprodtype + [(UNSPEC_VPDPWUSD "wusd") (UNSPEC_VPDPWUSDS "wusds") + (UNSPEC_VPDPWSUD "wsud") (UNSPEC_VPDPWSUDS "wsuds") + (UNSPEC_VPDPWUUD "wuud") (UNSPEC_VPDPWUUDS "wuuds")]) + +(define_expand "usdot_prod<mode>" + [(match_operand:<sseunpackmode> 0 "register_operand") + (match_operand:VI2_AVXVNNIINT16 1 "register_operand") + (match_operand:VI2_AVXVNNIINT16 2 "register_operand") + (match_operand:<sseunpackmode> 3 "register_operand")] + "TARGET_AVXVNNIINT16" +{ + operands[1] = lowpart_subreg (<sseunpackmode>mode, + force_reg (<MODE>mode, operands[1]), + <MODE>mode); + operands[2] = lowpart_subreg (<sseunpackmode>mode, + force_reg (<MODE>mode, operands[2]), + <MODE>mode); + emit_insn (gen_vpdpwusd_<SDOT_VPDP_SUF> (operands[0], operands[3], + operands[1], operands[2])); + DONE; +}) + +(define_expand "udot_prod<mode>" + [(match_operand:<sseunpackmode> 0 "register_operand") + (match_operand:VI2_AVXVNNIINT16 1 "register_operand") + (match_operand:VI2_AVXVNNIINT16 2 "register_operand") + (match_operand:<sseunpackmode> 3 "register_operand")] + "TARGET_AVXVNNIINT16" +{ + operands[1] = lowpart_subreg (<sseunpackmode>mode, + force_reg (<MODE>mode, operands[1]), + <MODE>mode); + operands[2] = lowpart_subreg (<sseunpackmode>mode, + force_reg (<MODE>mode, operands[2]), + <MODE>mode); + emit_insn (gen_vpdpwuud_<SDOT_VPDP_SUF> (operands[0], operands[3], + operands[1], operands[2])); + DONE; +}) + +(define_insn "vpdp<vpdpwprodtype>_<mode>" + [(set (match_operand:VI4_AVX 0 "register_operand" "=x") + (unspec:VI4_AVX + [(match_operand:VI4_AVX 1 "register_operand" "0") + (match_operand:VI4_AVX 2 "register_operand" "x") + (match_operand:VI4_AVX 3 "nonimmediate_operand" "xm")] + VPDPWPROD))] + "TARGET_AVXVNNIINT16" + "vpdp<vpdpwprodtype>\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "prefix" "vex")]) diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-1.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-1.c new file mode 100644 index 00000000000..f45ce993690 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-1.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-mavxvnniint16 -O2" } */ +/* { dg-final { scan-assembler-times "vpdpwusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsud\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsud\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsuds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsuds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuud\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuud\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuuds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+\[^\n\r\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuuds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+\[^\n\r\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ + +#include <immintrin.h> + +volatile __m256i x, y, z; +volatile __m128i x_, y_, z_; + +void +avxvnniint16_test (void) +{ + x = _mm256_dpwusd_avx_epi32 (x, y, z); + x_ = _mm_dpwusd_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwusds_avx_epi32 (x, y, z); + x_ = _mm_dpwusds_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwsud_avx_epi32 (x, y, z); + x_ = _mm_dpwsud_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwsuds_avx_epi32 (x, y, z); + x_ = _mm_dpwsuds_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwuud_avx_epi32 (x, y, z); + x_ = _mm_dpwuud_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwuuds_avx_epi32 (x, y, z); + x_ = _mm_dpwuuds_avx_epi32 (x_, y_, z_); +} diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index 6bfdcdade82..f90db003e3a 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -88,6 +88,10 @@ extern void test_amx_fp16 (void) __attribute__((__target__("amx-fp16"))); extern void test_prefetchi (void) __attribute__((__target__("prefetchi"))); extern void test_raoint (void) __attribute__((__target__("raoint"))); extern void test_amx_complex (void) __attribute__((__target__("amx-complex"))); +extern void test_avxvnniint16 (void) __attribute__((__target__("avxvnniint16"))); +extern void test_sm3 (void) __attribute__((__target__("sm3"))); +extern void test_sha512 (void) __attribute__((__target__("sha512"))); +extern void test_sm4 (void) __attribute__((__target__("sm4"))); extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); @@ -177,6 +181,10 @@ extern void test_no_amx_fp16 (void) __attribute__((__target__("no-amx-fp16"))); extern void test_no_prefetchi (void) __attribute__((__target__("no-prefetchi"))); extern void test_no_raoint (void) __attribute__((__target__("no-raoint"))); extern void test_no_amx_complex (void) __attribute__((__target__("no-amx-complex"))); +extern void test_no_avxvnniint16 (void) __attribute__((__target__("no-avxvnniint16"))); +extern void test_no_sm3 (void) __attribute__((__target__("no-sm3"))); +extern void test_no_sha512 (void) __attribute__((__target__("no-sha512"))); +extern void test_no_sm4 (void) __attribute__((__target__("no-sm4"))); extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); diff --git a/gcc/testsuite/gcc.target/i386/sha512-1.c b/gcc/testsuite/gcc.target/i386/sha512-1.c new file mode 100644 index 00000000000..0dbabcd0d48 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sha512-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msha512" } */ +/* { dg-final { scan-assembler "vsha512msg1\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsha512msg2\[ \\t\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsha512rnds2\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ + +#include <immintrin.h> + +volatile __m128i x; +volatile __m256i y; + +void +sha512_test (void) +{ + y = _mm256_sha512msg1_epi64 (y, x); + y = _mm256_sha512msg2_epi64 (y, y); + y = _mm256_sha512rnds2_epi64 (y, y, x); +} diff --git a/gcc/testsuite/gcc.target/i386/sm3-1.c b/gcc/testsuite/gcc.target/i386/sm3-1.c new file mode 100644 index 00000000000..9822ee5613f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm3-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msm3" } */ +/* { dg-final { scan-assembler "vsm3msg1\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm3msg2\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm3rnds2\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ + +#include <immintrin.h> + +volatile __m128i x, y, z; + +void +sm3_test (void) +{ + x = _mm_sm3msg1_epi32 (x, y, z); + x = _mm_sm3msg2_epi32 (x, y, z); + x = _mm_sm3rnds2_epi32 (x, y, z, 1); +} diff --git a/gcc/testsuite/gcc.target/i386/sm4-1.c b/gcc/testsuite/gcc.target/i386/sm4-1.c new file mode 100644 index 00000000000..1692ec033b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm4-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msm4" } */ +/* { dg-final { scan-assembler "vsm4key4\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm4key4\[ \\t\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm4rnds4\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm4rnds4\[ \\t\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ + +#include <immintrin.h> + +volatile __m128i a, b, c; +volatile __m256i d, e, f; + +void +sm4_test (void) +{ + a = _mm_sm4key4_epi32 (b, c); + d = _mm256_sm4key4_epi32 (e, f); + a = _mm_sm4rnds4_epi32 (b, c); + d = _mm256_sm4rnds4_epi32 (e, f); +} diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 2e9e5291741..e42ee2896fd 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9734,6 +9734,61 @@ proc check_effective_target_avxvnniint8 { } { } "-O0 -mavxvnniint8" ] } +# Return 1 if avxvnniint16 instructions can be compiled. +proc check_effective_target_avxvnniint16 { } { + return [check_no_compiler_messages avxvnniint16 object { + typedef int __v8si __attribute__ ((__vector_size__ (32))); + __v8si + _mm256_dpwsud_avx_epi32 (__v8si __A, __v8si __B, __v8si __C) + { + return __builtin_ia32_vpdpwsud256 (__A, __B, __C); + } + } "-O0 -mavxvnniint16" ] +} + +# Return 1 if sm3 instructions can be compiled. +proc check_effective_target_sm3 { } { + return [check_no_compiler_messages sm3 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + __m128i + _mm_sm3msg1_epi32 (__m128i __A, __m128i __B, __m128i __C) + { + return (__m128i) __builtin_ia32_vsm3msg1 ((__v4si) __A, + (__v4si) __B, + (__v4si) __C); + } + } "-msm3" ] +} + +# Return 1 if sha512 instructions can be compiled. +proc check_effective_target_sha512 { } { + return [check_no_compiler_messages sha512 object { + typedef long long __m256i __attribute__ ((__vector_size__ (32))); + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + __m256i + _mm256_sha512msg2_epi64 (__m256i __A, __m256i __B) + { + return (__m256i) __builtin_ia32_vsha512msg2 ((__v4di) __A, + (__v4di) __B); + } + } "-msha512" ] +} + +# Return 1 if sm4 instructions can be compiled. +proc check_effective_target_sm4 { } { + return [check_no_compiler_messages sm4 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + __m128i + _mm_sm4key4_epi32 (__m128i __A, __m128i __B) + { + return (__m128i) __builtin_ia32_vsm4key4128 ((__v4si) __A, + (__v4si) __B); + } + } "-msm4" ] +} + # Return 1 if avxneconvert instructions can be compiled. proc check_effective_target_avxneconvert { } { return [check_no_compiler_messages avxneconvert object { -- 2.47.3
