diff mbox

[i386,AVX512] Match latest spec.

Message ID 20140220153922.GB1312@msticlxl7.ims.intel.com
State New
Headers show

Commit Message

Ilya Tocar Feb. 20, 2014, 3:39 p.m. UTC
Hi,
Latest version of AVX512 spec
http://download-software.intel.com/sites/default/files/managed/50/1a/319433-018.pdf
Has a few changes.
This patch fixes first of them:
Vptestnmd and vptestnmq instructions now have CPUID AVX512F instead of
AVX512CD. This path changes thier CPUID accordingly.
However I have a question about other changes:

1)PREFETCHWT1 instruction now has separate CPUID bit PREFETCHWT1.
We can either support new CPUID or disable PREFETCHWT1 from generating,
without removing code, and enable it in 4.9.1/latest version.
I am not sure that adding new -m flag and related stuff this late
is a good idea. Should still add it?

2)Currently for scatter/gather prefetches intrinsics we accept 1 as
possible hint parameter. This is consistent with ICC. However as
GCC defines _MM_HINT_T0 to 3 and not to 1 as ICC
(see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56603), gather prefethces
are inconsistent with normal prefetches as they won't accept _MM_HINT_T0 as
hint. We can either change gather prefetches to accept 1 instead of 3 and
hope that everyone will use _MM_HINT_T0 and not the raw value, or we can
change _MM_HINT_T0 to be consistent with ICC. What solution do you
prefer?

Patch bellow changes CPUID of vptestnmq/vptestnmd and changes some bogus
%v to v. Bootstraps, passes make check. Ok for trunk?

ChangeLog

2014-02-20  Ilya Tocar  <ilya.tocar@intel.com>
 
	* config/i386/avx512fintrin.h (_mm512_testn_epi32_mask),
	(_mm512_mask_testn_epi32_mask), (_mm512_testn_epi64_mask),
	(_mm512_mask_testn_epi64_mask): Move to ...
	* config/i386/avx512cdintrin.h: Here.
	* config/i386/i386.c (bdesc_args): Change MASK_ISA for testnm.
	* config/i386/sse.md (avx512f_vmscalef<mode><round_name>): Remove %.
	(avx512f_scalef<mode><mask_name><round_name>): Ditto.
	(avx512f_testnm<mode>3<mask_scalar_merge_name>): Change conditon to
	TARGET_AVX512F from TARGET_AVX512CD.

And for testsuite

2014-02-20  Ilya Tocar  <ilya.tocar@intel.com>
 
	* gcc.target/i386/avx512cd-vptestnmd-1.c: Change into ...
	* gcc.target/i386/avx512f-vptestnmd-1.c: This.
	* gcc.target/i386/avx512cd-vptestnmq-1.c: Change into ...
	* gcc.target/i386/avx512f-vptestnmq-1.c: This.
	* gcc.target/i386/avx512cd-vptestnmd-2.c: Change into ...
	* gcc.target/i386/avx512f-vptestnmd-2.c: This.
	* gcc.target/i386/avx512cd-vptestnmq-2.c: Change into ...
	* gcc.target/i386/avx512f-vptestnmq-2.c: This.


---
 gcc/config/i386/avx512cdintrin.h                   | 34 --------------
 gcc/config/i386/avx512fintrin.h                    | 34 ++++++++++++++
 gcc/config/i386/i386.c                             |  4 +-
 gcc/config/i386/sse.md                             |  8 ++--
 .../gcc.target/i386/avx512cd-vptestnmd-1.c         | 16 -------
 .../gcc.target/i386/avx512cd-vptestnmd-2.c         | 52 ----------------------
 .../gcc.target/i386/avx512cd-vptestnmq-1.c         | 16 -------
 .../gcc.target/i386/avx512cd-vptestnmq-2.c         | 52 ----------------------
 .../gcc.target/i386/avx512f-vptestnmd-1.c          | 16 +++++++
 .../gcc.target/i386/avx512f-vptestnmd-2.c          | 52 ++++++++++++++++++++++
 .../gcc.target/i386/avx512f-vptestnmq-1.c          | 16 +++++++
 .../gcc.target/i386/avx512f-vptestnmq-2.c          | 52 ++++++++++++++++++++++
 12 files changed, 176 insertions(+), 176 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-1.c
 delete mode 100644 gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-2.c
 delete mode 100644 gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-1.c
 delete mode 100644 gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-2.c

Comments

Uros Bizjak Feb. 20, 2014, 4:23 p.m. UTC | #1
On Thu, Feb 20, 2014 at 4:39 PM, Ilya Tocar <tocarip.intel@gmail.com> wrote:

> Latest version of AVX512 spec
> http://download-software.intel.com/sites/default/files/managed/50/1a/319433-018.pdf
> Has a few changes.
> This patch fixes first of them:
> Vptestnmd and vptestnmq instructions now have CPUID AVX512F instead of
> AVX512CD. This path changes thier CPUID accordingly.
> However I have a question about other changes:
>
> 1)PREFETCHWT1 instruction now has separate CPUID bit PREFETCHWT1.
> We can either support new CPUID or disable PREFETCHWT1 from generating,
> without removing code, and enable it in 4.9.1/latest version.
> I am not sure that adding new -m flag and related stuff this late
> is a good idea. Should still add it?

Please submit the patch anyway. We can relax release constraints on
non-algorithmic patch a bit, weighting in benefits of having gcc
release that fully conforms to some published specification.

> 2)Currently for scatter/gather prefetches intrinsics we accept 1 as
> possible hint parameter. This is consistent with ICC. However as
> GCC defines _MM_HINT_T0 to 3 and not to 1 as ICC
> (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56603), gather prefethces
> are inconsistent with normal prefetches as they won't accept _MM_HINT_T0 as
> hint. We can either change gather prefetches to accept 1 instead of 3 and
> hope that everyone will use _MM_HINT_T0 and not the raw value, or we can
> change _MM_HINT_T0 to be consistent with ICC. What solution do you
> prefer?

Builtins, including __builtin_prefetch, are considered as internal
implementation detail, so we can pass to them wharever we like. The
published interface is in *.h files, and this includes _MM_HINT_T0.
For now, I suggest to change prefetches, so they will accept
_MM_HINT_T0, as this is the least invasive change.

FWIW, we can change _MM_HINT_T0 in the future, as intrinsic headers
correspond to the compiler, but it will raise maintenance burden (you
can't just recompile sources involving builtins with different
versions of the compiler anymore due to difference in constant
arguments).

> Patch bellow changes CPUID of vptestnmq/vptestnmd and changes some bogus
> %v to v. Bootstraps, passes make check. Ok for trunk?
>
> ChangeLog
>
> 2014-02-20  Ilya Tocar  <ilya.tocar@intel.com>
>
>         * config/i386/avx512fintrin.h (_mm512_testn_epi32_mask),
>         (_mm512_mask_testn_epi32_mask), (_mm512_testn_epi64_mask),
>         (_mm512_mask_testn_epi64_mask): Move to ...
>         * config/i386/avx512cdintrin.h: Here.
>         * config/i386/i386.c (bdesc_args): Change MASK_ISA for testnm.
>         * config/i386/sse.md (avx512f_vmscalef<mode><round_name>): Remove %.
>         (avx512f_scalef<mode><mask_name><round_name>): Ditto.
>         (avx512f_testnm<mode>3<mask_scalar_merge_name>): Change conditon to
>         TARGET_AVX512F from TARGET_AVX512CD.
>
> And for testsuite
>
> 2014-02-20  Ilya Tocar  <ilya.tocar@intel.com>
>
>         * gcc.target/i386/avx512cd-vptestnmd-1.c: Change into ...
>         * gcc.target/i386/avx512f-vptestnmd-1.c: This.
>         * gcc.target/i386/avx512cd-vptestnmq-1.c: Change into ...
>         * gcc.target/i386/avx512f-vptestnmq-1.c: This.
>         * gcc.target/i386/avx512cd-vptestnmd-2.c: Change into ...
>         * gcc.target/i386/avx512f-vptestnmd-2.c: This.
>         * gcc.target/i386/avx512cd-vptestnmq-2.c: Change into ...
>         * gcc.target/i386/avx512f-vptestnmq-2.c: This.

This is OK for mainline.

Thanks,
Uros.
diff mbox

Patch

diff --git a/gcc/config/i386/avx512cdintrin.h b/gcc/config/i386/avx512cdintrin.h
index 3935b77..a4939f7a 100644
--- a/gcc/config/i386/avx512cdintrin.h
+++ b/gcc/config/i386/avx512cdintrin.h
@@ -176,40 +176,6 @@  _mm512_broadcastmw_epi32 (__mmask16 __A)
   return (__m512i) __builtin_ia32_broadcastmw512 (__A);
 }
 
-extern __inline __mmask16
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_testn_epi32_mask (__m512i __A, __m512i __B)
-{
-  return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A,
-						 (__v16si) __B,
-						 (__mmask16) -1);
-}
-
-extern __inline __mmask16
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_testn_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B)
-{
-  return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A,
-						 (__v16si) __B, __U);
-}
-
-extern __inline __mmask8
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_testn_epi64_mask (__m512i __A, __m512i __B)
-{
-  return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A,
-						(__v8di) __B,
-						(__mmask8) -1);
-}
-
-extern __inline __mmask8
-__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_testn_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
-{
-  return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A,
-						(__v8di) __B, __U);
-}
-
 #ifdef __DISABLE_AVX512CD__
 #undef __DISABLE_AVX512CD__
 #pragma GCC pop_options
diff --git a/gcc/config/i386/avx512fintrin.h b/gcc/config/i386/avx512fintrin.h
index b3a4f3a..95f9822 100644
--- a/gcc/config/i386/avx512fintrin.h
+++ b/gcc/config/i386/avx512fintrin.h
@@ -7149,6 +7149,40 @@  _mm512_mask_test_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
   return (__mmask8) __builtin_ia32_ptestmq512 ((__v8di) __A, (__v8di) __B, __U);
 }
 
+extern __inline __mmask16
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_testn_epi32_mask (__m512i __A, __m512i __B)
+{
+  return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A,
+						 (__v16si) __B,
+						 (__mmask16) -1);
+}
+
+extern __inline __mmask16
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_mask_testn_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B)
+{
+  return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A,
+						 (__v16si) __B, __U);
+}
+
+extern __inline __mmask8
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_testn_epi64_mask (__m512i __A, __m512i __B)
+{
+  return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A,
+						(__v8di) __B,
+						(__mmask8) -1);
+}
+
+extern __inline __mmask8
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_mask_testn_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
+{
+  return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A,
+						(__v8di) __B, __U);
+}
+
 extern __inline __m512i
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
 _mm512_unpackhi_epi32 (__m512i __A, __m512i __B)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0a15e44..62e5295 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -30047,8 +30047,8 @@  static const struct builtin_description bdesc_args[] =
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_subv8di3_mask, "__builtin_ia32_psubq512_mask", IX86_BUILTIN_PSUBQ512, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_QI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_testmv16si3_mask, "__builtin_ia32_ptestmd512", IX86_BUILTIN_PTESTMD512, UNKNOWN, (int) HI_FTYPE_V16SI_V16SI_HI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_testmv8di3_mask, "__builtin_ia32_ptestmq512", IX86_BUILTIN_PTESTMQ512, UNKNOWN, (int) QI_FTYPE_V8DI_V8DI_QI },
-  { OPTION_MASK_ISA_AVX512CD, CODE_FOR_avx512f_testnmv16si3_mask, "__builtin_ia32_ptestnmd512", IX86_BUILTIN_PTESTNMD512, UNKNOWN, (int) HI_FTYPE_V16SI_V16SI_HI },
-  { OPTION_MASK_ISA_AVX512CD, CODE_FOR_avx512f_testnmv8di3_mask, "__builtin_ia32_ptestnmq512", IX86_BUILTIN_PTESTNMQ512, UNKNOWN, (int) QI_FTYPE_V8DI_V8DI_QI },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_testnmv16si3_mask, "__builtin_ia32_ptestnmd512", IX86_BUILTIN_PTESTNMD512, UNKNOWN, (int) HI_FTYPE_V16SI_V16SI_HI },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_testnmv8di3_mask, "__builtin_ia32_ptestnmq512", IX86_BUILTIN_PTESTNMQ512, UNKNOWN, (int) QI_FTYPE_V8DI_V8DI_QI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_interleave_highv16si_mask, "__builtin_ia32_punpckhdq512_mask", IX86_BUILTIN_PUNPCKHDQ512, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_HI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_interleave_highv8di_mask, "__builtin_ia32_punpckhqdq512_mask", IX86_BUILTIN_PUNPCKHQDQ512, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_QI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_interleave_lowv16si_mask, "__builtin_ia32_punpckldq512_mask", IX86_BUILTIN_PUNPCKLDQ512, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_HI },
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 5595767..c0da6b7 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -6567,7 +6567,7 @@ 
 	  (match_dup 1)
 	  (const_int 1)))]
   "TARGET_AVX512F"
-  "%vscalef<ssescalarmodesuffix>\t{<round_op3>%2, %1, %0|%0, %1, %2<round_op3>}"
+  "vscalef<ssescalarmodesuffix>\t{<round_op3>%2, %1, %0|%0, %1, %2<round_op3>}"
   [(set_attr "prefix" "evex")
    (set_attr "mode"  "<ssescalarmode>")])
 
@@ -6578,7 +6578,7 @@ 
 	   (match_operand:VF_512 2 "<round_nimm_predicate>" "<round_constraint>")]
 	  UNSPEC_SCALEF))]
   "TARGET_AVX512F"
-  "%vscalef<ssemodesuffix>\t{<round_mask_op3>%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2<round_mask_op3>}"
+  "vscalef<ssemodesuffix>\t{<round_mask_op3>%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2<round_mask_op3>}"
   [(set_attr "prefix" "evex")
    (set_attr "mode"  "<MODE>")])
 
@@ -9072,8 +9072,8 @@ 
 	 [(match_operand:VI48_512 1 "register_operand" "v")
 	  (match_operand:VI48_512 2 "nonimmediate_operand" "vm")]
 	 UNSPEC_TESTNM))]
-  "TARGET_AVX512CD"
-  "%vptestnm<ssemodesuffix>\t{%2, %1, %0<mask_scalar_merge_operand3>|%0<mask_scalar_merge_operand3>, %1, %2}"
+  "TARGET_AVX512F"
+  "vptestnm<ssemodesuffix>\t{%2, %1, %0<mask_scalar_merge_operand3>|%0<mask_scalar_merge_operand3>, %1, %2}"
   [(set_attr "prefix" "evex")
    (set_attr "mode"  "<sseinsnmode>")])
 
diff --git a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-1.c b/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-1.c
deleted file mode 100644
index 39797a8..0000000
--- a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-1.c
+++ /dev/null
@@ -1,16 +0,0 @@ 
-/* { dg-do compile } */
-/* { dg-options "-mavx512cd -O2" } */
-/* { dg-final { scan-assembler-times "vptestnmd\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\[^\{\]" 1 } } */
-/* { dg-final { scan-assembler-times "vptestnmd\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\{" 1 } } */
-
-#include <immintrin.h>
-
-volatile __m512i x;
-volatile __mmask16 m16;
-
-void extern
-avx512cd_test (void)
-{
-  m16 = _mm512_testn_epi32_mask (x, x);
-  m16 = _mm512_mask_testn_epi32_mask (3, x, x);
-}
diff --git a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-2.c b/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-2.c
deleted file mode 100644
index 567e164..0000000
--- a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmd-2.c
+++ /dev/null
@@ -1,52 +0,0 @@ 
-/* { dg-do run } */
-/* { dg-options "-O2 -mavx512cd" } */
-/* { dg-require-effective-target avx512cd } */
-
-#define AVX512CD
-
-#include "avx512f-helper.h"
-
-#define SIZE (AVX512F_LEN / 32)
-#include "avx512f-mask-type.h"
-
-CALC (MASK_TYPE *res, int *src1, int *src2)
-{
-  int i;
-  *res = 0;
-  MASK_TYPE one = 1;
-
-  for (i = 0; i < SIZE; i++)
-    if (!(src1[i] & src2[i]))
-      *res = *res | one << i;
-}
-
-static void
-TEST (void)
-{
-  int i, sign = 1;
-  UNION_TYPE (AVX512F_LEN, i_d) src1, src2;
-  MASK_TYPE res_ref, res1, res2;
-  MASK_TYPE mask = MASK_VALUE;
-  res1 = 0;
-  res2 = 0;
-
-  for (i = 0; i < SIZE; i++)
-    {
-      src1.a[i] = i * i * sign;
-      src2.a[i] = i + 20;
-      sign = -sign;
-    }
-
-  res1 = INTRINSIC (_testn_epi32_mask) (src1.x, src2.x);
-  res2 = INTRINSIC (_mask_testn_epi32_mask) (mask, src1.x, src2.x);
-
-  CALC (&res_ref, src1.a, src2.a);
-
-  if (res1 != res_ref)
-    abort ();
-
-  res_ref &= mask;
-
-  if (res2 != res_ref)
-    abort ();
-}
diff --git a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-1.c b/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-1.c
deleted file mode 100644
index dd68612..0000000
--- a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-1.c
+++ /dev/null
@@ -1,16 +0,0 @@ 
-/* { dg-do compile } */
-/* { dg-options "-mavx512cd -O2" } */
-/* { dg-final { scan-assembler-times "vptestnmq\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\[^\{\]" 1 } } */
-/* { dg-final { scan-assembler-times "vptestnmq\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\{" 1 } } */
-
-#include <immintrin.h>
-
-volatile __m512i x;
-volatile __mmask8 m8;
-
-void extern
-avx512cd_test (void)
-{
-  m8 = _mm512_testn_epi64_mask (x, x);
-  m8 = _mm512_mask_testn_epi64_mask (3, x, x);
-}
diff --git a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-2.c b/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-2.c
deleted file mode 100644
index ff9f011..0000000
--- a/gcc/testsuite/gcc.target/i386/avx512cd-vptestnmq-2.c
+++ /dev/null
@@ -1,52 +0,0 @@ 
-/* { dg-do run } */
-/* { dg-options "-O2 -mavx512cd" } */
-/* { dg-require-effective-target avx512cd } */
-
-#define AVX512CD
-
-#include "avx512f-helper.h"
-
-#define SIZE (AVX512F_LEN / 64)
-#include "avx512f-mask-type.h"
-
-CALC (MASK_TYPE *res, long long *src1, long long *src2)
-{
-  int i;
-  *res = 0;
-  MASK_TYPE one = 1;
-
-  for (i = 0; i < SIZE; i++)
-    if (!(src1[i] & src2[i]))
-      *res = *res | one << i;
-}
-
-static void
-TEST (void)
-{
-  int i, sign = 1;
-  UNION_TYPE (AVX512F_LEN, i_q) src1, src2;
-  MASK_TYPE res_ref, res1, res2;
-  MASK_TYPE mask = MASK_VALUE;
-  res1 = 0;
-  res2 = 0;
-
-  for (i = 0; i < SIZE; i++)
-    {
-      src1.a[i] = i * i * sign;
-      src2.a[i] = i + 20;
-      sign = -sign;
-    }
-
-  res1 = INTRINSIC (_testn_epi64_mask) (src1.x, src2.x);
-  res2 = INTRINSIC (_mask_testn_epi64_mask) (mask, src1.x, src2.x);
-
-  CALC (&res_ref, src1.a, src2.a);
-
-  if (res1 != res_ref)
-    abort ();
-
-  res_ref &= mask;
-
-  if (res2 != res_ref)
-    abort ();
-}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-1.c
new file mode 100644
index 0000000..1094ee5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-1.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mavx512f -O2" } */
+/* { dg-final { scan-assembler-times "vptestnmd\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\[^\{\]" 1 } } */
+/* { dg-final { scan-assembler-times "vptestnmd\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\{" 1 } } */
+
+#include <immintrin.h>
+
+volatile __m512i x;
+volatile __mmask16 m16;
+
+void extern
+avx512f_test (void)
+{
+  m16 = _mm512_testn_epi32_mask (x, x);
+  m16 = _mm512_mask_testn_epi32_mask (3, x, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-2.c
new file mode 100644
index 0000000..b2b4d0e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmd-2.c
@@ -0,0 +1,52 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx512f" } */
+/* { dg-require-effective-target avx512f } */
+
+#define AVX512F
+
+#include "avx512f-helper.h"
+
+#define SIZE (AVX512F_LEN / 32)
+#include "avx512f-mask-type.h"
+
+CALC (MASK_TYPE *res, int *src1, int *src2)
+{
+  int i;
+  *res = 0;
+  MASK_TYPE one = 1;
+
+  for (i = 0; i < SIZE; i++)
+    if (!(src1[i] & src2[i]))
+      *res = *res | one << i;
+}
+
+static void
+TEST (void)
+{
+  int i, sign = 1;
+  UNION_TYPE (AVX512F_LEN, i_d) src1, src2;
+  MASK_TYPE res_ref, res1, res2;
+  MASK_TYPE mask = MASK_VALUE;
+  res1 = 0;
+  res2 = 0;
+
+  for (i = 0; i < SIZE; i++)
+    {
+      src1.a[i] = i * i * sign;
+      src2.a[i] = i + 20;
+      sign = -sign;
+    }
+
+  res1 = INTRINSIC (_testn_epi32_mask) (src1.x, src2.x);
+  res2 = INTRINSIC (_mask_testn_epi32_mask) (mask, src1.x, src2.x);
+
+  CALC (&res_ref, src1.a, src2.a);
+
+  if (res1 != res_ref)
+    abort ();
+
+  res_ref &= mask;
+
+  if (res2 != res_ref)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-1.c
new file mode 100644
index 0000000..081a25e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-1.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mavx512f -O2" } */
+/* { dg-final { scan-assembler-times "vptestnmq\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\[^\{\]" 1 } } */
+/* { dg-final { scan-assembler-times "vptestnmq\[ \\t\]+\[^\n\]*%zmm\[0-7\]\[^\n^k\]*k\[1-7\]\{" 1 } } */
+
+#include <immintrin.h>
+
+volatile __m512i x;
+volatile __mmask8 m8;
+
+void extern
+avx512f_test (void)
+{
+  m8 = _mm512_testn_epi64_mask (x, x);
+  m8 = _mm512_mask_testn_epi64_mask (3, x, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-2.c
new file mode 100644
index 0000000..b6330d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vptestnmq-2.c
@@ -0,0 +1,52 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx512f" } */
+/* { dg-require-effective-target avx512f } */
+
+#define AVX512F
+
+#include "avx512f-helper.h"
+
+#define SIZE (AVX512F_LEN / 64)
+#include "avx512f-mask-type.h"
+
+CALC (MASK_TYPE *res, long long *src1, long long *src2)
+{
+  int i;
+  *res = 0;
+  MASK_TYPE one = 1;
+
+  for (i = 0; i < SIZE; i++)
+    if (!(src1[i] & src2[i]))
+      *res = *res | one << i;
+}
+
+static void
+TEST (void)
+{
+  int i, sign = 1;
+  UNION_TYPE (AVX512F_LEN, i_q) src1, src2;
+  MASK_TYPE res_ref, res1, res2;
+  MASK_TYPE mask = MASK_VALUE;
+  res1 = 0;
+  res2 = 0;
+
+  for (i = 0; i < SIZE; i++)
+    {
+      src1.a[i] = i * i * sign;
+      src2.a[i] = i + 20;
+      sign = -sign;
+    }
+
+  res1 = INTRINSIC (_testn_epi64_mask) (src1.x, src2.x);
+  res2 = INTRINSIC (_mask_testn_epi64_mask) (mask, src1.x, src2.x);
+
+  CALC (&res_ref, src1.a, src2.a);
+
+  if (res1 != res_ref)
+    abort ();
+
+  res_ref &= mask;
+
+  if (res2 != res_ref)
+    abort ();
+}