AMD General Hi
> -----Original Message----- > From: Haochen Jiang <[email protected]> > Sent: Thursday, July 2, 2026 12:19 PM > To: [email protected] > Cc: [email protected]; [email protected]; Sharma, Dipesh > <[email protected]>; Kumar, Venkataramanan > <[email protected]> > Subject: [PATCH 7/7] Support ACEv1 outer product instructions > > Caution: This message originated from an External Source. Use proper caution > when opening attachments, clicking links, or responding. > > > Outer product instructions in ACEv1 are quite similar as those VNNI dot > product > instructions in AVX/AVX512/AVX10 space. Thus, we use the same naming > convention as dot product for these insts. > > gcc/ChangeLog: > > * config/i386/acev1intrin.h: Add new intrins. > * config/i386/i386-builtin-types.def: Add new builtin type. > * config/i386/i386-builtin.def (BDESC): Add new builtins. > * config/i386/i386-expand.cc (ix86_expand_ace_builtin): > Handle new builtin type. > * config/i386/sse.md (UNSPECV_TOP2BF16PS): New. > (UNSPECV_TOP4BSSD): Ditto. > (UNSPECV_TOP4BSSDS): Ditto. > (UNSPECV_TOP4BSUD): Ditto. > (UNSPECV_TOP4BSUDS): Ditto. > (UNSPECV_TOP4BUSD): Ditto. > (UNSPECV_TOP4BUSDS): Ditto. > (UNSPECV_TOP4BUUD): Ditto. > (UNSPECV_TOP4BUUDS): Ditto. > (UNSPECV_TOP4MXBF8PS): Ditto. > (UNSPECV_TOP4MXBHF8PS): Ditto. > (UNSPECV_TOP4MXHBF8PS): Ditto. > (UNSPECV_TOP4MXHF8PS): Ditto. > (UNSPECV_TOP4MXBSSPS): Ditto. > (top2bf16ps): Ditto. > (top4<top4bdtype>): Ditto. > (top4<top4mxfp8type>ps): Ditto. > (top4mxbssps): Ditto. > > gcc/testsuite/ChangeLog: > > * gcc.target/i386/acev1-1.c: Add compile test. > * gcc.target/i386/ace-check.h: Add helper function. > * gcc.target/i386/ace-helper.h: Ditto. > * gcc.target/i386/fp8-helper.h: Modify helper function > to skip special value check. > * gcc.target/i386/avx-1.c: Add acev1 tests. > * gcc.target/i386/sse-13.c: Ditto. > * gcc.target/i386/sse-14.c: Ditto. > * gcc.target/i386/sse-22.c: Ditto. > * gcc.target/i386/sse-23.c: Ditto. > * gcc.target/i386/acev1-op2bf16ps-2.c: New test. > * gcc.target/i386/acev1-op4bssd-2.c: Ditto. > * gcc.target/i386/acev1-op4bsud-2.c: Ditto. > * gcc.target/i386/acev1-op4busd-2.c: Ditto. > * gcc.target/i386/acev1-op4buud-2.c: Ditto. > * gcc.target/i386/acev1-op4mxbf8ps-2.c: Ditto. > * gcc.target/i386/acev1-op4mxbhf8ps-2.c: Ditto. > * gcc.target/i386/acev1-op4mxbssps-2.c: Ditto. > * gcc.target/i386/acev1-op4mxhbf8ps-2.c: Ditto. > * gcc.target/i386/acev1-op4mxhf8ps-2.c: Ditto. > > Co-authored-by: Dipesh Sharma <[email protected]> > --- > gcc/config/i386/acev1intrin.h | 100 ++++++++++++++++++ > gcc/config/i386/i386-builtin-types.def | 3 + > gcc/config/i386/i386-builtin.def | 10 ++ > gcc/config/i386/i386-expand.cc | 18 +++- > gcc/config/i386/sse.md | 82 ++++++++++++++ > gcc/testsuite/gcc.target/i386/ace-check.h | 21 ++++ > gcc/testsuite/gcc.target/i386/ace-helper.h | 11 ++ > gcc/testsuite/gcc.target/i386/acev1-1.c | 24 +++++ > .../gcc.target/i386/acev1-op2bf16ps-2.c | 47 ++++++++ > .../gcc.target/i386/acev1-op4bssd-2.c | 47 ++++++++ > .../gcc.target/i386/acev1-op4bsud-2.c | 48 +++++++++ > .../gcc.target/i386/acev1-op4busd-2.c | 48 +++++++++ > .../gcc.target/i386/acev1-op4buud-2.c | 46 ++++++++ > .../gcc.target/i386/acev1-op4mxbf8ps-2.c | 59 +++++++++++ > .../gcc.target/i386/acev1-op4mxbhf8ps-2.c | 59 +++++++++++ > .../gcc.target/i386/acev1-op4mxbssps-2.c | 54 ++++++++++ > .../gcc.target/i386/acev1-op4mxhbf8ps-2.c | 59 +++++++++++ > .../gcc.target/i386/acev1-op4mxhf8ps-2.c | 59 +++++++++++ > gcc/testsuite/gcc.target/i386/avx-1.c | 10 ++ > gcc/testsuite/gcc.target/i386/fp8-helper.h | 21 ++-- > gcc/testsuite/gcc.target/i386/sse-13.c | 10 ++ > gcc/testsuite/gcc.target/i386/sse-14.c | 14 +++ > gcc/testsuite/gcc.target/i386/sse-22.c | 14 +++ > gcc/testsuite/gcc.target/i386/sse-23.c | 10 ++ > 24 files changed, 862 insertions(+), 12 deletions(-) create mode 100644 > gcc/testsuite/gcc.target/i386/acev1-op2bf16ps-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4bssd-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4bsud-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4busd-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4buud-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4mxbf8ps-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4mxbhf8ps-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4mxbssps-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4mxhbf8ps-2.c > create mode 100644 gcc/testsuite/gcc.target/i386/acev1-op4mxhf8ps-2.c > > diff --git a/gcc/config/i386/acev1intrin.h b/gcc/config/i386/acev1intrin.h > index > 7b205304302..a449c52af01 100644 > --- a/gcc/config/i386/acev1intrin.h > +++ b/gcc/config/i386/acev1intrin.h > @@ -155,6 +155,76 @@ _tile_insertcol (const int __A, __m512i __B, int __C) > __builtin_ia32_tilemovcolinsert (__A, (__v16si) __B, __C); } > > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op2bf16_ps (const int __W, __m512bh __A, __m512bh __B) { > + __builtin_ia32_top2bf16ps (__W, (__v32bf) __A, (__v32bf) __B); } > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4bssd_epi32 (const int __W, __m512i __A, __m512i __B) { > + __builtin_ia32_top4bssd (__W, (__v64qi) __A, (__v64qi) __B); } > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4bsud_epi32 (const int __W, __m512i __A, __m512i __B) { > + __builtin_ia32_top4bsud (__W, (__v64qi) __A, (__v64qi) __B); } > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4busd_epi32 (const int __W, __m512i __A, __m512i __B) { > + __builtin_ia32_top4busd (__W, (__v64qi) __A, (__v64qi) __B); } > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4buud_epi32 (const int __W, __m512i __A, __m512i __B) { > + __builtin_ia32_top4buud (__W, (__v64qi) __A, (__v64qi) __B); } > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4mxbf8_ps (const int __W, __m512i __A, __m512i __B, const int > +__C) { > + __builtin_ia32_top4mxbf8ps (__W, (__v64qi) __A, (__v64qi) __B, __C); > +} > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4mxbhf8_ps (const int __W, __m512i __A, __m512i __B, const int > +__C) { > + __builtin_ia32_top4mxbhf8ps (__W, (__v64qi) __A, (__v64qi) __B, __C); > +} > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4mxhbf8_ps (const int __W, __m512i __A, __m512i __B, const int > +__C) { > + __builtin_ia32_top4mxhbf8ps (__W, (__v64qi) __A, (__v64qi) __B, __C); > +} > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4mxhf8_ps (const int __W, __m512i __A, __m512i __B, const int > +__C) { > + __builtin_ia32_top4mxhf8ps (__W, (__v64qi) __A, (__v64qi) __B, __C); > +} > + > +extern __inline void > +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) > +_tile_op4mxbss_ps (const int __W, __m512i __A, __m512i __B, const int > +__C) { > + __builtin_ia32_top4mxbssps (__W, (__v64qi) __A, (__v64qi) __B, __C); > +} > + > #else > #define _tile_ace_zero(A) \ > __builtin_ia32_tilezero (A); > @@ -183,6 +253,36 @@ _tile_insertcol (const int __A, __m512i __B, int __C) > #define _tile_insertcol(A, B, C) \ > __builtin_ia32_tilemovcolinsert ((A), (__v16si) (B), (C)) > > +#define _tile_op2bf16_ps(W, A, B) \ > + __builtin_ia32_top2bf16ps (W, (__v32bf) (A), (__v32bf) (B)) > + > +#define _tile_op4bssd_epi32(W, A, B) \ > + __builtin_ia32_top4bssd (W, (__v64qi) (A), (__v64qi) (B)) > + > +#define _tile_op4bsud_epi32(W, A, B) \ > + __builtin_ia32_top4bsud (W, (__v64qi) (A), (__v64qi) (B)) > + > +#define _tile_op4busd_epi32(W, A, B) \ > + __builtin_ia32_top4busd (W, (__v64qi) (A), (__v64qi) (B)) > + > +#define _tile_op4buud_epi32(W, A, B) \ > + __builtin_ia32_top4buud (W, (__v64qi) (A), (__v64qi) (B)) > + > +#define _tile_op4mxbf8_ps(W, A, B, C) \ > + __builtin_ia32_top4mxbf8ps (W, (__v64qi) (A), (__v64qi) (B), C) > + > +#define _tile_op4mxbhf8_ps(W, A, B, C) \ > + __builtin_ia32_top4mxbhf8ps (W, (__v64qi) (A), (__v64qi) (B), C) > + > +#define _tile_op4mxhbf8_ps(W, A, B, C) \ > + __builtin_ia32_top4mxhbf8ps (W, (__v64qi) (A), (__v64qi) (B), C) > + > +#define _tile_op4mxhf8_ps(W, A, B, C) \ > + __builtin_ia32_top4mxhf8ps (W, (__v64qi) (A), (__v64qi) (B), C) > + > +#define _tile_op4mxbss_ps(W, A, B, C) \ > + __builtin_ia32_top4mxbssps (W, (__v64qi) (A), (__v64qi) (B), C) > + > #endif /* __OPTIMIZE__ */ > > #endif /* __x86_64__ */ > diff --git a/gcc/config/i386/i386-builtin-types.def > b/gcc/config/i386/i386-builtin- > types.def > index c5869f11124..450c326dbda 100644 > --- a/gcc/config/i386/i386-builtin-types.def > +++ b/gcc/config/i386/i386-builtin-types.def > @@ -1510,3 +1510,6 @@ DEF_FUNCTION_TYPE (V32HF, UQI, SI) > DEF_FUNCTION_TYPE (V32BF, UQI, SI) DEF_FUNCTION_TYPE (V16SI, UQI, SI) > DEF_FUNCTION_TYPE (VOID, UQI, V16SI, SI) > +DEF_FUNCTION_TYPE (VOID, UQI, V32BF, V32BF) DEF_FUNCTION_TYPE (VOID, > +UQI, V64QI, V64QI) DEF_FUNCTION_TYPE (VOID, UQI, V64QI, V64QI, SI) > diff --git a/gcc/config/i386/i386-builtin.def > b/gcc/config/i386/i386-builtin.def > index 823fa33cc1f..65479370fc5 100644 > --- a/gcc/config/i386/i386-builtin.def > +++ b/gcc/config/i386/i386-builtin.def > @@ -3986,5 +3986,15 @@ BDESC (OPTION_MASK_ISA_64BIT, > OPTION_MASK_ISA2_ACEV1, CODE_FOR_tcvtrowps2phl, "_ BDESC > (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1, > CODE_FOR_tilemovrow_extract, "__builtin_ia32_tilemovrowextract", > IX86_BUILTIN_TILEMOVROWEXTRACT, UNKNOWN, (int) V16SI_FTYPE_UQI_SI) > BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1, > CODE_FOR_tilemovrow_insert, "__builtin_ia32_tilemovrowinsert", > IX86_BUILTIN_TILEMOVROWINSERT, UNKNOWN, (int) > VOID_FTYPE_UQI_V16SI_SI) BDESC (OPTION_MASK_ISA_64BIT, > OPTION_MASK_ISA2_ACEV1, CODE_FOR_tilemovcol_insert, > "__builtin_ia32_tilemovcolinsert", IX86_BUILTIN_TILEMOVCOLINSERT, > UNKNOWN, (int) VOID_FTYPE_UQI_V16SI_SI) > +BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1, > +CODE_FOR_top2bf16ps, "__builtin_ia32_top2bf16ps", > +IX86_BUILTIN_TOP2BF16PS, UNKNOWN, (int) VOID_FTYPE_UQI_V32BF_V32BF) > +BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1, > +CODE_FOR_top4bssd, "__builtin_ia32_top4bssd", IX86_BUILTIN_TOP4BSSD, > +UNKNOWN, (int) VOID_FTYPE_UQI_V64QI_V64QI) BDESC > +(OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1, > CODE_FOR_top4bsud, > +"__builtin_ia32_top4bsud", IX86_BUILTIN_TOP4BSUD, UNKNOWN, (int) > +VOID_FTYPE_UQI_V64QI_V64QI) BDESC (OPTION_MASK_ISA_64BIT, > +OPTION_MASK_ISA2_ACEV1, CODE_FOR_top4busd, > "__builtin_ia32_top4busd", > +IX86_BUILTIN_TOP4BUSD, UNKNOWN, (int) VOID_FTYPE_UQI_V64QI_V64QI) > BDESC > +(OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1, > CODE_FOR_top4buud, > +"__builtin_ia32_top4buud", IX86_BUILTIN_TOP4BUUD, UNKNOWN, (int) > +VOID_FTYPE_UQI_V64QI_V64QI) BDESC (OPTION_MASK_ISA_64BIT, > +OPTION_MASK_ISA2_ACEV1, CODE_FOR_top4mxbf8ps, > +"__builtin_ia32_top4mxbf8ps", IX86_BUILTIN_TOP4MXBF8PS, UNKNOWN, (int) > +VOID_FTYPE_UQI_V64QI_V64QI_SI) BDESC (OPTION_MASK_ISA_64BIT, > +OPTION_MASK_ISA2_ACEV1, CODE_FOR_top4mxbhf8ps, > +"__builtin_ia32_top4mxbhf8ps", IX86_BUILTIN_TOP4MXBHF8PS, UNKNOWN, > +(int) VOID_FTYPE_UQI_V64QI_V64QI_SI) BDESC (OPTION_MASK_ISA_64BIT, > +OPTION_MASK_ISA2_ACEV1, CODE_FOR_top4mxhbf8ps, > +"__builtin_ia32_top4mxhbf8ps", IX86_BUILTIN_TOP4MXHBF8PS, UNKNOWN, > +(int) VOID_FTYPE_UQI_V64QI_V64QI_SI) BDESC (OPTION_MASK_ISA_64BIT, > +OPTION_MASK_ISA2_ACEV1, CODE_FOR_top4mxhf8ps, > +"__builtin_ia32_top4mxhf8ps", IX86_BUILTIN_TOP4MXHF8PS, UNKNOWN, (int) > +VOID_FTYPE_UQI_V64QI_V64QI_SI) BDESC (OPTION_MASK_ISA_64BIT, > +OPTION_MASK_ISA2_ACEV1, CODE_FOR_top4mxbssps, > +"__builtin_ia32_top4mxbssps", IX86_BUILTIN_TOP4MXBSSPS, UNKNOWN, (int) > +VOID_FTYPE_UQI_V64QI_V64QI_SI) > > BDESC_END (ACE, MAX) > diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc > index 3e3a9de38ec..02ccca4890f 100644 > --- a/gcc/config/i386/i386-expand.cc > +++ b/gcc/config/i386/i386-expand.cc > @@ -14789,7 +14789,7 @@ ix86_expand_ace_builtin (const struct > builtin_description *d, tree exp, { > tree arg; > rtx pat, op; > - unsigned int i, nargs, arg_adjust = 0; > + unsigned int i, nargs, arg_adjust = 0, constant = 100; Any reason we put 100 here ?? > bool tmm_src = false; > rtx xops[4]; > enum insn_code icode = d->icode; > @@ -14808,8 +14808,14 @@ ix86_expand_ace_builtin (const struct > builtin_description *d, tree exp, > tmm_src = true; > break; > case VOID_FTYPE_UQI_V16SI_SI: > + case VOID_FTYPE_UQI_V32BF_V32BF: > + case VOID_FTYPE_UQI_V64QI_V64QI: > nargs = 3; > break; > + case VOID_FTYPE_UQI_V64QI_V64QI_SI: > + nargs = 4; > + constant = 3; > + break; > > default: > gcc_unreachable (); > @@ -14835,16 +14841,17 @@ ix86_expand_ace_builtin (const struct > builtin_description *d, tree exp, > arg = CALL_EXPR_ARG (exp, i); > op = ix86_expand_unsigned_small_int_cst_argument (arg); > > - if (i == 0) > + if (i == 0 || i == constant) > { > - /* This must be the tmm reg number constant. */ > + /* This must be the constant. */ > if (!insn_p->operand[i + arg_adjust].predicate(op, SImode)) > { > error ("the argument must be constant"); > return const0_rtx; > } > > - if (!IN_RANGE (INTVAL (op), 0, 7)) > + /* This must be the tmm reg number constant. */ > + if (i == 0 && !IN_RANGE (INTVAL (op), 0, 7)) > { > error ("the tmm register number argument must be between 0 to > 7"); > return const0_rtx; > @@ -14892,6 +14899,9 @@ ix86_expand_ace_builtin (const struct > builtin_description *d, tree exp, > case 3: > pat = GEN_FCN (icode) (xops[0], xops[1], xops[2]); > break; > + case 4: > + pat = GEN_FCN (icode) (xops[0], xops[1], xops[2], xops[3]); > + break; > default: > gcc_unreachable (); > } > diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index > 9a514161b3b..f65884921bb 100644 > --- a/gcc/config/i386/sse.md > +++ b/gcc/config/i386/sse.md > @@ -320,6 +320,20 @@ > UNSPECV_BSRMOVL_LOAD > UNSPECV_TILEMOVROWINSERT > UNSPECV_TILEMOVCOLINSERT > + UNSPECV_TOP2BF16PS > + UNSPECV_TOP4BSSD > + UNSPECV_TOP4BSSDS > + UNSPECV_TOP4BSUD > + UNSPECV_TOP4BSUDS > + UNSPECV_TOP4BUSD > + UNSPECV_TOP4BUSDS > + UNSPECV_TOP4BUUD > + UNSPECV_TOP4BUUDS > + UNSPECV_TOP4MXBF8PS > + UNSPECV_TOP4MXBHF8PS > + UNSPECV_TOP4MXHBF8PS > + UNSPECV_TOP4MXHF8PS > + UNSPECV_TOP4MXBSSPS > ]) > > ;; All vector modes including V?TImode, used in move patterns. > @@ -34612,3 +34626,71 @@ > "TARGET_ACEV1" > "tilemov<rowcol>\t{%2, %1, %%tmm%c0|tmm%c0, %1, %2}" > [(set_attr "prefix" "evex")]) > + > +(define_insn "top2bf16ps" > + [(set (reg:V32SF TMM_REGNUM) > + (unspec_volatile:V32SF > + [(match_operand:SI 0 "const_0_to_7_operand") In previous patches we are giving QI mode, should we follow the same? > + (match_operand:V32BF 1 "register_operand" "v") > + (match_operand:V32BF 2 "register_operand" "v")] > + UNSPECV_TOP2BF16PS))] > + "TARGET_ACEV1" > + "top2bf16ps\t{%2, %1, %%tmm%c0|tmm%c0, %1, %2}" > + [(set_attr "prefix" "evex")]) Can we add mode here and other places?? > + > +(define_int_iterator TOP4BDTYPE > + [UNSPECV_TOP4BSSD > + UNSPECV_TOP4BSUD > + UNSPECV_TOP4BUSD > + UNSPECV_TOP4BUUD]) > + > +(define_int_attr top4bdtype > + [(UNSPECV_TOP4BSSD "bssd") (UNSPECV_TOP4BSUD "bsud") > + (UNSPECV_TOP4BUSD "busd") (UNSPECV_TOP4BUUD "buud")]) > + > +(define_insn "top4<top4bdtype>" > + [(set (reg:V32SI TMM_REGNUM) > + (unspec_volatile:V32SI > + [(match_operand:SI 0 "const_0_to_7_operand") > + (match_operand:V64QI 1 "register_operand" "v") > + (match_operand:V64QI 2 "register_operand" "v")] > + TOP4BDTYPE))] > + "TARGET_ACEV1" > + "top4<top4bdtype>\t{%2, %1, %%tmm%c0|tmm%c0, %1, %2}" > + [(set_attr "prefix" "evex")]) > + > +(define_int_iterator TOP4MXFP8TYPE > + [UNSPECV_TOP4MXBF8PS UNSPECV_TOP4MXBHF8PS > + UNSPECV_TOP4MXHBF8PS UNSPECV_TOP4MXHF8PS]) > + > +(define_int_attr top4mxfp8type > + [(UNSPECV_TOP4MXBF8PS "mxbf8") > + (UNSPECV_TOP4MXBHF8PS "mxbhf8") > + (UNSPECV_TOP4MXHBF8PS "mxhbf8") > + (UNSPECV_TOP4MXHF8PS "mxhf8")]) > + > +(define_insn "top4<top4mxfp8type>ps" > + [(set (reg:V32SF TMM_REGNUM) > + (unspec_volatile:V32SF > + [(match_operand:SI 0 "const_0_to_7_operand") > + (match_operand:V64QI 1 "register_operand" "v") > + (match_operand:V64QI 2 "register_operand" "v") > + (match_operand:SI 3 "const_0_to_255_operand") > + (reg:V32SI BSR0_REG)] > + TOP4MXFP8TYPE))] > + "TARGET_ACEV1" > + "top4<top4mxfp8type>ps\t{%3, %2, %1, %%tmm%c0|tmm%c0, %1, %2, %3}" > + [(set_attr "prefix" "evex")]) > + > +(define_insn "top4mxbssps" > + [(set (reg:V32SF TMM_REGNUM) > + (unspec_volatile:V32SF > + [(match_operand:SI 0 "const_0_to_7_operand") > + (match_operand:V64QI 1 "register_operand" "v") > + (match_operand:V64QI 2 "register_operand" "v") > + (match_operand:SI 3 "const_0_to_255_operand") > + (reg:V32SI BSR0_REG)] > + UNSPECV_TOP4MXBSSPS))] > + "TARGET_ACEV1" > + "top4mxbssps\t{%3, %2, %1, %%tmm%c0|tmm%c0, %1, %2, %3}" > + [(set_attr "prefix" "evex")]) > diff --git a/gcc/testsuite/gcc.target/i386/ace-check.h > b/gcc/testsuite/gcc.target/i386/ace-check.h > index 210f20e7a47..e153c5ff84b 100644 > --- a/gcc/testsuite/gcc.target/i386/ace-check.h > +++ b/gcc/testsuite/gcc.target/i386/ace-check.h > @@ -63,6 +63,27 @@ void init_tile_config (__tilecfg *dst, __bsr* bsr) > _bsr0_init (); > } > > +#define CHECK_TILE_REGISTER(regnum, dst_ref) \ > +{ \ > + int miss = 0; \ > + for (int j = 0; j < 16; j++) \ > + { \ > + __m512i tmp; \ > + union512i_ub a; \ > + tmp = _tile_extractrow (regnum, j); \ > + a.x = tmp; \ > + for (int k = 0; k < 64; k++) \ > + if (a.a[k] != dst_ref.buf[j * 64 + k]) \ > + { \ > + printf ("Row %d Column %d: 0x%x != 0x%x\n", j, k, a.a[k], \ > + dst_ref.buf[j * 64 + k]); \ > + miss += 1; \ > + } \ > + } \ > + if (miss) \ > + abort (); \ > +} > + > #ifndef DO_TEST > #define DO_TEST do_test > static void test_ace (void); > diff --git a/gcc/testsuite/gcc.target/i386/ace-helper.h > b/gcc/testsuite/gcc.target/i386/ace-helper.h > index 8b4611e6e3f..9f9401aa2b2 100644 > --- a/gcc/testsuite/gcc.target/i386/ace-helper.h > +++ b/gcc/testsuite/gcc.target/i386/ace-helper.h > @@ -4,4 +4,15 @@ > #define AVX512FP16 > #define AVX512BF16 > #include "avx512f-helper.h" > +#include "fp8-helper.h" > + > +float convert_e8m0_to_fp32 (unsigned char x) { > + unsigned int tmp = ((unsigned int) x) << 23; > + Floatuint32Union ux = { .u = tmp }; > + if (x == 0xff) > + ux.u |= 0x1; > + return ux.f; > +} > + > #endif > diff --git a/gcc/testsuite/gcc.target/i386/acev1-1.c > b/gcc/testsuite/gcc.target/i386/acev1-1.c > index 6d01745c592..8976b555a4a 100644 > --- a/gcc/testsuite/gcc.target/i386/acev1-1.c > +++ b/gcc/testsuite/gcc.target/i386/acev1-1.c > @@ -15,6 +15,16 @@ > /* { dg-final { scan-assembler-times "tcvtrowps2phl\[ \t]" 1 } } */ > /* { dg-final { scan-assembler-times "tilemovrow\[ \t]" 2 } } */ > /* { dg-final { scan-assembler-times "tilemovcol\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top2bf16ps\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4bssd\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4bsud\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4busd\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4buud\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4mxbf8ps\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4mxbhf8ps\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4mxhbf8ps\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4mxhf8ps\[ \t]" 1 } } */ > +/* { dg-final { scan-assembler-times "top4mxbssps\[ \t]" 1 } } */ > #include <immintrin.h> > > extern int t[]; > @@ -52,3 +62,17 @@ void cvtrow () > _tile_insertrow (7, a1, 10); > _tile_insertcol (2, a2, 11); > } > + > +void op () > +{ > + _tile_op2bf16_ps (1, b1, b2); > + _tile_op4bssd_epi32 (2, a1, a2); > + _tile_op4bsud_epi32 (3, a1, a2); > + _tile_op4busd_epi32 (4, a1, a2); > + _tile_op4buud_epi32 (5, a1, a2); > + _tile_op4mxbf8_ps (6, a1, a2, 1); > + _tile_op4mxbhf8_ps (7, a1, a2, 6); > + _tile_op4mxhbf8_ps (0, a1, a2, 9); > + _tile_op4mxhf8_ps (1, a1, a2, 3); > + _tile_op4mxbss_ps (2, a1, a2, 4); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op2bf16ps-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op2bf16ps-2.c > new file mode 100644 > index 00000000000..c644eea4b77 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op2bf16ps-2.c > @@ -0,0 +1,47 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op2bf16ps > +void test_acev1_op2bf16ps (); > +#include "ace-helper.h" > + > +void calc_op2bf16ps (__tile *dst, __bf16 *src1, __bf16 *src2) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + for (j = 0; j < 16; j++) > + { > + dst->a[i * 16 + j] += (float) src1[2 * i] * (float) src2[2 * j]; > + dst->a[i * 16 + j] += (float) src1[2 * i + 1] * (float) src2[2 * j + > 1]; > + } > +} > + > +void test_acev1_op2bf16ps () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512bf16_bf src1, src2; > + int m; > + > + for (m = 0; m < 32; m++) > + { > + int sign; > + sign = m % 2 ? 1 : -1; > + src1.a[m] = (__bf16) (sign * (1.5 * (1 << (m % 3)))); > + sign = m % 5 ? 1 : -1; > + src2.a[m] = (__bf16) (sign * (2.5 * (1 << (m % 3)))); > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + calc_op2bf16ps (&dst_ref, src1.a, src2.a); > + > + init_tile_config (&cfg, &bsr0); > + _tile_ace_zero (1); > + _tile_op2bf16_ps (1, src1.x, src2.x); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4bssd-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4bssd-2.c > new file mode 100644 > index 00000000000..5243ff1c931 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4bssd-2.c > @@ -0,0 +1,47 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4bssd > +void test_acev1_op4bssd (); > +#include "ace-helper.h" > + > +void calc_op4bssd (__tile *dst, char *src1, char *src2) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + for (j = 0; j < 16; j++) > + { > + dst->b[i * 16 + j] += (int) src1[4 * i] * (int) src2[4 * j]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 1] * (int) src2[4 * j + 1]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 2] * (int) src2[4 * j + 2]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 3] * (int) src2[4 * j + 3]; > + } > +} > + > +void test_acev1_op4bssd () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_b src1, src2; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + int sign = m % 2 ? 1 : -1; > + src1.a[m] = 10 + 3 * m + sign; > + src2.a[m] = sign * 10 * m * m; > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + calc_op4bssd (&dst_ref, src1.a, src2.a); > + > + init_tile_config (&cfg, &bsr0); > + _tile_ace_zero (1); > + _tile_op4bssd_epi32 (1, src1.x, src2.x); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4bsud-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4bsud-2.c > new file mode 100644 > index 00000000000..1fed75a61b2 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4bsud-2.c > @@ -0,0 +1,48 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4bsud > +void test_acev1_op4bsud (); > +#include "ace-helper.h" > + > +void calc_op4bsud (__tile *dst, char *src1, unsigned char *src2) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + for (j = 0; j < 16; j++) > + { > + dst->b[i * 16 + j] += (int) src1[4 * i] * (int) src2[4 * j]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 1] * (int) src2[4 * j + 1]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 2] * (int) src2[4 * j + 2]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 3] * (int) src2[4 * j + 3]; > + } > +} > + > +void test_acev1_op4bsud () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_b src1; > + union512i_ub src2; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + int sign = m % 2 ? 1 : -1; > + src1.a[m] = sign * (10 + 3 * m + sign); > + src2.a[m] = 10 * m * m; > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + calc_op4bsud (&dst_ref, src1.a, src2.a); > + > + init_tile_config (&cfg, &bsr0); > + _tile_ace_zero (1); > + _tile_op4bsud_epi32 (1, src1.x, src2.x); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4busd-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4busd-2.c > new file mode 100644 > index 00000000000..236e073f68f > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4busd-2.c > @@ -0,0 +1,48 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4busd > +void test_acev1_op4busd (); > +#include "ace-helper.h" > + > +void calc_op4busd (__tile *dst, unsigned char *src1, char *src2) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + for (j = 0; j < 16; j++) > + { > + dst->b[i * 16 + j] += (int) src1[4 * i] * (int) src2[4 * j]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 1] * (int) src2[4 * j + 1]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 2] * (int) src2[4 * j + 2]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 3] * (int) src2[4 * j + 3]; > + } > +} > + > +void test_acev1_op4busd () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_ub src1; > + union512i_b src2; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + int sign = m % 2 ? 1 : -1; > + src1.a[m] = 10 + 3 * m; > + src2.a[m] = sign * 10 * m * m; > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + calc_op4busd (&dst_ref, src1.a, src2.a); > + > + init_tile_config (&cfg, &bsr0); > + _tile_ace_zero (1); > + _tile_op4busd_epi32 (1, src1.x, src2.x); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4buud-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4buud-2.c > new file mode 100644 > index 00000000000..debf48d7958 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4buud-2.c > @@ -0,0 +1,46 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4buud > +void test_acev1_op4buud (); > +#include "ace-helper.h" > + > +void calc_op4buud (__tile *dst, unsigned char *src1, unsigned char > +*src2) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + for (j = 0; j < 16; j++) > + { > + dst->b[i * 16 + j] += (int) src1[4 * i] * (int) src2[4 * j]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 1] * (int) src2[4 * j + 1]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 2] * (int) src2[4 * j + 2]; > + dst->b[i * 16 + j] += (int) src1[4 * i + 3] * (int) src2[4 * j + 3]; > + } > +} > + > +void test_acev1_op4buud () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_ub src1, src2; > + int m, n; > + > + for (m = 0; m < 64; m++) > + { > + src1.a[m] = 10 + 3 * m; > + src2.a[m] = 10 * m * m; > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + calc_op4buud (&dst_ref, src1.a, src2.a); > + > + init_tile_config (&cfg, &bsr0); > + _tile_ace_zero (1); > + _tile_op4buud_epi32 (1, src1.x, src2.x); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4mxbf8ps-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4mxbf8ps-2.c > new file mode 100644 > index 00000000000..e4cfa57a272 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4mxbf8ps-2.c > @@ -0,0 +1,59 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4mxbf8ps > +void test_acev1_op4mxbf8ps (); > +#include "ace-helper.h" > + > +void calc_op4mxbf8ps (__tile *dst, char *src1, char *src2, __bsr* bsr, > +const int imm) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + { > + for (j = 0; j < 16; j++) > + { > + __int128_t tmp = 0; > + float scale = convert_e8m0_to_fp32 (bsr->buf[4 * i + (imm & 0x3)]) > + * convert_e8m0_to_fp32 (bsr->buf[64 + 4 * j + ((imm & 0x18) >> > 3)]); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j], 1, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 1], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 1], 1, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 2], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 2], 1, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 3], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 3], 1, NULL); > + dst->a[16 * i + j] += shift_int128_to_fp32 (tmp, 1, 1) * scale; > + } > + } > +} > + > +void test_acev1_op4mxbf8ps () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_b src1, src2; > + union512i_ub bsrl, bsrh; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + src1.a[m] = (m % 2) << 7 | (m % 30 + 1) << 2 | ((m + 1) % 4); > + src2.a[m] = ((m % 3) % 2) << 7 | ((m + 10) % 30 + 1) << 2 | ((m + 2) % > 4); > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + init_tile_config (&cfg, &bsr0); > + fill_bsr (&bsr0, &bsrl, &bsrh); > + calc_op4mxbf8ps (&dst_ref, src1.a, src2.a, &bsr0, 10); > + > + _tile_ace_zero (1); > + _bsr0_insertfull (bsrh.x, bsrl.x); > + _tile_op4mxbf8_ps (1, src1.x, src2.x, 10); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4mxbhf8ps-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4mxbhf8ps-2.c > new file mode 100644 > index 00000000000..6ef4f7113e4 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4mxbhf8ps-2.c > @@ -0,0 +1,59 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4mxbhf8ps > +void test_acev1_op4mxbhf8ps (); > +#include "ace-helper.h" > + > +void calc_op4mxbhf8ps (__tile *dst, char *src1, char *src2, __bsr* bsr, > +const int imm) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + { > + for (j = 0; j < 16; j++) > + { > + __int128_t tmp = 0; > + float scale = convert_e8m0_to_fp32 (bsr->buf[4 * i + (imm & 0x3)]) > + * convert_e8m0_to_fp32 (bsr->buf[64 + 4 * j + ((imm & 0x18) >> > 3)]); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j], 0, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 1], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 1], 0, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 2], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 2], 0, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 3], 1, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 3], 0, NULL); > + dst->a[16 * i + j] += shift_int128_to_fp32 (tmp, 1, 0) * scale; > + } > + } > +} > + > +void test_acev1_op4mxbhf8ps () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_b src1, src2; > + union512i_ub bsrl, bsrh; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + src1.a[m] = (m % 2) << 7 | (m % 31) << 2 | ((m + 1) % 4); > + src2.a[m] = ((m % 3) % 2) << 7 | ((m + 7) % 16) << 3 | ((m + 2) % 8); > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + init_tile_config (&cfg, &bsr0); > + fill_bsr (&bsr0, &bsrl, &bsrh); > + calc_op4mxbhf8ps (&dst_ref, src1.a, src2.a, &bsr0, 1); > + > + _tile_ace_zero (1); > + _bsr0_insertfull (bsrh.x, bsrl.x); > + _tile_op4mxbhf8_ps (1, src1.x, src2.x, 1); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4mxbssps-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4mxbssps-2.c > new file mode 100644 > index 00000000000..0fe5a3a7e8a > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4mxbssps-2.c > @@ -0,0 +1,54 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4mxbssps > +void test_acev1_op4mxbssps (); > +#include "ace-helper.h" > + > +void calc_op4mxbssps (__tile *dst, char *src1, char *src2, __bsr* bsr, > +const int imm) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + for (j = 0; j < 16; j++) > + { > + int tmp = 0; > + float scale = convert_e8m0_to_fp32 (bsr->buf[4 * i + (imm & 0x3)]) > + * convert_e8m0_to_fp32 (bsr->buf[64 + 4 * j + ((imm & 0x18) >> 3)]); > + tmp += (int) src1[4 * i] * (int) src2[4 * j]; > + tmp += (int) src1[4 * i + 1] * (int) src2[4 * j + 1]; > + tmp += (int) src1[4 * i + 2] * (int) src2[4 * j + 2]; > + tmp += (int) src1[4 * i + 3] * (int) src2[4 * j + 3]; > + dst->a[16 * i + j] += (float) tmp * scale / 4096.0; > + } > +} > + > +void test_acev1_op4mxbssps () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_b src1, src2; > + union512i_ub bsrl, bsrh; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + int sign = m % 2 ? 1 : -1; > + src1.a[m] = 10 + 3 * m + sign; > + src2.a[m] = sign * 10 * m * m; > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + init_tile_config (&cfg, &bsr0); > + fill_bsr (&bsr0, &bsrl, &bsrh); > + calc_op4mxbssps (&dst_ref, src1.a, src2.a, &bsr0, 10); > + > + _tile_ace_zero (1); > + _bsr0_insertfull (bsrh.x, bsrl.x); > + _tile_op4mxbss_ps (1, src1.x, src2.x, 10); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4mxhbf8ps-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4mxhbf8ps-2.c > new file mode 100644 > index 00000000000..350f108b71c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4mxhbf8ps-2.c > @@ -0,0 +1,59 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4mxhbf8ps > +void test_acev1_op4mxhbf8ps (); > +#include "ace-helper.h" > + > +void calc_op4mxhbf8ps (__tile *dst, char *src1, char *src2, __bsr* bsr, > +const int imm) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + { > + for (j = 0; j < 16; j++) > + { > + __int128_t tmp = 0; > + float scale = convert_e8m0_to_fp32 (bsr->buf[4 * i + (imm & 0x3)]) > + * convert_e8m0_to_fp32 (bsr->buf[64 + 4 * j + ((imm & 0x18) >> > 3)]); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j], 1, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 1], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 1], 1, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 2], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 2], 1, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 3], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 3], 1, NULL); > + dst->a[16 * i + j] += shift_int128_to_fp32 (tmp, 0, 1) * scale; > + } > + } > +} > + > +void test_acev1_op4mxhbf8ps () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_b src1, src2; > + union512i_ub bsrl, bsrh; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + src1.a[m] = (m % 2) << 7 | (m % 16) << 3 | ((m + 1) % 8); > + src2.a[m] = ((m % 3) % 2) << 7 | ((m + 10) % 31) << 2| ((m + 2) % 4); > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + init_tile_config (&cfg, &bsr0); > + fill_bsr (&bsr0, &bsrl, &bsrh); > + calc_op4mxhbf8ps (&dst_ref, src1.a, src2.a, &bsr0, 17); > + > + _tile_ace_zero (1); > + _bsr0_insertfull (bsrh.x, bsrl.x); > + _tile_op4mxhbf8_ps (1, src1.x, src2.x, 17); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/acev1-op4mxhf8ps-2.c > b/gcc/testsuite/gcc.target/i386/acev1-op4mxhf8ps-2.c > new file mode 100644 > index 00000000000..c3329026b11 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/acev1-op4mxhf8ps-2.c > @@ -0,0 +1,59 @@ > +/* { dg-do run { target { ! ia32 } } } */ > +/* { dg-require-effective-target acev1 } */ > +/* { dg-options "-O2 -macev1" } */ > +#define DO_TEST test_acev1_op4mxhf8ps > +void test_acev1_op4mxhf8ps (); > +#include "ace-helper.h" > + > +void calc_op4mxhf8ps (__tile *dst, char *src1, char *src2, __bsr* bsr, > +const int imm) { > + int i, j; > + > + for (i = 0; i < 16; i++) > + { > + for (j = 0; j < 16; j++) > + { > + __int128_t tmp = 0; > + float scale = convert_e8m0_to_fp32 (bsr->buf[4 * i + (imm & 0x3)]) > + * convert_e8m0_to_fp32 (bsr->buf[64 + 4 * j + ((imm & 0x18) >> > 3)]); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j], 0, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 1], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 1], 0, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 2], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 2], 0, NULL); > + tmp += (__int128_t) shift_fp8_to_int64 (src1[4 * i + 3], 0, NULL) > + * (__int128_t) shift_fp8_to_int64 (src2[4 * j + 3], 0, NULL); > + dst->a[16 * i + j] += shift_int128_to_fp32 (tmp, 0, 0) * scale; > + } > + } > +} > + > +void test_acev1_op4mxhf8ps () > +{ > + __tilecfg cfg; > + __tile dst_ref; > + __bsr bsr0; > + union512i_b src1, src2; > + union512i_ub bsrl, bsrh; > + int m; > + > + for (m = 0; m < 64; m++) > + { > + src1.a[m] = (m % 2) << 7 | (m % 16) << 3 | ((m + 1) % 8); > + src2.a[m] = ((m % 3) % 2) << 7 | ((m + 7) % 16) << 3 | ((m + 2) % 8); > + } > + > + for (m = 0; m < 1024; m++) > + dst_ref.buf[m] = 0; > + > + init_tile_config (&cfg, &bsr0); > + fill_bsr (&bsr0, &bsrl, &bsrh); > + calc_op4mxhf8ps (&dst_ref, src1.a, src2.a, &bsr0, 16); > + > + _tile_ace_zero (1); > + _bsr0_insertfull (bsrh.x, bsrl.x); > + _tile_op4mxhf8_ps (1, src1.x, src2.x, 16); > + > + CHECK_TILE_REGISTER (1, dst_ref); > +} > diff --git a/gcc/testsuite/gcc.target/i386/avx-1.c > b/gcc/testsuite/gcc.target/i386/avx-1.c > index 815b635abe9..7231bc40405 100644 > --- a/gcc/testsuite/gcc.target/i386/avx-1.c > +++ b/gcc/testsuite/gcc.target/i386/avx-1.c > @@ -929,6 +929,16 @@ > #define __builtin_ia32_tilemovrowextract(A, B) > __builtin_ia32_tilemovrowextract > (1, B) #define __builtin_ia32_tilemovrowinsert(A, B, C) > __builtin_ia32_tilemovrowinsert (1, B, C) #define > __builtin_ia32_tilemovcolinsert(A, B, C) __builtin_ia32_tilemovcolinsert (1, > B, C) > +#define __builtin_ia32_top2bf16ps(W, A, B) __builtin_ia32_top2bf16ps > +(1, A, B) #define __builtin_ia32_top4bssd(W, A, B) > +__builtin_ia32_top4bssd (1, A, B) #define __builtin_ia32_top4bsud(W, A, > +B) __builtin_ia32_top4bsud (1, A, B) #define __builtin_ia32_top4busd(W, > +A, B) __builtin_ia32_top4busd (1, A, B) #define > +__builtin_ia32_top4buud(W, A, B) __builtin_ia32_top4buud (1, A, B) > +#define __builtin_ia32_top4mxbf8ps(W, A, B, C) > +__builtin_ia32_top4mxbf8ps (1, A, B, 9) #define > +__builtin_ia32_top4mxbhf8ps(W, A, B, C) __builtin_ia32_top4mxbhf8ps (1, > +A, B, 9) #define __builtin_ia32_top4mxhbf8ps(W, A, B, C) > +__builtin_ia32_top4mxhbf8ps (1, A, B, 9) #define > +__builtin_ia32_top4mxhf8ps(W, A, B, C) __builtin_ia32_top4mxhf8ps (1, > +A, B, 9) #define __builtin_ia32_top4mxbssps(W, A, B, C) > +__builtin_ia32_top4mxbssps (1, A, B, 9) > #endif > > #include <wmmintrin.h> > diff --git a/gcc/testsuite/gcc.target/i386/fp8-helper.h > b/gcc/testsuite/gcc.target/i386/fp8-helper.h > index d3f526f651c..f113ec76f4a 100644 > --- a/gcc/testsuite/gcc.target/i386/fp8-helper.h > +++ b/gcc/testsuite/gcc.target/i386/fp8-helper.h > @@ -210,14 +210,19 @@ bf8_isInf(unsigned char value) static int64_t > shift_fp8_to_int64 (unsigned char x, int bf8, int *valueState) { > - *valueState = (x >> 7) ? -1 : 1; > - if (fp8_isNan (x, bf8)) > - *valueState = -2; > - if (bf8) > - if (bf8_isInf(x) == 1) > - *valueState = 3; > - else if (bf8_isInf(x) == -1) > - *valueState = -3; > + if (valueState != NULL) > + { > + *valueState = (x >> 7) ? -1 : 1; > + if (fp8_isNan (x, bf8)) > + *valueState = -2; > + if (bf8) > + { > + if (bf8_isInf(x) == 1) > + *valueState = 3; > + else if (bf8_isInf(x) == -1) > + *valueState = -3; > + } > + } > > unsigned short sign = (x & 0x80) >> 7; > unsigned short exp = bf8 ? (x & 0x7c) >> 2 : (x & 0x78) >> 3; diff --git > a/gcc/testsuite/gcc.target/i386/sse-13.c > b/gcc/testsuite/gcc.target/i386/sse-13.c > index 628a7e218af..2b9b7ecd5c9 100644 > --- a/gcc/testsuite/gcc.target/i386/sse-13.c > +++ b/gcc/testsuite/gcc.target/i386/sse-13.c > @@ -936,6 +936,16 @@ > #define __builtin_ia32_tilemovrowextract(A, B) > __builtin_ia32_tilemovrowextract > (1, B) #define __builtin_ia32_tilemovrowinsert(A, B, C) > __builtin_ia32_tilemovrowinsert (1, B, C) #define > __builtin_ia32_tilemovcolinsert(A, B, C) __builtin_ia32_tilemovcolinsert (1, > B, C) > +#define __builtin_ia32_top2bf16ps(W, A, B) __builtin_ia32_top2bf16ps > +(1, A, B) #define __builtin_ia32_top4bssd(W, A, B) > +__builtin_ia32_top4bssd (1, A, B) #define __builtin_ia32_top4bsud(W, A, > +B) __builtin_ia32_top4bsud (1, A, B) #define __builtin_ia32_top4busd(W, > +A, B) __builtin_ia32_top4busd (1, A, B) #define > +__builtin_ia32_top4buud(W, A, B) __builtin_ia32_top4buud (1, A, B) > +#define __builtin_ia32_top4mxbf8ps(W, A, B, C) > +__builtin_ia32_top4mxbf8ps (1, A, B, 9) #define > +__builtin_ia32_top4mxbhf8ps(W, A, B, C) __builtin_ia32_top4mxbhf8ps (1, > +A, B, 9) #define __builtin_ia32_top4mxhbf8ps(W, A, B, C) > +__builtin_ia32_top4mxhbf8ps (1, A, B, 9) #define > +__builtin_ia32_top4mxhf8ps(W, A, B, C) __builtin_ia32_top4mxhf8ps (1, > +A, B, 9) #define __builtin_ia32_top4mxbssps(W, A, B, C) > +__builtin_ia32_top4mxbssps (1, A, B, 9) > #endif > > #include <x86intrin.h> > diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c > b/gcc/testsuite/gcc.target/i386/sse-14.c > index 77d29e05772..fe886f4fa5d 100644 > --- a/gcc/testsuite/gcc.target/i386/sse-14.c > +++ b/gcc/testsuite/gcc.target/i386/sse-14.c > @@ -65,6 +65,10 @@ > void _CONCAT(_,func) (op1_type A, op2_type B, int const I, int const L) \ > { func (A, B, imm1, imm2); } > > +#define test_2vxt(func, imm1, op1_type, op2_type, imm2) > \ > + void _CONCAT(_,func) (int const I, op1_type A, op2_type B, int const > +L) \ > + { func (imm1, A, B, imm2); } > + > #define test_3(func, type, op1_type, op2_type, op3_type, imm) \ > type _CONCAT(_,func) (op1_type A, op2_type B, > \ > op3_type C, int const I) \ > @@ -1223,4 +1227,14 @@ test_1t (_tile_cvtrowl_ps_ph, __m512h, 1, int) > test_1t (_tile_extractrow, __m512i, 1, int) test_2vt (_tile_insertrow, 1, > __m512i, > int) test_2vt (_tile_insertcol, 1, __m512i, int) > +test_2vt (_tile_op2bf16_ps, 1, __m512bh, __m512bh) test_2vt > +(_tile_op4bssd_epi32, 1, __m512i, __m512i) test_2vt > +(_tile_op4bsud_epi32, 1, __m512i, __m512i) test_2vt > +(_tile_op4busd_epi32, 1, __m512i, __m512i) test_2vt > +(_tile_op4buud_epi32, 1, __m512i, __m512i) test_2vxt > +(_tile_op4mxbf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxbhf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxhbf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxhf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxbss_ps, 1, __m512i, __m512i, 9) > #endif > diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c > b/gcc/testsuite/gcc.target/i386/sse-22.c > index 493772106cc..c1ea4ba96f4 100644 > --- a/gcc/testsuite/gcc.target/i386/sse-22.c > +++ b/gcc/testsuite/gcc.target/i386/sse-22.c > @@ -58,6 +58,10 @@ > type _CONCAT(_,func) (op1_type A, op2_type B, int const I, int const L) \ > { return func (A, B, imm1, imm2); } > > +#define test_2vxt(func, imm1, op1_type, op2_type, imm2) > \ > + void _CONCAT(_,func) (int const I, op1_type A, op2_type B, int const > +L) \ > + { func (imm1, A, B, imm2); } > + > #define test_2y(func, type, op1_type, op2_type, imm1, imm2, imm3) \ > type _CONCAT(_,func) (op1_type A, op2_type B, int const I, int const L,\ > int const R) \ > @@ -1264,4 +1268,14 @@ test_1t (_tile_cvtrowl_ps_ph, __m512h, 1, int) > test_1t (_tile_extractrow, __m512i, 1, int) test_2vt (_tile_insertrow, 1, > __m512i, > int) test_2vt (_tile_insertcol, 1, __m512i, int) > +test_2vt (_tile_op2bf16_ps, 1, __m512bh, __m512bh) test_2vt > +(_tile_op4bssd_epi32, 1, __m512i, __m512i) test_2vt > +(_tile_op4bsud_epi32, 1, __m512i, __m512i) test_2vt > +(_tile_op4busd_epi32, 1, __m512i, __m512i) test_2vt > +(_tile_op4buud_epi32, 1, __m512i, __m512i) test_2vxt > +(_tile_op4mxbf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxbhf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxhbf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxhf8_ps, 1, __m512i, __m512i, 9) test_2vxt > +(_tile_op4mxbss_ps, 1, __m512i, __m512i, 9) > #endif > diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c > b/gcc/testsuite/gcc.target/i386/sse-23.c > index 719803bec4b..f6e3fb10613 100644 > --- a/gcc/testsuite/gcc.target/i386/sse-23.c > +++ b/gcc/testsuite/gcc.target/i386/sse-23.c > @@ -911,6 +911,16 @@ > #define __builtin_ia32_tilemovrowextract(A, B) > __builtin_ia32_tilemovrowextract > (1, B) #define __builtin_ia32_tilemovrowinsert(A, B, C) > __builtin_ia32_tilemovrowinsert (1, B, C) #define > __builtin_ia32_tilemovcolinsert(A, B, C) __builtin_ia32_tilemovcolinsert (1, > B, C) > +#define __builtin_ia32_top2bf16ps(W, A, B) __builtin_ia32_top2bf16ps > +(1, A, B) #define __builtin_ia32_top4bssd(W, A, B) > +__builtin_ia32_top4bssd (1, A, B) #define __builtin_ia32_top4bsud(W, A, > +B) __builtin_ia32_top4bsud (1, A, B) #define __builtin_ia32_top4busd(W, > +A, B) __builtin_ia32_top4busd (1, A, B) #define > +__builtin_ia32_top4buud(W, A, B) __builtin_ia32_top4buud (1, A, B) > +#define __builtin_ia32_top4mxbf8ps(W, A, B, C) > +__builtin_ia32_top4mxbf8ps (1, A, B, 9) #define > +__builtin_ia32_top4mxbhf8ps(W, A, B, C) __builtin_ia32_top4mxbhf8ps (1, > +A, B, 9) #define __builtin_ia32_top4mxhbf8ps(W, A, B, C) > +__builtin_ia32_top4mxhbf8ps (1, A, B, 9) #define > +__builtin_ia32_top4mxhf8ps(W, A, B, C) __builtin_ia32_top4mxhf8ps (1, > +A, B, 9) #define __builtin_ia32_top4mxbssps(W, A, B, C) > +__builtin_ia32_top4mxbssps (1, A, B, 9) > #endif > > #pragma GCC target > ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lw > p,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,sha,xsavec,xsaves > ,clflushopt,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,vpclmulqdq,pconfig,wbnoinvd, > enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx- > bf16,kl,widekl,avxvnni,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx- > fp16,prefetchi,raoint,amx-complex,avxvnniint16,sm3,sha512,sm4,avx10.2,amx- > avx512,amx-fp8,movrs,amx-movrs,avx10v2aux,acev1") > -- > 2.31.1 Otherwise, the patch looks good, Regards, Venkat.
