AMD General

Hi Haochen,

> -----Original Message-----
> From: Haochen Jiang <[email protected]>
> Sent: Wednesday, August 19, 2026 11:19 AM
> To: [email protected]
> Cc: [email protected]; [email protected]; Kumar, Venkataramanan
> <[email protected]>; Sharma, Dipesh
> <[email protected]>; Sharma, Dipesh <[email protected]>
> Subject: [PATCH v2 6/7] Support ACEv1 instructions reused from AMX-
> AVX512 and tilemovcol
>
> Caution: This message originated from an External Source. Use proper
> caution when opening attachments, clicking links, or responding.
>
>
> The other part ACE reused from legacy AMX is from AMX-AVX512. Similar as
> AMX-TILE, we need to use a different intrin name to distinguish intrins
> between ACE and legacy AMX.
>
> However, for legacy AMX-AVX512 convert related intrins, it does not obey
> the intrin naming conventions for convert insts. Thus, it leaves the correct
> naming space for ACE to use. We will directly use that naming space for
> ACE.
>
> We also added new tilemovcol implementation in this patch since it is quite
> similar with tilemovrow. The insert/extract usage is the same as BSR
> scenario.
>
> For runtime tests, since the functionality is the same, we only added
> tilemovcol runtime test.

What about adding runtime tests for cvtrow* patterns?
They should get tested under targets having ACEV1 and no AMX-AVX512.

>
> gcc/ChangeLog:
>
>         * config/i386/acev1intrin.h: Add new intrins.
>         * config/i386/i386-builtin-types.def: Add new builtin types.
>         * config/i386/i386-builtin.def (BDESC): Handle new builtins.
>         * config/i386/i386-expand.cc
>         (ix86_expand_ace_builtin): Handle new builtin type.
>         * config/i386/sse.md (UNSPEC_TCVTROWD2PS) New.
>         (UNSPEC_TCVTROWPS2FP16H): Ditto.
>         (UNSPEC_TCVTROWPS2FP16L): Ditto.
>         (UNSPEC_TILEMOVROWEXTRACT): Ditto.
>         (UNSPECV_TILEMOVROWINSERT): Ditto.
>         (UNSPECV_TILEMOVCOLINSERT): Ditto.
>         (VHFBF_512): Ditto.
>         (tcvtrowd2ps): Ditto.
>         (tcvtrowps2<bf16_ph><highlowsuffix>): Ditto.
>         (tilemovrow_extract): Ditto.:
Remove :
>         (tilemov<rowcol>_insert): Ditto.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/i386/ace-check.h: Add new helper function.
>         * gcc.target/i386/acev1-1.c: Add new compile test.
>         * 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-movcol-2.c: New test.
>
> Co-authored-by: Dipesh Sharma <[email protected]>
> ---
>  gcc/config/i386/acev1intrin.h                 | 80 +++++++++++++++++++
>  gcc/config/i386/i386-builtin-types.def        |  5 ++
>  gcc/config/i386/i386-builtin.def              |  9 +++
>  gcc/config/i386/i386-expand.cc                | 64 ++++++++++++---
>  gcc/config/i386/sse.md                        | 64 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/ace-check.h     | 12 +++
>  gcc/testsuite/gcc.target/i386/acev1-1.c       | 22 +++++
>  .../gcc.target/i386/acev1-movcol-2.c          | 45 +++++++++++
>  gcc/testsuite/gcc.target/i386/avx-1.c         |  8 ++
>  gcc/testsuite/gcc.target/i386/sse-13.c        |  8 ++
>  gcc/testsuite/gcc.target/i386/sse-14.c        | 16 ++++
>  gcc/testsuite/gcc.target/i386/sse-22.c        | 16 ++++
>  gcc/testsuite/gcc.target/i386/sse-23.c        |  8 ++
>  13 files changed, 345 insertions(+), 12 deletions(-)  create mode 100644
> gcc/testsuite/gcc.target/i386/acev1-movcol-2.c
>
> diff --git a/gcc/config/i386/acev1intrin.h b/gcc/config/i386/acev1intrin.h
> index 316d2c11f74..7b205304302 100644
> --- a/gcc/config/i386/acev1intrin.h
> +++ b/gcc/config/i386/acev1intrin.h
> @@ -99,10 +99,90 @@ _tile_ace_zero (const int __A)
>    __builtin_ia32_tilezero (__A);
>  }
>
> +extern __inline __m512
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_cvtrow_epi32_ps (const int __A, int __B) {
> +  return (__m512) __builtin_ia32_tcvtrowd2ps (__A, __B); }
> +
> +extern __inline __m512bh
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_cvtrowh_ps_pbh (const int __A, int __B) {
> +  return (__m512bh) __builtin_ia32_tcvtrowps2bf16h (__A, __B); }
> +
> +extern __inline __m512bh
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_cvtrowl_ps_pbh (const int __A, int __B) {
> +  return (__m512bh) __builtin_ia32_tcvtrowps2bf16l (__A, __B); }
> +
> +extern __inline __m512h
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_cvtrowh_ps_ph (const int __A, int __B) {
> +  return (__m512h) __builtin_ia32_tcvtrowps2phh (__A, __B); }
> +
> +extern __inline __m512h
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_cvtrowl_ps_ph (const int __A, int __B) {
> +  return (__m512h) __builtin_ia32_tcvtrowps2phl (__A, __B); }
> +
> +extern __inline __m512i
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_extractrow (const int __A, int __B) {
> +  return (__m512i) __builtin_ia32_tilemovrowextract (__A, __B); }
> +
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_insertrow (const int __A, __m512i __B, int __C) {
> +  __builtin_ia32_tilemovrowinsert (__A, (__v16si) __B, __C); }
> +
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +_tile_insertcol (const int __A, __m512i __B, int __C) {
> +  __builtin_ia32_tilemovcolinsert (__A, (__v16si) __B, __C); }
> +
>  #else
>  #define _tile_ace_zero(A)                      \
>    __builtin_ia32_tilezero (A);
>
> +#define _tile_cvtrow_epi32_ps(A, B)            \
> +  (__m512) __builtin_ia32_tcvtrowd2ps ((A), (B))
> +
> +#define _tile_cvtrowh_ps_pbh(A, B)             \
> +  (__m512bh) __builtin_ia32_tcvtrowps2bf16h ((A), (B))
> +
> +#define _tile_cvtrowl_ps_pbh(A, B)             \
> +  (__m512bh) __builtin_ia32_tcvtrowps2bf16l ((A), (B))
> +
> +#define _tile_cvtrowh_ps_ph(A, B)              \
> +  (__m512h) __builtin_ia32_tcvtrowps2phh ((A), (B))
> +
> +#define _tile_cvtrowl_ps_ph(A, B)              \
> +  (__m512h) __builtin_ia32_tcvtrowps2phl ((A), (B))
> +
> +#define _tile_extractrow(A, B)                 \
> +  (__m512i) __builtin_ia32_tilemovrowextract ((A), (B))
> +
> +#define _tile_insertrow(A, B, C)               \
> +  __builtin_ia32_tilemovrowinsert ((A), (__v16si) (B), (C))
> +
> +#define _tile_insertcol(A, B, C)               \
> +  __builtin_ia32_tilemovcolinsert ((A), (__v16si) (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 baf03960954..9b969d0d4a9 100644
> --- a/gcc/config/i386/i386-builtin-types.def
> +++ b/gcc/config/i386/i386-builtin-types.def
> @@ -1505,3 +1505,8 @@ DEF_FUNCTION_TYPE (VOID, UQI)
> DEF_FUNCTION_TYPE (VOID, V16SI)  DEF_FUNCTION_TYPE (V16SI)
> DEF_FUNCTION_TYPE (VOID, V16SI, V16SI)
> +DEF_FUNCTION_TYPE (V16SF, UQI, SI)
> +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)
> diff --git a/gcc/config/i386/i386-builtin.def 
> b/gcc/config/i386/i386-builtin.def
> index 62e175d01ef..50b60e60c9c 100644
> --- a/gcc/config/i386/i386-builtin.def
> +++ b/gcc/config/i386/i386-builtin.def
> @@ -3978,4 +3978,13 @@ BDESC_END (CET, ACE)
>  /* ACEv1.  */
>  BDESC_FIRST (ace, ACE,
>         OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
> CODE_FOR_tilezero, "__builtin_ia32_tilezero", IX86_BUILTIN_TILEZERO,
> UNKNOWN, (int) VOID_FTYPE_UQI)
> +BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
> +CODE_FOR_tcvtrowd2ps, "__builtin_ia32_tcvtrowd2ps",
> +IX86_BUILTIN_TCVTROWD2PS, UNKNOWN, (int) V16SF_FTYPE_UQI_SI)
> BDESC
> +(OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
> +CODE_FOR_tcvtrowps2bf16h, "__builtin_ia32_tcvtrowps2bf16h",
> +IX86_BUILTIN_TCVTROWPS2BF16H, UNKNOWN, (int) V32BF_FTYPE_UQI_SI)
> BDESC
> +(OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
> +CODE_FOR_tcvtrowps2bf16l, "__builtin_ia32_tcvtrowps2bf16l",
> +IX86_BUILTIN_TCVTROWPS2BF16L, UNKNOWN, (int) V32BF_FTYPE_UQI_SI)
> BDESC
> +(OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
> CODE_FOR_tcvtrowps2phh,
> +"__builtin_ia32_tcvtrowps2phh", IX86_BUILTIN_TCVTROWPS2PHH,
> UNKNOWN,
> +(int) V32HF_FTYPE_UQI_SI) BDESC (OPTION_MASK_ISA_64BIT,
> +OPTION_MASK_ISA2_ACEV1, CODE_FOR_tcvtrowps2phl,
> +"__builtin_ia32_tcvtrowps2phl", IX86_BUILTIN_TCVTROWPS2PHL,
> UNKNOWN,
> +(int) V32HF_FTYPE_UQI_SI) 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_END (ACE, MAX)
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index b6e5180564a..e9bc4a7d8e6 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -14711,11 +14711,13 @@ ix86_expand_special_args_builtin (const
> struct builtin_description *d,
>     with variable number of operands.  */
>
>  static rtx
> -ix86_expand_ace_builtin (const struct builtin_description *d, tree exp)
> +ix86_expand_ace_builtin (const struct builtin_description *d, tree exp,
> +                        rtx target)
>  {
>    tree arg;
>    rtx pat, op;
> -  unsigned int i, nargs;
> +  unsigned int i, nargs, arg_adjust = 0;  bool tmm_src = false;
>    rtx xops[4];
>    enum insn_code icode = d->icode;
>    const struct insn_data_d *insn_p = &insn_data[icode]; @@ -14725,6
> +14727,16 @@ ix86_expand_ace_builtin (const struct builtin_description
> *d, tree exp)
>      case VOID_FTYPE_UQI:
>        nargs = 1;
>        break;
> +    case V16SF_FTYPE_UQI_SI:
> +    case V32BF_FTYPE_UQI_SI:
> +    case V32HF_FTYPE_UQI_SI:
> +    case V16SI_FTYPE_UQI_SI:
> +      nargs = 2;
> +      tmm_src = true;
> +      break;
> +    case VOID_FTYPE_UQI_V16SI_SI:
> +      nargs = 3;
> +      break;
>
>      default:
>        gcc_unreachable ();
> @@ -14732,9 +14744,20 @@ ix86_expand_ace_builtin (const struct
> builtin_description *d, tree exp)
>
>    gcc_assert (nargs <= ARRAY_SIZE (xops));
>
> +  if (tmm_src)
> +    {
> +      machine_mode tmode = insn_p->operand[0].mode;
> +      arg_adjust = 1;
> +      if (optimize
> +         || target == 0
> +         || !register_operand (target, tmode)
> +         || GET_MODE (target) != tmode)
> +       target = gen_reg_rtx (tmode);
> +    }

Why are we creating register always when optimize is set ??

> +
>    for (i = 0; i < nargs; i++)
>      {
> -      machine_mode mode = insn_p->operand[i].mode;
> +      machine_mode mode = insn_p->operand[i + arg_adjust].mode;
>
>        arg = CALL_EXPR_ARG (exp, i);
>        op = ix86_expand_unsigned_small_int_cst_argument (arg); @@ -
> 14742,7 +14765,7 @@ ix86_expand_ace_builtin (const struct
> builtin_description *d, tree exp)
>        if (i == 0)
>         {
>           /* This must be the tmm reg number constant.  */
> -         if (!insn_p->operand[i].predicate(op, SImode))
> +         if (!insn_p->operand[i + arg_adjust].predicate(op, SImode))
>             {
>               error ("the argument must be constant");
>               return const0_rtx;
> @@ -14775,20 +14798,37 @@ ix86_expand_ace_builtin (const struct
> builtin_description *d, tree exp)
>        xops[i] = op;
>      }
>
> -  switch (nargs)
> +  if (tmm_src)
>      {
> -    case 1:
> -      pat = GEN_FCN (icode) (xops[0]);
> -      break;
> -    default:
> -      gcc_unreachable ();
> +      switch (nargs)
> +       {
> +       case 2:
> +         pat = GEN_FCN (icode) (target, xops[0], xops[1]);
> +         break;
> +       default:
> +         gcc_unreachable ();
> +       }
> +  }
> +  else
> +    {
> +      switch (nargs)
> +       {
> +       case 1:
> +         pat = GEN_FCN (icode) (xops[0]);
> +         break;
> +       case 3:
> +         pat = GEN_FCN (icode) (xops[0], xops[1], xops[2]);
> +         break;
> +       default:
> +         gcc_unreachable ();
> +       }
>      }
>
>    if (!pat)
>      return 0;
>
>    emit_insn (pat);
> -  return 0;
> +  return tmm_src ? target : 0;
>  }
>
>  /* Return the integer constant in ARG.  Constrain it to be in the range @@
> -17423,7 +17463,7 @@ rdseed_step:
>        && fcode <= IX86_BUILTIN__BDESC_ACE_LAST)
>      {
>        i = fcode - IX86_BUILTIN__BDESC_ACE_FIRST;
> -      return ix86_expand_ace_builtin (bdesc_ace + i, exp);
> +      return ix86_expand_ace_builtin (bdesc_ace + i, exp, target);
>      }
>
>    gcc_unreachable ();
> diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index
> e0e19a2d128..6f3bf44b557 100644
> --- a/gcc/config/i386/sse.md
> +++ b/gcc/config/i386/sse.md
> @@ -285,6 +285,10 @@
>    ;; For ACEv1 support
>    UNSPEC_BSRMOVH_STORE
>    UNSPEC_BSRMOVL_STORE
> +  UNSPEC_TCVTROWD2PS
> +  UNSPEC_TCVTROWPS2FP16H
> +  UNSPEC_TCVTROWPS2FP16L
> +  UNSPEC_TILEMOVROWEXTRACT
>  ])
>
>  (define_c_enum "unspecv" [
> @@ -314,6 +318,8 @@
>    UNSPECV_BSRMOVF
>    UNSPECV_BSRMOVH_LOAD
>    UNSPECV_BSRMOVL_LOAD
> +  UNSPECV_TILEMOVROWINSERT
> +  UNSPECV_TILEMOVCOLINSERT
>  ])
>
>  ;; All vector modes including V?TImode, used in move patterns.
> @@ -572,6 +578,7 @@
>
>  (define_mode_iterator VHFBF
>    [V32HF V16HF V8HF V32BF V16BF V8BF])
> +(define_mode_iterator VHFBF_512 [V32HF V32BF])
>  (define_mode_iterator VHFBF_256 [V16HF V16BF])  (define_mode_iterator
> VHFBF_128 [V8HF V8BF])
>
> @@ -34994,3 +35001,60 @@
>    "TARGET_ACEV1"
>    "bsrmovl\t{%1, %0|%0, %1}"
>    [(set_attr "prefix" "evex")])
> +
> +(define_insn "tcvtrowd2ps"
> +  [(set (match_operand:V16SF 0 "register_operand" "=v")
> +        (unspec:V16SF
> +         [(reg:V32SI TMM_REGNUM)
> +          (match_operand:QI 1 "const_0_to_7_operand")
> +          (match_operand:SI 2 "nonmemory_operand" "rN")]

Is it left for the user to make sure he is not providing incorrect row index??

> +         UNSPEC_TCVTROWD2PS))]
> +  "TARGET_ACEV1"
> +  "tcvtrowd2ps\t{%2, %%tmm%c1, %0|%0, tmm%c1, %2}"
> +  [(set_attr "prefix" "evex")])
> +
> +(define_int_iterator UNSPEC_TCVTROWPS2FP16TYPE
> +  [UNSPEC_TCVTROWPS2FP16H UNSPEC_TCVTROWPS2FP16L])
> +
> +(define_int_attr highlowsuffix
> +  [(UNSPEC_TCVTROWPS2FP16H "h") (UNSPEC_TCVTROWPS2FP16L "l")])
> +
> +(define_insn "tcvtrowps2<bf16_ph><highlowsuffix>"
> +  [(set (match_operand:VHFBF_512 0 "register_operand" "=v")
> +        (unspec:VHFBF_512
> +         [(reg:V32SF TMM_REGNUM)

Mode of TMM register is V32SF in one place and V32SI in another place.

> +          (match_operand:QI 1 "const_0_to_7_operand")
> +          (match_operand:SI 2 "nonmemory_operand" "rN")]
> +         UNSPEC_TCVTROWPS2FP16TYPE))]
> +  "TARGET_ACEV1"
> +  "tcvtrowps2<bf16_ph><highlowsuffix>\t{%2, %%tmm%c1, %0|%0,
> tmm%c1, %2}"
> +  [(set_attr "prefix" "evex")])
> +
> +(define_int_iterator UNSPECV_TILEMOVINSERT
> +  [UNSPECV_TILEMOVROWINSERT UNSPECV_TILEMOVCOLINSERT])
> +
> +(define_int_attr rowcol
> +  [(UNSPECV_TILEMOVROWINSERT "row")
> +   (UNSPECV_TILEMOVCOLINSERT "col")])
> +
> +(define_insn "tilemovrow_extract"
> +  [(set (match_operand:V16SI 0 "register_operand" "=v")
> +        (unspec:V16SI
> +         [(reg:V32SI TMM_REGNUM)
> +          (match_operand:QI 1 "const_0_to_7_operand")
> +          (match_operand:SI 2 "nonmemory_operand" "rN")]
> +         UNSPEC_TILEMOVROWEXTRACT))]
> +  "TARGET_ACEV1"
> +  "tilemovrow\t{%2, %%tmm%c1, %0|%0, tmm%c1, %2}"
> +  [(set_attr "prefix" "evex")])
> +
> +(define_insn "tilemov<rowcol>_insert"
> +  [(set (reg:V32SI TMM_REGNUM)
> +        (unspec_volatile:V32SI
> +         [(match_operand:QI 0 "const_0_to_7_operand")
> +          (match_operand:V16SI 1 "register_operand" "v")
> +          (match_operand:SI 2 "nonmemory_operand" "rN")]
> +         UNSPECV_TILEMOVINSERT))]
> +  "TARGET_ACEV1"
> +  "tilemov<rowcol>\t{%2, %1, %%tmm%c0|tmm%c0, %1, %2}"
> +  [(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 e9ea67ce3dd..210f20e7a47 100644
> --- a/gcc/testsuite/gcc.target/i386/ace-check.h
> +++ b/gcc/testsuite/gcc.target/i386/ace-check.h
> @@ -51,6 +51,18 @@ void fill_bsr (__bsr *bsr, union512i_ub* src1,
> union512i_ub* src2)
>      }
>  }
>
> +void init_tile_config (__tilecfg *dst, __bsr* bsr) {
> +  int i;
> +  dst->palette_id = 2;
> +  for (i = 0; i < 63; i++)
> +    dst->reserved[i] = 0;
> +  for (i = 0; i < 128; i++)
> +    bsr->buf[i] = 0xff;
> +  _tile_ace_loadconfig (dst);
> +  _bsr0_init ();
> +}
> +
>  #ifndef DO_TEST
>  #define DO_TEST do_test
>  static void test_ace (void);
> diff --git a/gcc/testsuite/gcc.target/i386/acev1-1.c
> b/gcc/testsuite/gcc.target/i386/acev1-1.c
> index daff9278363..6d01745c592 100644
> --- a/gcc/testsuite/gcc.target/i386/acev1-1.c
> +++ b/gcc/testsuite/gcc.target/i386/acev1-1.c
> @@ -8,10 +8,20 @@
>  /* { dg-final { scan-assembler-times "bsrmovf\[ \t]" 1 } } */
>  /* { dg-final { scan-assembler-times "bsrmovl\[ \t]" 2 } } */
>  /* { dg-final { scan-assembler-times "bsrmovh\[ \t]" 2 } } */
> +/* { dg-final { scan-assembler-times "tcvtrowd2ps\[ \t]" 1 } } */
> +/* { dg-final { scan-assembler-times "tcvtrowps2bf16h\[ \t]" 1 } } */
> +/* { dg-final { scan-assembler-times "tcvtrowps2bf16l\[ \t]" 1 } } */
> +/* { dg-final { scan-assembler-times "tcvtrowps2phh\[ \t]" 1 } } */
> +/* { dg-final { scan-assembler-times "tcvtrowps2phl\[ \t]" 1 } } */
> +/* { dg-final { scan-assembler-times "tilemovrow\[ \t]" 2 } } */
> +/* { dg-final { scan-assembler-times "tilemovcol\[ \t]" 1 } } */
>  #include <immintrin.h>
>
>  extern int t[];
>  __m512i a1,a2;
> +__m512bh b1,b2;
> +__m512h c1,c2;
> +__m512 d;
>
>  void amxtile ()
>  {
> @@ -30,3 +40,15 @@ void bsr ()
>    _bsr0_insertl (a2);
>    a2 = _bsr0_extractl ();
>  }
> +
> +void cvtrow ()
> +{
> +  d = _tile_cvtrow_epi32_ps (1, 1);
> +  b1 = _tile_cvtrowh_ps_pbh (2, 3);
> +  b2 = _tile_cvtrowl_ps_pbh (3, 5);
> +  c1 = _tile_cvtrowh_ps_ph (4, 7);
> +  c2 = _tile_cvtrowl_ps_ph (5, 9);
> +  a1 = _tile_extractrow (6, 2);
> +  _tile_insertrow (7, a1, 10);
> +  _tile_insertcol (2, a2, 11);
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/acev1-movcol-2.c
> b/gcc/testsuite/gcc.target/i386/acev1-movcol-2.c
> new file mode 100644
> index 00000000000..e6dfd60eb2b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/acev1-movcol-2.c
> @@ -0,0 +1,45 @@
> +/* { dg-do run { target { ! ia32 } } } */
> +/* { dg-require-effective-target acev1 } */
> +/* { dg-options "-O2 -macev1" } */
> +#define DO_TEST test_acev1_movcol
> +void test_acev1_movcol ();
> +#include "ace-helper.h"
> +
> +void calc_movrow (__tile *src, int *dst, int row) {
> +  int i, index;
> +
> +  index = row % 16;
> +  for (i = 0; i < 16; i++)
> +    dst[i] = src->b[16 * index + i];
> +}
> +
> +void test_acev1_movcol ()
> +{
> +  __tilecfg cfg;
> +  __tile src;
> +  __bsr bsr0;
> +  union512i_d res;
> +  int res_ref[16];
> +  int i, j;
> +
> +  init_tile_config (&cfg, &bsr0);
> +  for (i = 0; i < 16; i++)
> +  {
> +    union512i_ud tmp;
> +    for (j = 0; j < 16; j++)
> +      {
> +       tmp.a[j] = i * 16 + j;
> +       src.b[i + j * 16] = i * 16 + j;
> +      }
> +    _tile_insertcol (1, tmp.x, i);
> +  }
> +
> +  for (i = 0; i < 16; i++)
> +    {
> +      calc_movrow (&src, res_ref, i);
> +      res.x = _tile_extractrow (1, i);
> +      if (UNION_CHECK (512, i_d) (res, res_ref))
> +       abort ();
> +    }
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/avx-1.c
> b/gcc/testsuite/gcc.target/i386/avx-1.c
> index 3f4bbb34a40..623446deec8 100644
> --- a/gcc/testsuite/gcc.target/i386/avx-1.c
> +++ b/gcc/testsuite/gcc.target/i386/avx-1.c
> @@ -921,6 +921,14 @@
>  /* acev1intrin.h */
>  #ifdef __x86_64__
>  #define __builtin_ia32_tilezero(A) __builtin_ia32_tilezero (1)
> +#define __builtin_ia32_tcvtrowd2ps(A, B) __builtin_ia32_tcvtrowd2ps (1,
> +B) #define __builtin_ia32_tcvtrowps2bf16h(A, B)
> +__builtin_ia32_tcvtrowps2bf16h (1, B) #define
> +__builtin_ia32_tcvtrowps2bf16l(A, B) __builtin_ia32_tcvtrowps2bf16l (1,
> +B) #define __builtin_ia32_tcvtrowps2phh(A, B)
> +__builtin_ia32_tcvtrowps2phh (1, B) #define
> +__builtin_ia32_tcvtrowps2phl(A, B) __builtin_ia32_tcvtrowps2phl (1, B)
> +#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)
>  #endif
>
>  #include <wmmintrin.h>
> diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c
> b/gcc/testsuite/gcc.target/i386/sse-13.c
> index d55d4635876..67ee7f0088d 100644
> --- a/gcc/testsuite/gcc.target/i386/sse-13.c
> +++ b/gcc/testsuite/gcc.target/i386/sse-13.c
> @@ -928,6 +928,14 @@
>  /* acev1intrin.h */
>  #ifdef __x86_64__
>  #define __builtin_ia32_tilezero(A) __builtin_ia32_tilezero (1)
> +#define __builtin_ia32_tcvtrowd2ps(A, B) __builtin_ia32_tcvtrowd2ps (1,
> +B) #define __builtin_ia32_tcvtrowps2bf16h(A, B)
> +__builtin_ia32_tcvtrowps2bf16h (1, B) #define
> +__builtin_ia32_tcvtrowps2bf16l(A, B) __builtin_ia32_tcvtrowps2bf16l (1,
> +B) #define __builtin_ia32_tcvtrowps2phh(A, B)
> +__builtin_ia32_tcvtrowps2phh (1, B) #define
> +__builtin_ia32_tcvtrowps2phl(A, B) __builtin_ia32_tcvtrowps2phl (1, B)
> +#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)
>  #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 0a67ede6011..c0b9fb0a796 100644
> --- a/gcc/testsuite/gcc.target/i386/sse-14.c
> +++ b/gcc/testsuite/gcc.target/i386/sse-14.c
> @@ -32,6 +32,10 @@
>    type _CONCAT(_,func) (op1_type A, int const I)                       \
>    { return func (A, imm); }
>
> +#define test_1t(func, type, imm, op1_type)                             \
> +  type _CONCAT(_,func) (int const I, op1_type A)                       \
> +  { return func (imm, A); }
> +
>  #define test_1x(func, type, op1_type, imm1, imm2)                      \
>    type _CONCAT(_,func) (op1_type A, int const I, int const L)          \
>    { return func (A, imm1, imm2); }
> @@ -44,6 +48,10 @@
>    type _CONCAT(_,func) (op1_type A, op2_type B, int const I)           \
>    { return func (A, B, imm); }
>
> +#define test_2vt(func, imm, op1_type, op2_type)                              
>   \
> +  void _CONCAT(_,func) (int const I, op1_type A, op2_type B)           \
> +  { func (imm, A, B); }
> +
>  #define test_2x(func, type, op1_type, op2_type, imm1, imm2)            \
>    type _CONCAT(_,func) (op1_type A, op2_type B, int const I, int const L) \
>    { return func (A, B, imm1, imm2); }
> @@ -1211,4 +1219,12 @@ test_2 (_mm512_maskz_unpack_epi8, __m512i,
> __mmask64, __m512i, 10)
>  /* acev1intrin.h */
>  #ifdef __x86_64__
>  test_0v (_tile_ace_zero, 1)
> +test_1t (_tile_cvtrow_epi32_ps, __m512, 1, int) test_1t
> +(_tile_cvtrowh_ps_pbh, __m512bh, 1, int) test_1t (_tile_cvtrowl_ps_pbh,
> +__m512bh, 1, int) test_1t (_tile_cvtrowh_ps_ph, __m512h, 1, int)
> +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)
>  #endif
> diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c
> b/gcc/testsuite/gcc.target/i386/sse-22.c
> index e615b2b135e..fa5e42fc808 100644
> --- a/gcc/testsuite/gcc.target/i386/sse-22.c
> +++ b/gcc/testsuite/gcc.target/i386/sse-22.c
> @@ -34,6 +34,10 @@
>    type _CONCAT(_,func) (op1_type A, int const I)                       \
>    { return func (A, imm); }
>
> +#define test_1t(func, type, imm, op1_type)                             \
> +  type _CONCAT(_,func) (int const I, op1_type A)                       \
> +  { return func (imm, A); }
> +
>  #define test_1x(func, type, op1_type, imm1, imm2)                      \
>    type _CONCAT(_,func) (op1_type A, int const I, int const L)          \
>    { return func (A, imm1, imm2); }
> @@ -46,6 +50,10 @@
>    type _CONCAT(_,func) (op1_type A, op2_type B, int const I)           \
>    { return func (A, B, imm); }
>
> +#define test_2vt(func, imm, op1_type, op2_type)                              
>   \
> +  void _CONCAT(_,func) (int const I, op1_type A, op2_type B)           \
> +  { func (imm, A, B); }
> +
>  #define test_2x(func, type, op1_type, op2_type, imm1, imm2)            \
>    type _CONCAT(_,func) (op1_type A, op2_type B, int const I, int const L) \
>    { return func (A, B, imm1, imm2); }
> @@ -1252,4 +1260,12 @@ test_2 (_mm512_maskz_unpack_epi8, __m512i,
> __mmask64, __m512i, 10)
>  /* acev1intrin.h */
>  #ifdef __x86_64__
>  test_0v (_tile_ace_zero, 1)
> +test_1t (_tile_cvtrow_epi32_ps, __m512, 1, int) test_1t
> +(_tile_cvtrowh_ps_pbh, __m512bh, 1, int) test_1t (_tile_cvtrowl_ps_pbh,
> +__m512bh, 1, int) test_1t (_tile_cvtrowh_ps_ph, __m512h, 1, int)
> +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)
>  #endif
> diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c
> b/gcc/testsuite/gcc.target/i386/sse-23.c
> index 9d5ef61e9ee..741984fded1 100644
> --- a/gcc/testsuite/gcc.target/i386/sse-23.c
> +++ b/gcc/testsuite/gcc.target/i386/sse-23.c
> @@ -903,6 +903,14 @@
>  /* acev1intrin.h */
>  #ifdef __x86_64__
>  #define __builtin_ia32_tilezero(A) __builtin_ia32_tilezero (1)
> +#define __builtin_ia32_tcvtrowd2ps(A, B) __builtin_ia32_tcvtrowd2ps (1,
> +B) #define __builtin_ia32_tcvtrowps2bf16h(A, B)
> +__builtin_ia32_tcvtrowps2bf16h (1, B) #define
> +__builtin_ia32_tcvtrowps2bf16l(A, B) __builtin_ia32_tcvtrowps2bf16l (1,
> +B) #define __builtin_ia32_tcvtrowps2phh(A, B)
> +__builtin_ia32_tcvtrowps2phh (1, B) #define
> +__builtin_ia32_tcvtrowps2phl(A, B) __builtin_ia32_tcvtrowps2phl (1, B)
> +#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)
>  #endif
>
>  #pragma GCC target
> ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tb
> m,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,sha,xsav
> ec,xsaves,clflushopt,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,vpclmulqdq,pconfi
> g,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

Other than the above questions and comments the patch looks good.

Regards,
Venkat.

Reply via email to