public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH AVX512] Fix dg.torture tests with avx512
@ 2014-10-30 15:08 Ilya Tocar
  2014-10-31 10:32 ` Uros Bizjak
  0 siblings, 1 reply; 4+ messages in thread
From: Ilya Tocar @ 2014-10-30 15:08 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: GCC Patches

Hi,

I've run gcc.dg/torture/* tests with -mavx512bw -mavx512vl -mavx512dq
flags, and got a bunch of fails (mostly in permutes autogen).
Patch below fixes them.
Ok for trunk?

2014-10-30  Ilya Tocar  <ilya.tocar@intel.com>

	* config/i386/i386.c (expand_vec_perm_pshufb): Try vpermq/vpermd
	for 512-bit wide modes.
	(expand_vec_perm_1): Use correct versions of patterns.
	* config/i386/sse.md (avx512f_vec_dup_<mode>_1): New.
	(vashr<mode>3<mask_name>): Split V8HImode and V16QImode.

---
 gcc/config/i386/i386.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------
 gcc/config/i386/sse.md | 54 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 98 insertions(+), 15 deletions(-)

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 71a4f6a..74ff894 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -45889,6 +45889,42 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
 	{
 	  if (!TARGET_AVX512BW)
 	    return false;
+
+	  /* If vpermq didn't work, vpshufb won't work either.  */
+	  if (d->vmode == V8DFmode || d->vmode == V8DImode)
+	    return false;
+
+	  vmode = V64QImode;
+	  if (d->vmode == V16SImode
+	      || d->vmode == V32HImode
+	      || d->vmode == V64QImode)
+	    {
+	      /* First see if vpermq can be used for
+		 V16SImode/V32HImode/V64QImode.  */
+	      if (valid_perm_using_mode_p (V8DImode, d))
+		{
+		  for (i = 0; i < 8; i++)
+		    perm[i] = (d->perm[i * nelt / 8] * 8 / nelt) & 7;
+		  if (d->testing_p)
+		    return true;
+		  target = gen_reg_rtx (V8DImode);
+		  if (expand_vselect (target, gen_lowpart (V8DImode, d->op0),
+				      perm, 8, false))
+		    {
+		      emit_move_insn (d->target,
+				      gen_lowpart (d->vmode, target));
+		      return true;
+		    }
+		  return false;
+		}
+
+	      /* Next see if vpermd can be used.  */
+	      if (valid_perm_using_mode_p (V16SImode, d))
+		vmode = V16SImode;
+	    }
+	  /* Or if vpermps can be used.  */
+	  else if (d->vmode == V16SFmode)
+	    vmode = V16SImode;
 	  if (vmode == V64QImode)
 	    {
 	      /* vpshufb only works intra lanes, it is not
@@ -45908,6 +45944,9 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
   if (vmode == V8SImode)
     for (i = 0; i < 8; ++i)
       rperm[i] = GEN_INT ((d->perm[i * nelt / 8] * 8 / nelt) & 7);
+  else if (vmode == V16SImode)
+    for (i = 0; i < 16; ++i)
+      rperm[i] = GEN_INT ((d->perm[i * nelt / 16] * 16 / nelt) & 15);
   else
     {
       eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
@@ -45946,8 +45985,14 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
 	emit_insn (gen_avx512bw_pshufbv64qi3 (target, op0, vperm));
       else if (vmode == V8SFmode)
 	emit_insn (gen_avx2_permvarv8sf (target, op0, vperm));
-      else
+      else if (vmode == V8SImode)
 	emit_insn (gen_avx2_permvarv8si (target, op0, vperm));
+      else if (vmode == V16SFmode)
+	emit_insn (gen_avx512f_permvarv16sf (target, op0, vperm));
+      else if (vmode == V16SImode)
+	emit_insn (gen_avx512f_permvarv16si (target, op0, vperm));
+      else
+	gcc_unreachable ();
     }
   else
     {
@@ -46001,21 +46046,21 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
 	    {
 	    case V64QImode:
 	      if (TARGET_AVX512BW)
-		gen = gen_avx512bw_vec_dupv64qi;
+		gen = gen_avx512bw_vec_dup_v64qi_1;
 	      break;
 	    case V32QImode:
 	      gen = gen_avx2_pbroadcastv32qi_1;
 	      break;
 	    case V32HImode:
 	      if (TARGET_AVX512BW)
-		gen = gen_avx512bw_vec_dupv32hi;
+		gen = gen_avx512bw_vec_dup_v32hi_1;
 	      break;
 	    case V16HImode:
 	      gen = gen_avx2_pbroadcastv16hi_1;
 	      break;
 	    case V16SImode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv16si;
+		gen = gen_avx512f_vec_dup_v16si_1;
 	      break;
 	    case V8SImode:
 	      gen = gen_avx2_pbroadcastv8si_1;
@@ -46028,18 +46073,18 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
 	      break;
 	    case V16SFmode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv16sf;
+		gen = gen_avx512f_vec_dup_v16sf_1;
 	      break;
 	    case V8SFmode:
 	      gen = gen_avx2_vec_dupv8sf_1;
 	      break;
 	    case V8DFmode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv8df;
+		gen = gen_avx512f_vec_dup_v8df_1;
 	      break;
 	    case V8DImode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv8di;
+		gen = gen_avx512f_vec_dup_v8di_1;
 	      break;
 	    /* For other modes prefer other shuffles this function creates.  */
 	    default: break;
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 5986d4b..ff36e26 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -6297,6 +6297,18 @@
     (set_attr "prefix" "vex")
     (set_attr "mode" "V8SF")])
 
+(define_insn "avx512f_vec_dup_<mode>_1"
+  [(set (match_operand:VF_512 0 "register_operand" "=v")
+	(vec_duplicate:VF_512
+	  (vec_select:<ssescalarmode>
+	    (match_operand:VF_512 1 "register_operand" "v")
+	    (parallel [(const_int 0)]))))]
+  "TARGET_AVX512F"
+  "vbroadcast<bcstscalarsuff>\t{%x1, %0|%0, %x1}"
+  [(set_attr "type" "sselog1")
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "<MODE>")])
+
 (define_insn "vec_dupv4sf"
   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
 	(vec_duplicate:V4SF
@@ -15922,22 +15934,35 @@
 	  (match_operand:VI48_256 2 "nonimmediate_operand")))]
   "TARGET_AVX2")
 
-(define_expand "vashr<mode>3<mask_name>"
-  [(set (match_operand:VI12_128 0 "register_operand")
-	(ashiftrt:VI12_128
-	  (match_operand:VI12_128 1 "register_operand")
-	  (match_operand:VI12_128 2 "nonimmediate_operand")))]
+(define_expand "vashrv8hi3<mask_name>"
+  [(set (match_operand:V8HI 0 "register_operand")
+	(ashiftrt:V8HI
+	  (match_operand:V8HI 1 "register_operand")
+	  (match_operand:V8HI 2 "nonimmediate_operand")))]
   "TARGET_XOP || (TARGET_AVX512BW && TARGET_AVX512VL)"
 {
   if (TARGET_XOP)
     {
-      rtx neg = gen_reg_rtx (<MODE>mode);
-      emit_insn (gen_neg<mode>2 (neg, operands[2]));
-      emit_insn (gen_xop_sha<mode>3 (operands[0], operands[1], neg));
+      rtx neg = gen_reg_rtx (V8HImode);
+      emit_insn (gen_negv8hi2 (neg, operands[2]));
+      emit_insn (gen_xop_shav8hi3 (operands[0], operands[1], neg));
       DONE;
     }
 })
 
+(define_expand "vashrv16qi3"
+  [(set (match_operand:V16QI 0 "register_operand")
+	(ashiftrt:V16QI
+	  (match_operand:V16QI 1 "register_operand")
+	  (match_operand:V16QI 2 "nonimmediate_operand")))]
+  "TARGET_XOP"
+{
+   rtx neg = gen_reg_rtx (V16QImode);
+   emit_insn (gen_negv16qi2 (neg, operands[2]));
+   emit_insn (gen_xop_shav16qi3 (operands[0], operands[1], neg));
+   DONE;
+})
+
 (define_expand "vashrv2di3<mask_name>"
   [(set (match_operand:V2DI 0 "register_operand")
 	(ashiftrt:V2DI
@@ -16531,6 +16556,19 @@
    (set_attr "prefix" "vex")
    (set_attr "mode" "V4DF")])
 
+(define_insn "<avx512>_vec_dup_<mode>_1"
+  [(set (match_operand:VI_AVX512BW 0 "register_operand" "=v,v")
+	(vec_duplicate:VI_AVX512BW
+	  (vec_select:VI_AVX512BW
+	    (match_operand:VI_AVX512BW 1 "nonimmediate_operand" "v,m")
+	    (parallel [(const_int 0)]))))]
+  "TARGET_AVX512F"
+  "vpbroadcast<ssemodesuffix>\t{%1, %0|%0, %<iptr>1}
+   vpbroadcast<ssemodesuffix>\t{%x1, %0|%0, %x1}"
+  [(set_attr "type" "ssemov")
+   (set_attr "prefix" "evex")
+   (set_attr "mode" "<sseinsnmode>")])
+
 (define_insn "<avx512>_vec_dup<mode><mask_name>"
   [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v")
 	(vec_duplicate:V48_AVX512VL
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH AVX512] Fix dg.torture tests with avx512
  2014-10-30 15:08 [PATCH AVX512] Fix dg.torture tests with avx512 Ilya Tocar
@ 2014-10-31 10:32 ` Uros Bizjak
  2014-11-03 10:22   ` Jakub Jelinek
  0 siblings, 1 reply; 4+ messages in thread
From: Uros Bizjak @ 2014-10-31 10:32 UTC (permalink / raw)
  To: Ilya Tocar; +Cc: GCC Patches, Jakub Jelinek

On Thu, Oct 30, 2014 at 3:55 PM, Ilya Tocar <tocarip.intel@gmail.com> wrote:
> Hi,
>
> I've run gcc.dg/torture/* tests with -mavx512bw -mavx512vl -mavx512dq
> flags, and got a bunch of fails (mostly in permutes autogen).
> Patch below fixes them.
> Ok for trunk?
>
> 2014-10-30  Ilya Tocar  <ilya.tocar@intel.com>
>
>         * config/i386/i386.c (expand_vec_perm_pshufb): Try vpermq/vpermd
>         for 512-bit wide modes.
>         (expand_vec_perm_1): Use correct versions of patterns.
>         * config/i386/sse.md (avx512f_vec_dup_<mode>_1): New.
>         (vashr<mode>3<mask_name>): Split V8HImode and V16QImode.

Please name new patterns ..._vec_dup<mode>... , without space between
vec_dup and <mode>.

> ---
>  gcc/config/i386/i386.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------
>  gcc/config/i386/sse.md | 54 ++++++++++++++++++++++++++++++++++++++-------
>  2 files changed, 98 insertions(+), 15 deletions(-)
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 71a4f6a..74ff894 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -45889,6 +45889,42 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
>         {
>           if (!TARGET_AVX512BW)
>             return false;
> +
> +         /* If vpermq didn't work, vpshufb won't work either.  */
> +         if (d->vmode == V8DFmode || d->vmode == V8DImode)
> +           return false;
> +
> +         vmode = V64QImode;
> +         if (d->vmode == V16SImode
> +             || d->vmode == V32HImode
> +             || d->vmode == V64QImode)
> +           {
> +             /* First see if vpermq can be used for
> +                V16SImode/V32HImode/V64QImode.  */
> +             if (valid_perm_using_mode_p (V8DImode, d))
> +               {
> +                 for (i = 0; i < 8; i++)
> +                   perm[i] = (d->perm[i * nelt / 8] * 8 / nelt) & 7;
> +                 if (d->testing_p)
> +                   return true;
> +                 target = gen_reg_rtx (V8DImode);
> +                 if (expand_vselect (target, gen_lowpart (V8DImode, d->op0),
> +                                     perm, 8, false))
> +                   {
> +                     emit_move_insn (d->target,
> +                                     gen_lowpart (d->vmode, target));
> +                     return true;
> +                   }
> +                 return false;
> +               }
> +
> +             /* Next see if vpermd can be used.  */
> +             if (valid_perm_using_mode_p (V16SImode, d))
> +               vmode = V16SImode;
> +           }
> +         /* Or if vpermps can be used.  */
> +         else if (d->vmode == V16SFmode)
> +           vmode = V16SImode;
>           if (vmode == V64QImode)
>             {
>               /* vpshufb only works intra lanes, it is not
> @@ -45908,6 +45944,9 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
>    if (vmode == V8SImode)
>      for (i = 0; i < 8; ++i)
>        rperm[i] = GEN_INT ((d->perm[i * nelt / 8] * 8 / nelt) & 7);
> +  else if (vmode == V16SImode)
> +    for (i = 0; i < 16; ++i)
> +      rperm[i] = GEN_INT ((d->perm[i * nelt / 16] * 16 / nelt) & 15);
>    else
>      {
>        eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));


I'd like to ask Jakub for a review of the above two parts, other parts
are OK with a rename (as mentioned above).

Uros.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH AVX512] Fix dg.torture tests with avx512
  2014-10-31 10:32 ` Uros Bizjak
@ 2014-11-03 10:22   ` Jakub Jelinek
  2014-11-05 15:59     ` Ilya Tocar
  0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2014-11-03 10:22 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: Ilya Tocar, GCC Patches

On Fri, Oct 31, 2014 at 11:17:07AM +0100, Uros Bizjak wrote:
> I'd like to ask Jakub for a review of the above two parts, other parts
> are OK with a rename (as mentioned above).

Looks ok to me.  Where the ICEs discovered just by normal make check or only
with GCC_TEST_RUN_EXPENSIVE ?  If the latter, can you promote one of the
permutations that caused the ICEs to normal tests?  If not and
GCC_TEST_RUN_EXPENSIVE has not been tested, can you try that?

	Jakub

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH AVX512] Fix dg.torture tests with avx512
  2014-11-03 10:22   ` Jakub Jelinek
@ 2014-11-05 15:59     ` Ilya Tocar
  0 siblings, 0 replies; 4+ messages in thread
From: Ilya Tocar @ 2014-11-05 15:59 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Uros Bizjak, GCC Patches

On 03 Nov 11:21, Jakub Jelinek wrote:
> On Fri, Oct 31, 2014 at 11:17:07AM +0100, Uros Bizjak wrote:
> > I'd like to ask Jakub for a review of the above two parts, other parts
> > are OK with a rename (as mentioned above).
> 
> Looks ok to me.  Where the ICEs discovered just by normal make check or only
> with GCC_TEST_RUN_EXPENSIVE ?  If the latter, can you promote one of the
> permutations that caused the ICEs to normal tests?  If not and
> GCC_TEST_RUN_EXPENSIVE has not been tested, can you try that?
>

This was discovered without GCC_TEST_RUN_EXPENSIVE, but I've tested it
with it enabled, and didn't see any fails.

I've committed version below.

---
 gcc/config/i386/i386.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------
 gcc/config/i386/sse.md | 54 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 98 insertions(+), 15 deletions(-)

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c528599..aaffe9d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -45943,6 +45943,42 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
 	{
 	  if (!TARGET_AVX512BW)
 	    return false;
+
+	  /* If vpermq didn't work, vpshufb won't work either.  */
+	  if (d->vmode == V8DFmode || d->vmode == V8DImode)
+	    return false;
+
+	  vmode = V64QImode;
+	  if (d->vmode == V16SImode
+	      || d->vmode == V32HImode
+	      || d->vmode == V64QImode)
+	    {
+	      /* First see if vpermq can be used for
+		 V16SImode/V32HImode/V64QImode.  */
+	      if (valid_perm_using_mode_p (V8DImode, d))
+		{
+		  for (i = 0; i < 8; i++)
+		    perm[i] = (d->perm[i * nelt / 8] * 8 / nelt) & 7;
+		  if (d->testing_p)
+		    return true;
+		  target = gen_reg_rtx (V8DImode);
+		  if (expand_vselect (target, gen_lowpart (V8DImode, d->op0),
+				      perm, 8, false))
+		    {
+		      emit_move_insn (d->target,
+				      gen_lowpart (d->vmode, target));
+		      return true;
+		    }
+		  return false;
+		}
+
+	      /* Next see if vpermd can be used.  */
+	      if (valid_perm_using_mode_p (V16SImode, d))
+		vmode = V16SImode;
+	    }
+	  /* Or if vpermps can be used.  */
+	  else if (d->vmode == V16SFmode)
+	    vmode = V16SImode;
 	  if (vmode == V64QImode)
 	    {
 	      /* vpshufb only works intra lanes, it is not
@@ -45962,6 +45998,9 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
   if (vmode == V8SImode)
     for (i = 0; i < 8; ++i)
       rperm[i] = GEN_INT ((d->perm[i * nelt / 8] * 8 / nelt) & 7);
+  else if (vmode == V16SImode)
+    for (i = 0; i < 16; ++i)
+      rperm[i] = GEN_INT ((d->perm[i * nelt / 16] * 16 / nelt) & 15);
   else
     {
       eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
@@ -46000,8 +46039,14 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
 	emit_insn (gen_avx512bw_pshufbv64qi3 (target, op0, vperm));
       else if (vmode == V8SFmode)
 	emit_insn (gen_avx2_permvarv8sf (target, op0, vperm));
-      else
+      else if (vmode == V8SImode)
 	emit_insn (gen_avx2_permvarv8si (target, op0, vperm));
+      else if (vmode == V16SFmode)
+	emit_insn (gen_avx512f_permvarv16sf (target, op0, vperm));
+      else if (vmode == V16SImode)
+	emit_insn (gen_avx512f_permvarv16si (target, op0, vperm));
+      else
+	gcc_unreachable ();
     }
   else
     {
@@ -46055,21 +46100,21 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
 	    {
 	    case V64QImode:
 	      if (TARGET_AVX512BW)
-		gen = gen_avx512bw_vec_dupv64qi;
+		gen = gen_avx512bw_vec_dupv64qi_1;
 	      break;
 	    case V32QImode:
 	      gen = gen_avx2_pbroadcastv32qi_1;
 	      break;
 	    case V32HImode:
 	      if (TARGET_AVX512BW)
-		gen = gen_avx512bw_vec_dupv32hi;
+		gen = gen_avx512bw_vec_dupv32hi_1;
 	      break;
 	    case V16HImode:
 	      gen = gen_avx2_pbroadcastv16hi_1;
 	      break;
 	    case V16SImode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv16si;
+		gen = gen_avx512f_vec_dupv16si_1;
 	      break;
 	    case V8SImode:
 	      gen = gen_avx2_pbroadcastv8si_1;
@@ -46082,18 +46127,18 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
 	      break;
 	    case V16SFmode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv16sf;
+		gen = gen_avx512f_vec_dupv16sf_1;
 	      break;
 	    case V8SFmode:
 	      gen = gen_avx2_vec_dupv8sf_1;
 	      break;
 	    case V8DFmode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv8df;
+		gen = gen_avx512f_vec_dupv8df_1;
 	      break;
 	    case V8DImode:
 	      if (TARGET_AVX512F)
-		gen = gen_avx512f_vec_dupv8di;
+		gen = gen_avx512f_vec_dupv8di_1;
 	      break;
 	    /* For other modes prefer other shuffles this function creates.  */
 	    default: break;
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 2757a1e..13ddd29 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -6297,6 +6297,18 @@
     (set_attr "prefix" "vex")
     (set_attr "mode" "V8SF")])
 
+(define_insn "avx512f_vec_dup<mode>_1"
+  [(set (match_operand:VF_512 0 "register_operand" "=v")
+	(vec_duplicate:VF_512
+	  (vec_select:<ssescalarmode>
+	    (match_operand:VF_512 1 "register_operand" "v")
+	    (parallel [(const_int 0)]))))]
+  "TARGET_AVX512F"
+  "vbroadcast<bcstscalarsuff>\t{%x1, %0|%0, %x1}"
+  [(set_attr "type" "sselog1")
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "<MODE>")])
+
 (define_insn "vec_dupv4sf"
   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
 	(vec_duplicate:V4SF
@@ -15922,22 +15934,35 @@
 	  (match_operand:VI48_256 2 "nonimmediate_operand")))]
   "TARGET_AVX2")
 
-(define_expand "vashr<mode>3<mask_name>"
-  [(set (match_operand:VI12_128 0 "register_operand")
-	(ashiftrt:VI12_128
-	  (match_operand:VI12_128 1 "register_operand")
-	  (match_operand:VI12_128 2 "nonimmediate_operand")))]
+(define_expand "vashrv8hi3<mask_name>"
+  [(set (match_operand:V8HI 0 "register_operand")
+	(ashiftrt:V8HI
+	  (match_operand:V8HI 1 "register_operand")
+	  (match_operand:V8HI 2 "nonimmediate_operand")))]
   "TARGET_XOP || (TARGET_AVX512BW && TARGET_AVX512VL)"
 {
   if (TARGET_XOP)
     {
-      rtx neg = gen_reg_rtx (<MODE>mode);
-      emit_insn (gen_neg<mode>2 (neg, operands[2]));
-      emit_insn (gen_xop_sha<mode>3 (operands[0], operands[1], neg));
+      rtx neg = gen_reg_rtx (V8HImode);
+      emit_insn (gen_negv8hi2 (neg, operands[2]));
+      emit_insn (gen_xop_shav8hi3 (operands[0], operands[1], neg));
       DONE;
     }
 })
 
+(define_expand "vashrv16qi3"
+  [(set (match_operand:V16QI 0 "register_operand")
+	(ashiftrt:V16QI
+	  (match_operand:V16QI 1 "register_operand")
+	  (match_operand:V16QI 2 "nonimmediate_operand")))]
+  "TARGET_XOP"
+{
+   rtx neg = gen_reg_rtx (V16QImode);
+   emit_insn (gen_negv16qi2 (neg, operands[2]));
+   emit_insn (gen_xop_shav16qi3 (operands[0], operands[1], neg));
+   DONE;
+})
+
 (define_expand "vashrv2di3<mask_name>"
   [(set (match_operand:V2DI 0 "register_operand")
 	(ashiftrt:V2DI
@@ -16531,6 +16556,19 @@
    (set_attr "prefix" "vex")
    (set_attr "mode" "V4DF")])
 
+(define_insn "<avx512>_vec_dup<mode>_1"
+  [(set (match_operand:VI_AVX512BW 0 "register_operand" "=v,v")
+	(vec_duplicate:VI_AVX512BW
+	  (vec_select:VI_AVX512BW
+	    (match_operand:VI_AVX512BW 1 "nonimmediate_operand" "v,m")
+	    (parallel [(const_int 0)]))))]
+  "TARGET_AVX512F"
+  "vpbroadcast<ssemodesuffix>\t{%1, %0|%0, %<iptr>1}
+   vpbroadcast<ssemodesuffix>\t{%x1, %0|%0, %x1}"
+  [(set_attr "type" "ssemov")
+   (set_attr "prefix" "evex")
+   (set_attr "mode" "<sseinsnmode>")])
+
 (define_insn "<avx512>_vec_dup<mode><mask_name>"
   [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v")
 	(vec_duplicate:V48_AVX512VL
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-11-05 15:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-30 15:08 [PATCH AVX512] Fix dg.torture tests with avx512 Ilya Tocar
2014-10-31 10:32 ` Uros Bizjak
2014-11-03 10:22   ` Jakub Jelinek
2014-11-05 15:59     ` Ilya Tocar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).