[PATCH v2 5/7] Support ACEv1 bsr instructions

Haochen Jiang <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
gcc/ChangeLog:

	* config/i386/acev1intrin.h: Add new intrins.
	* config/i386/i386-builtin-types.def: Add new function types.
	* config/i386/i386-builtins.cc
	(ix86_init_mmx_sse_builtins): Add new builtins.
	* config/i386/i386-builtins.h (enum ix86_builtins): Ditto.
	* config/i386/i386-expand.cc (ix86_expand_builtin):
	Handle new builtins.
	* config/i386/sse.md (UNSPEC_BSRMOVH_STORE): New.
	(UNSPEC_BSRMOVL_STORE): Ditto.
	(UNSPECV_BSRINIT): Ditto.
	(UNSPECV_BSRMOVH_LOAD): Ditto.
	(UNSPECV_BSRMOVL_LOAD): Ditto.
	(bsrinit): Ditto.
	(bsrmovf): Ditto.
	(bsrmovh_load): Ditto.
	(bsrmovl_load): Ditto.
	(bsrmovh_store): Ditto.
	(bsrmovl_store): Ditto.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/acev1-1.c: Add new tests.
	* gcc.target/i386/avx512f-helper.h: Modify include logic to
	reuse 512 related union.
	* lib/target-supports.exp: Check for ACEv1.
	* gcc.target/i386/ace-check.h: Add function entry for
	ACE execution test.
	* gcc.target/i386/ace-helper.h: Add helper function file.
	* gcc.target/i386/acev1-bsrinit-2.c: New test.
	* gcc.target/i386/acev1-bsrmovf-2.c: Ditto.
	* gcc.target/i386/acev1-bsrmovh-2.c: Ditto.
	* gcc.target/i386/acev1-bsrmovl-2.c: Ditto.
---
 gcc/config/i386/acev1intrin.h                 | 42 ++++++++++
 gcc/config/i386/i386-builtin-types.def        |  3 +
 gcc/config/i386/i386-builtins.cc              | 20 +++++
 gcc/config/i386/i386-builtins.h               |  6 ++
 gcc/config/i386/i386-expand.cc                | 54 ++++++++++++
 gcc/config/i386/sse.md                        | 61 ++++++++++++++
 gcc/testsuite/gcc.target/i386/ace-check.h     | 84 +++++++++++++++++++
 gcc/testsuite/gcc.target/i386/ace-helper.h    |  7 ++
 gcc/testsuite/gcc.target/i386/acev1-1.c       | 15 ++++
 .../gcc.target/i386/acev1-bsrinit-2.c         | 44 ++++++++++
 .../gcc.target/i386/acev1-bsrmovf-2.c         | 44 ++++++++++
 .../gcc.target/i386/acev1-bsrmovh-2.c         | 34 ++++++++
 .../gcc.target/i386/acev1-bsrmovl-2.c         | 34 ++++++++
 .../gcc.target/i386/avx512f-helper.h          |  4 +-
 gcc/testsuite/lib/target-supports.exp         | 13 +++
 15 files changed, 464 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/ace-check.h
 create mode 100644 gcc/testsuite/gcc.target/i386/ace-helper.h
 create mode 100644 gcc/testsuite/gcc.target/i386/acev1-bsrinit-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/acev1-bsrmovf-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/acev1-bsrmovh-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/acev1-bsrmovl-2.c

diff --git a/gcc/config/i386/acev1intrin.h b/gcc/config/i386/acev1intrin.h
index 6daa05db342..316d2c11f74 100644
--- a/gcc/config/i386/acev1intrin.h
+++ b/gcc/config/i386/acev1intrin.h
@@ -49,6 +49,48 @@ _tile_ace_release (void)
   __asm__ volatile ("tilerelease" ::);
 }
 
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_bsr0_init ()
+{
+  __builtin_ia32_bsr0init ();
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_bsr0_insertfull (__m512i __A, __m512i __B)
+{
+  __builtin_ia32_bsr0movf ((__v16si) __A, (__v16si) __B);
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_bsr0_inserth (__m512i __A)
+{
+  __builtin_ia32_bsr0movhinsert ((__v16si) __A);
+}
+
+extern __inline __m512i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_bsr0_extracth ()
+{
+  return (__m512i) __builtin_ia32_bsr0movhextract ();
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_bsr0_insertl (__m512i __A)
+{
+  __builtin_ia32_bsr0movlinsert ((__v16si) __A);
+}
+
+extern __inline __m512i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_bsr0_extractl ()
+{
+  return (__m512i) __builtin_ia32_bsr0movlextract ();
+}
+
 #ifdef __OPTIMIZE__
 extern __inline void
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index 40db96e68e3..baf03960954 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -1502,3 +1502,6 @@ DEF_FUNCTION_TYPE (INT64, PCINT64)
 
 # ACEv1 builtins
 DEF_FUNCTION_TYPE (VOID, UQI)
+DEF_FUNCTION_TYPE (VOID, V16SI)
+DEF_FUNCTION_TYPE (V16SI)
+DEF_FUNCTION_TYPE (VOID, V16SI, V16SI)
diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc
index d0c7cd47a6b..a34d977b757 100644
--- a/gcc/config/i386/i386-builtins.cc
+++ b/gcc/config/i386/i386-builtins.cc
@@ -1265,6 +1265,26 @@ ix86_init_mmx_sse_builtins (void)
 	       "__builtin_ia32_uwrmsr", VOID_FTYPE_UINT64_UINT64,
 	       IX86_BUILTIN_UWRMSR);
 
+  /* ACEv1.  */
+  def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
+	       "__builtin_ia32_bsr0init", VOID_FTYPE_VOID,
+	       IX86_BUILTIN_BSR0INIT);
+  def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
+	       "__builtin_ia32_bsr0movf", VOID_FTYPE_V16SI_V16SI,
+	       IX86_BUILTIN_BSR0MOVF);
+  def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
+	       "__builtin_ia32_bsr0movhinsert", VOID_FTYPE_V16SI,
+	       IX86_BUILTIN_BSR0MOVHINSERT);
+  def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
+	       "__builtin_ia32_bsr0movhextract", V16SI_FTYPE_VOID,
+	       IX86_BUILTIN_BSR0MOVHEXTRACT);
+  def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
+	       "__builtin_ia32_bsr0movlinsert", VOID_FTYPE_V16SI,
+	       IX86_BUILTIN_BSR0MOVLINSERT);
+  def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_ACEV1,
+	       "__builtin_ia32_bsr0movlextract", V16SI_FTYPE_VOID,
+	       IX86_BUILTIN_BSR0MOVLEXTRACT);
+
   /* CLDEMOTE.  */
   def_builtin (0, OPTION_MASK_ISA2_CLDEMOTE, "__builtin_ia32_cldemote",
 	       VOID_FTYPE_PCVOID, IX86_BUILTIN_CLDEMOTE);
diff --git a/gcc/config/i386/i386-builtins.h b/gcc/config/i386/i386-builtins.h
index 910a6f60e95..63a2cb9b51a 100644
--- a/gcc/config/i386/i386-builtins.h
+++ b/gcc/config/i386/i386-builtins.h
@@ -41,6 +41,12 @@ enum ix86_builtins
   IX86_BUILTIN_UMWAIT,
   IX86_BUILTIN_URDMSR,
   IX86_BUILTIN_UWRMSR,
+  IX86_BUILTIN_BSR0INIT,
+  IX86_BUILTIN_BSR0MOVF,
+  IX86_BUILTIN_BSR0MOVHINSERT,
+  IX86_BUILTIN_BSR0MOVHEXTRACT,
+  IX86_BUILTIN_BSR0MOVLINSERT,
+  IX86_BUILTIN_BSR0MOVLEXTRACT,
   IX86_BUILTIN_TPAUSE,
   IX86_BUILTIN_TESTUI,
   IX86_BUILTIN_CLZERO,
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 45c79342a40..b6e5180564a 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -15695,6 +15695,60 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
 	return target;
       }
 
+    case IX86_BUILTIN_BSR0INIT:
+      {
+	target = gen_rtx_REG (V32SImode, BSR0_REG);
+	emit_insn (gen_bsrinit (target));
+	return 0;
+      }
+
+    case IX86_BUILTIN_BSR0MOVF:
+      {
+	arg0 = CALL_EXPR_ARG (exp, 0);
+	arg1 = CALL_EXPR_ARG (exp, 1);
+	op0 = expand_normal (arg0);
+	op1 = expand_normal (arg1);
+
+	target = gen_rtx_REG (V32SImode, BSR0_REG);
+	if (CONST_VECTOR_P (op0) || MEM_P (op0))
+	  op0 = force_reg (V16SImode, op0);
+	if (CONST_VECTOR_P (op1))
+	  op1 = force_reg (V16SImode, op1);
+	emit_insn (gen_bsrmovf (target, op0, op1));
+	return 0;
+      }
+
+    case IX86_BUILTIN_BSR0MOVHINSERT:
+    case IX86_BUILTIN_BSR0MOVLINSERT:
+      {
+	arg0 = CALL_EXPR_ARG (exp, 0);
+	op0 = expand_normal (arg0);
+
+	if (fcode == IX86_BUILTIN_BSR0MOVHINSERT)
+	  icode = CODE_FOR_bsrmovh_load;
+	else
+	  icode = CODE_FOR_bsrmovl_load;
+	target = gen_rtx_REG (V32SImode, BSR0_REG);
+	if (CONST_VECTOR_P (op0))
+	  op0 = force_reg (V16SImode, op0);
+	emit_insn (GEN_FCN (icode) (target, op0));
+	return 0;
+      }
+
+    case IX86_BUILTIN_BSR0MOVHEXTRACT:
+    case IX86_BUILTIN_BSR0MOVLEXTRACT:
+      {
+	op0 = gen_rtx_REG (V32SImode, BSR0_REG);
+	if (fcode == IX86_BUILTIN_BSR0MOVHEXTRACT)
+	  icode = CODE_FOR_bsrmovh_store;
+	else
+	  icode = CODE_FOR_bsrmovl_store;
+	if (target == 0 || !register_operand (target, V16SImode))
+	  target = gen_reg_rtx (V16SImode);
+	emit_insn (GEN_FCN (icode) (target, op0));
+	return target;
+      }
+
     case IX86_BUILTIN_VEC_INIT_V2SI:
     case IX86_BUILTIN_VEC_INIT_V4HI:
     case IX86_BUILTIN_VEC_INIT_V8QI:
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 1081737bfce..e0e19a2d128 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -281,6 +281,10 @@
   UNSPEC_VCVTHF62HF8
   UNSPEC_VUNPACKB
   UNSPEC_VPMOVSSDB
+
+  ;; For ACEv1 support
+  UNSPEC_BSRMOVH_STORE
+  UNSPEC_BSRMOVL_STORE
 ])
 
 (define_c_enum "unspecv" [
@@ -306,6 +310,10 @@
 
   ;; For ACEv1
   UNSPECV_TILEZERO
+  UNSPECV_BSRINIT
+  UNSPECV_BSRMOVF
+  UNSPECV_BSRMOVH_LOAD
+  UNSPECV_BSRMOVL_LOAD
 ])
 
 ;; All vector modes including V?TImode, used in move patterns.
@@ -34933,3 +34941,56 @@
   "TARGET_ACEV1"
   "tilezero\t{%%tmm%c0|tmm%c0}"
   [(set_attr "prefix" "vex")])
+
+(define_insn "bsrinit"
+  [(set (match_operand:V32SI 0 "bsr0_operand")
+        (unspec_volatile:V32SI [(const_int 0)] UNSPECV_BSRINIT))]
+  "TARGET_ACEV1"
+  "bsrinit\t{%0|%0}"
+  [(set_attr "prefix" "vex")])
+
+(define_insn "bsrmovf"
+  [(set (match_operand:V32SI 0 "bsr0_operand")
+        (unspec_volatile:V32SI
+	  [(match_operand:V16SI 1 "register_operand" "v")
+	   (match_operand:V16SI 2 "vector_operand" "vm")]
+	  UNSPECV_BSRMOVF))]
+  "TARGET_ACEV1"
+  "bsrmovf\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "prefix" "evex")])
+
+(define_insn "bsrmovh_load"
+  [(set (match_operand:V32SI 0 "bsr0_operand")
+        (unspec_volatile:V32SI
+	  [(match_operand:V16SI 1 "vector_operand" "vm")]
+	  UNSPECV_BSRMOVH_LOAD))]
+  "TARGET_ACEV1"
+  "bsrmovh\t{%1, %0|%0, %1}"
+  [(set_attr "prefix" "evex")])
+
+(define_insn "bsrmovl_load"
+  [(set (match_operand:V32SI 0 "bsr0_operand")
+        (unspec_volatile:V32SI
+	  [(match_operand:V16SI 1 "vector_operand" "vm")]
+	  UNSPECV_BSRMOVL_LOAD))]
+  "TARGET_ACEV1"
+  "bsrmovl\t{%1, %0|%0, %1}"
+  [(set_attr "prefix" "evex")])
+
+(define_insn "bsrmovh_store"
+  [(set (match_operand:V16SI 0 "vector_operand" "=vm")
+        (unspec:V16SI
+          [(match_operand:V32SI 1 "bsr0_operand")]
+	  UNSPEC_BSRMOVH_STORE))]
+  "TARGET_ACEV1"
+  "bsrmovh\t{%1, %0|%0, %1}"
+  [(set_attr "prefix" "evex")])
+
+(define_insn "bsrmovl_store"
+  [(set (match_operand:V16SI 0 "vector_operand" "=vm")
+        (unspec:V16SI
+          [(match_operand:V32SI 1 "bsr0_operand")]
+	  UNSPEC_BSRMOVL_STORE))]
+  "TARGET_ACEV1"
+  "bsrmovl\t{%1, %0|%0, %1}"
+  [(set_attr "prefix" "evex")])
diff --git a/gcc/testsuite/gcc.target/i386/ace-check.h b/gcc/testsuite/gcc.target/i386/ace-check.h
new file mode 100644
index 00000000000..e9ea67ce3dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/ace-check.h
@@ -0,0 +1,84 @@
+#ifndef ACE_CHECK_H_INCLUDED
+#define ACE_CHECK_H_INCLUDED
+#include "cpuid.h"
+#include "m512-check.h"
+
+typedef struct __tile_config
+{
+  unsigned char palette_id; 
+  unsigned char reserved[63];
+} __tilecfg;
+
+typedef union __tile
+{
+  unsigned char buf[1024];
+  float a[256];
+  int b[256];
+} __tile;
+
+typedef struct __bsr
+{
+  unsigned char buf[128];
+} __bsr;
+
+void init_bsr (__bsr *bsr, union512i_ub *src1, union512i_ub *src2)
+{
+  int i;
+  for (i = 0; i < 64; i++)
+    {
+      bsr->buf[i] = 0x7f;
+      src1->a[i] = 0x7f;
+    }
+  for (i = 0; i < 64; i++)
+    {
+      bsr->buf[i + 64] = 0x7f;
+      src2->a[i] = 0x7f;
+    }
+}
+
+void fill_bsr (__bsr *bsr, union512i_ub* src1, union512i_ub* src2)
+{
+  int i;
+  for (i = 0; i < 64; i++)
+    {
+      bsr->buf[i] = 127 + i;
+      src1->a[i] = 127 + i;
+    }
+  for (i = 0; i < 64; i++)
+    {
+      bsr->buf[i + 64] = 127 - i;
+      src2->a[i] = 127 - i;
+    }
+}
+
+#ifndef DO_TEST
+#define DO_TEST do_test
+static void test_ace (void);
+__attribute__ ((noinline))
+static void
+do_test (void)
+{
+  test_ace ();
+}
+#endif
+
+int
+main ()
+{
+  /* Check cpu support for ACE */
+  if (__builtin_cpu_supports ("acev1"))
+    {
+      DO_TEST ();
+#ifdef DEBUG
+      printf ("PASSED\n");
+#endif
+    }
+#ifdef DEBUG
+  else
+    printf ("SKIPPED\n");
+#endif
+
+  return 0;
+}
+
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/ace-helper.h b/gcc/testsuite/gcc.target/i386/ace-helper.h
new file mode 100644
index 00000000000..8b4611e6e3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/ace-helper.h
@@ -0,0 +1,7 @@
+#ifndef ACE_HELPER_H_INCLUDED
+#define ACE_HELPER_H_INCLUDED
+#define ACE
+#define AVX512FP16
+#define AVX512BF16
+#include "avx512f-helper.h"
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/acev1-1.c b/gcc/testsuite/gcc.target/i386/acev1-1.c
index 9165f571ef9..daff9278363 100644
--- a/gcc/testsuite/gcc.target/i386/acev1-1.c
+++ b/gcc/testsuite/gcc.target/i386/acev1-1.c
@@ -4,9 +4,14 @@
 /* { dg-final { scan-assembler-times "sttilecfg\[ \t]" 1 } } */
 /* { dg-final { scan-assembler-times "tilerelease" 1 } } */
 /* { dg-final { scan-assembler-times "tilezero\[ \t]" 1 } } */
+/* { dg-final { scan-assembler-times "bsrinit\[ \t]" 1 } } */
+/* { dg-final { scan-assembler-times "bsrmovf\[ \t]" 1 } } */
+/* { dg-final { scan-assembler-times "bsrmovl\[ \t]" 2 } } */
+/* { dg-final { scan-assembler-times "bsrmovh\[ \t]" 2 } } */
 #include <immintrin.h>
 
 extern int t[];
+__m512i a1,a2;
 
 void amxtile ()
 {
@@ -15,3 +20,13 @@ void amxtile ()
   _tile_ace_release ();
   _tile_ace_zero (0);
 }
+
+void bsr ()
+{
+  _bsr0_init ();
+  _bsr0_insertfull (a1, a2);
+  _bsr0_inserth (a1);
+  a1 = _bsr0_extracth ();
+  _bsr0_insertl (a2);
+  a2 = _bsr0_extractl ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/acev1-bsrinit-2.c b/gcc/testsuite/gcc.target/i386/acev1-bsrinit-2.c
new file mode 100644
index 00000000000..19ff3680e89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/acev1-bsrinit-2.c
@@ -0,0 +1,44 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-require-effective-target acev1 } */
+/* { dg-options "-O2 -macev1" } */
+#define DO_TEST test_acev1_bsrinit
+void test_acev1_bsrinit ();
+#include "ace-helper.h"
+
+void test_acev1_bsrinit ()
+{
+  __tilecfg cfg;
+  __bsr bsr0;
+  union512i_ub src1, src2, res1, res2;
+  int i, miss;
+
+  init_tile_config (&cfg, &bsr0);
+
+  init_bsr (&bsr0, &src1, &src2);
+
+  _bsr0_init ();
+  res1.x = _bsr0_extractl ();
+  res2.x = _bsr0_extracth ();
+
+  miss = 0;
+  for (i = 0; i < 64; i++)
+    if (res1.a[i] != bsr0.buf[i])
+      {
+#ifdef DEBUG
+	printf ("%d: %d != %d\n", i, res1.a[i], bsr0.buf[i]);
+#endif
+	miss++;
+      }
+
+  for (i = 0; i < 64; i++)
+    if (res2.a[i] != bsr0.buf[i + 64])
+      {
+#ifdef DEBUG
+	printf ("%d: %d != %d\n", i, res2.a[i], bsr0.buf[i + 64]);
+#endif
+	miss++;
+      }
+
+  if (miss)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/acev1-bsrmovf-2.c b/gcc/testsuite/gcc.target/i386/acev1-bsrmovf-2.c
new file mode 100644
index 00000000000..a807f92d6a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/acev1-bsrmovf-2.c
@@ -0,0 +1,44 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-require-effective-target acev1 } */
+/* { dg-options "-O2 -macev1" } */
+#define DO_TEST test_acev1_bsrmovf
+void test_acev1_bsrmovf ();
+#include "ace-helper.h"
+
+void test_acev1_bsrmovf ()
+{
+  __tilecfg cfg;
+  __bsr bsr0;
+  union512i_ub src1, src2, res1, res2;
+  int i, miss;
+
+  init_tile_config (&cfg, &bsr0);
+
+  fill_bsr (&bsr0, &src1, &src2);
+
+  _bsr0_insertfull (src2.x, src1.x);
+  res1.x = _bsr0_extractl ();
+  res2.x = _bsr0_extracth ();
+
+  miss = 0;
+  for (i = 0; i < 64; i++)
+    if (res1.a[i] != bsr0.buf[i])
+      {
+#ifdef DEBUG
+	printf ("%d: %d != %d\n", i, res1.a[i], bsr0.buf[i]);
+#endif
+	miss++;
+      }
+
+  for (i = 0; i < 64; i++)
+    if (res2.a[i] != bsr0.buf[i + 64])
+      {
+#ifdef DEBUG
+	printf ("%d: %d != %d\n", i, res2.a[i], bsr0.buf[i + 64]);
+#endif
+	miss++;
+      }
+
+  if (miss)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/acev1-bsrmovh-2.c b/gcc/testsuite/gcc.target/i386/acev1-bsrmovh-2.c
new file mode 100644
index 00000000000..bf0af09d4ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/acev1-bsrmovh-2.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-require-effective-target acev1 } */
+/* { dg-options "-O2 -macev1" } */
+#define DO_TEST test_acev1_bsrmovh
+void test_acev1_bsrmovh ();
+#include "ace-helper.h"
+
+void test_acev1_bsrmovh ()
+{
+  __tilecfg cfg;
+  __bsr bsr0;
+  union512i_ub src1, src2, res;
+  int i, miss;
+
+  init_tile_config (&cfg, &bsr0);
+
+  fill_bsr (&bsr0, &src1, &src2);
+
+  _bsr0_inserth (src2.x);
+  res.x = _bsr0_extracth ();
+
+  miss = 0;
+  for (i = 0; i < 64; i++)
+    if (res.a[i] != bsr0.buf[i + 64])
+      {
+#ifdef DEBUG
+	printf ("%d: %d != %d\n", i, res.a[i], bsr0.buf[i + 64]);
+#endif
+	miss++;
+      }
+
+  if (miss)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/acev1-bsrmovl-2.c b/gcc/testsuite/gcc.target/i386/acev1-bsrmovl-2.c
new file mode 100644
index 00000000000..0068c5c0623
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/acev1-bsrmovl-2.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-require-effective-target acev1 } */
+/* { dg-options "-O2 -macev1" } */
+#define DO_TEST test_acev1_bsrmovl
+void test_acev1_bsrmovl ();
+#include "ace-helper.h"
+
+void test_acev1_bsrmovl ()
+{
+  __tilecfg cfg;
+  __bsr bsr0;
+  union512i_ub src1, src2, res;
+  int i, miss;
+
+  init_tile_config (&cfg, &bsr0);
+
+  fill_bsr (&bsr0, &src1, &src2);
+
+  _bsr0_insertl (src1.x);
+  res.x = _bsr0_extractl ();
+
+  miss = 0;
+  for (i = 0; i < 64; i++)
+    if (res.a[i] != bsr0.buf[i])
+      {
+#ifdef DEBUG
+	printf ("%d: %d != %d\n", i, res.a[i], bsr0.buf[i]);
+#endif
+	miss++;
+      }
+
+  if (miss)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-helper.h b/gcc/testsuite/gcc.target/i386/avx512f-helper.h
index f0089812563..194d3b04035 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-helper.h
+++ b/gcc/testsuite/gcc.target/i386/avx512f-helper.h
@@ -8,7 +8,9 @@
 #ifndef AVX512F_HELPER_INCLUDED
 #define AVX512F_HELPER_INCLUDED
 
-#if defined(AVX10)
+#if defined(ACE)
+#include "ace-check.h"
+#elif defined(AVX10)
 #include "avx10-check.h"
 #else
 #include "avx512-check.h"
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 987e57dfac7..1a1256af1c3 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -11741,6 +11741,19 @@ proc check_effective_target_amx_movrs { } {
     } "-mamx-movrs" ]
 }
 
+
+# Return 1 if acev1 instructions can be compiled.
+proc check_effective_target_acev1 { } {
+    return [check_no_compiler_messages acev1 object {
+	void
+	_bsr0_init ()
+	{
+	  return __builtin_ia32_bsr0init ();
+	}
+
+    } "-macev1" ]
+}
+
 # Return 1 if sse instructions can be compiled.
 proc check_effective_target_sse { } {
     return [check_no_compiler_messages sse object {
-- 
2.31.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.