diff mbox

[i386,AVX512,61/n] Update FP logic insn patterns.

Message ID 20140926123231.GA5256@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Kirill Yukhin Sept. 26, 2014, 12:32 p.m. UTC
Hello,
This patch extends andnot and any_logic insn
patterns.

Bootstrapped.
AVX-512* tests on top of patch-set all pass
under simulator.

Is it ok for trunk?

gcc/
	* config/i386/sse.md
	(define_insn "<sse>_andnot<VF_128_256:mode>3<mask_name>"): Add masking,
	use VF_128_256 mode iterator and update assembler emit code.
	(define_insn "<sse>_andnot<VF_512:mode>3<mask_name>"): New.
	(define_expand "<any_logic:code><VF_128_256:mode>3<mask_name>"):
	Add masking, use VF_128_256 mode iterator.
	(define_expand "<any_logic:code><VF_512:mode>3<mask_name>"): New.
	(define_insn "*<any_logic:code><VF_128_256:mode>3<mask_name>"):
	Add masking, use VF_128_256 mode iterator and update assembler emit
	code.
	(define_insn "*<any_logic:code><VF_512:mode>3<mask_name>"): New.
	(define_mode_attr avx512flogicsuff): Delete.
	(define_insn "avx512f_<logic><mode>"): Ditto.
	(define_insn "*andnot<mode>3<mask_name>"): Update MODE_XI, MODE_OI,
	MODE_TI.
	(define_insn "<mask_codefor><code><mode>3<mask_name>"): Ditto.

--
Thanks, K

Comments

Uros Bizjak Sept. 29, 2014, 8 a.m. UTC | #1
On Fri, Sep 26, 2014 at 2:32 PM, Kirill Yukhin <kirill.yukhin@gmail.com> wrote:
> Hello,
> This patch extends andnot and any_logic insn
> patterns.
>
> Bootstrapped.
> AVX-512* tests on top of patch-set all pass
> under simulator.
>
> Is it ok for trunk?
>
> gcc/
>         * config/i386/sse.md
>         (define_insn "<sse>_andnot<VF_128_256:mode>3<mask_name>"): Add masking,
>         use VF_128_256 mode iterator and update assembler emit code.
>         (define_insn "<sse>_andnot<VF_512:mode>3<mask_name>"): New.
>         (define_expand "<any_logic:code><VF_128_256:mode>3<mask_name>"):
>         Add masking, use VF_128_256 mode iterator.
>         (define_expand "<any_logic:code><VF_512:mode>3<mask_name>"): New.
>         (define_insn "*<any_logic:code><VF_128_256:mode>3<mask_name>"):
>         Add masking, use VF_128_256 mode iterator and update assembler emit
>         code.
>         (define_insn "*<any_logic:code><VF_512:mode>3<mask_name>"): New.
>         (define_mode_attr avx512flogicsuff): Delete.
>         (define_insn "avx512f_<logic><mode>"): Ditto.
>         (define_insn "*andnot<mode>3<mask_name>"): Update MODE_XI, MODE_OI,
>         MODE_TI.
>         (define_insn "<mask_codefor><code><mode>3<mask_name>"): Ditto.
>
> --
> Thanks, K
>
> diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
> index 91d6778..9835234 100644
> --- a/gcc/config/i386/sse.md
> +++ b/gcc/config/i386/sse.md
> @@ -2687,15 +2687,15 @@
>  ;;
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> -(define_insn "<sse>_andnot<mode>3"
> -  [(set (match_operand:VF 0 "register_operand" "=x,v")
> -       (and:VF
> -         (not:VF
> -           (match_operand:VF 1 "register_operand" "0,v"))
> -         (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
> -  "TARGET_SSE"
> +(define_insn "<sse>_andnot<mode>3<mask_name>"
> +  [(set (match_operand:VF_128_256 0 "register_operand" "=x,v")
> +       (and:VF_128_256
> +         (not:VF_128_256
> +           (match_operand:VF_128_256 1 "register_operand" "0,v"))
> +         (match_operand:VF_128_256 2 "nonimmediate_operand" "xm,vm")))]
> +  "TARGET_SSE && <mask_avx512vl_condition>"
>  {
> -  static char buf[32];
> +  static char buf[128];
>    const char *ops;
>    const char *suffix;
>
> @@ -2715,17 +2715,17 @@
>        ops = "andn%s\t{%%2, %%0|%%0, %%2}";
>        break;
>      case 1:
> -      ops = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
> +      ops = "vandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
>        break;
>      default:
>        gcc_unreachable ();
>      }
>
> -  /* There is no vandnp[sd].  Use vpandnq.  */
> -  if (<MODE_SIZE> == 64)
> +  /* There is no vandnp[sd] in avx512f.  Use vpandn[qd].  */
> +  if (<mask_applied> && !TARGET_AVX512DQ)
>      {
> -      suffix = "q";
> -      ops = "vpandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
> +      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
> +      ops = "vpandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
>      }
>
>    snprintf (buf, sizeof (buf), ops, suffix);
> @@ -2745,30 +2745,63 @@
>                ]
>                (const_string "<MODE>")))])
>
> -(define_expand "<code><mode>3"
> +
> +(define_insn "<sse>_andnot<mode>3<mask_name>"
> +  [(set (match_operand:VF_512 0 "register_operand" "=v")
> +       (and:VF_512
> +         (not:VF_512
> +           (match_operand:VF_512 1 "register_operand" "v"))
> +         (match_operand:VF_512 2 "nonimmediate_operand" "vm")))]
> +  "TARGET_AVX512F"
> +{
> +  static char buf[128];
> +  const char *ops;
> +  const char *suffix;
> +
> +  suffix = "<ssemodesuffix>";
> +  ops = "";
> +
> +  /* There is no vandnp[sd] in avx512f.  Use vpandn[qd].  */
> +  if (!TARGET_AVX512DQ)

All other patterns also have "<mask_applied> &&" condition here. Is
the above condition correct?

> +    {
> +      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
> +      ops = "p";
> +    }
> +
> +  snprintf (buf, sizeof (buf),
> +           "v%sandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}",
> +           ops, suffix);
> +  return buf;
> +}
> +  [(set_attr "type" "sselog")
> +   (set_attr "prefix" "evex")
> +   (set_attr "mode" "<sseinsnmode>")])
> +
> +(define_expand "<code><mode>3<mask_name>"
>    [(set (match_operand:VF_128_256 0 "register_operand")
> -       (any_logic:VF_128_256
> -         (match_operand:VF_128_256 1 "nonimmediate_operand")
> -         (match_operand:VF_128_256 2 "nonimmediate_operand")))]
> -  "TARGET_SSE"
> +       (any_logic:VF_128_256
> +         (match_operand:VF_128_256 1 "nonimmediate_operand")
> +         (match_operand:VF_128_256 2 "nonimmediate_operand")))]
> +  "TARGET_SSE && <mask_avx512vl_condition>"
>    "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
>
> -(define_expand "<code><mode>3"
> +(define_expand "<code><mode>3<mask_name>"
>    [(set (match_operand:VF_512 0 "register_operand")
> -       (fpint_logic:VF_512
> +       (any_logic:VF_512
>           (match_operand:VF_512 1 "nonimmediate_operand")
>           (match_operand:VF_512 2 "nonimmediate_operand")))]
>    "TARGET_AVX512F"
>    "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
>
> -(define_insn "*<code><mode>3"
> -  [(set (match_operand:VF 0 "register_operand" "=x,v")
> -       (any_logic:VF
> -         (match_operand:VF 1 "nonimmediate_operand" "%0,v")
> -         (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
> -  "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
> +(define_insn "*<code><mode>3<mask_name>"
> +  [(set (match_operand:VF_128_256 0 "register_operand" "=x,v")
> +       (any_logic:VF_128_256
> +         (match_operand:VF_128_256 1 "nonimmediate_operand" "%0,v")
> +         (match_operand:VF_128_256 2 "nonimmediate_operand" "xm,vm")))]
> +  "TARGET_SSE && <mask_avx512vl_condition>
> +   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
>  {
> -  static char buf[32];
> +  static char buf[128];
>    const char *ops;
>    const char *suffix;
>
> @@ -2788,17 +2821,17 @@
>        ops = "<logic>%s\t{%%2, %%0|%%0, %%2}";
>        break;
>      case 1:
> -      ops = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
> +      ops = "v<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
>        break;
>      default:
>        gcc_unreachable ();
>      }
>
> -  /* There is no v<logic>p[sd].  Use vp<logic>q.  */
> -  if (<MODE_SIZE> == 64)
> +  /* There is no v<logic>p[sd] in avx512f.  Use vp<logic>[dq].  */
> +  if (<mask_applied> && !TARGET_AVX512DQ)
>      {
> -      suffix = "q";
> -      ops = "vp<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
> +      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
> +      ops = "vp<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
>      }
>
>    snprintf (buf, sizeof (buf), ops, suffix);
> @@ -2818,6 +2851,36 @@
>                ]
>                (const_string "<MODE>")))])
>
> +(define_insn "*<code><mode>3<mask_name>"
> +  [(set (match_operand:VF_512 0 "register_operand" "=v")
> +       (any_logic:VF_512
> +         (match_operand:VF_512 1 "nonimmediate_operand" "%v")
> +         (match_operand:VF_512 2 "nonimmediate_operand" "vm")))]
> +  "TARGET_AVX512F && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
> +{
> +  static char buf[128];
> +  const char *ops;
> +  const char *suffix;
> +
> +  suffix = "<ssemodesuffix>";
> +  ops = "";
> +
> +  /* There is no v<logic>p[sd] in avx512f.  Use vp<logic>[dq].  */
> +  if ((<MODE_SIZE> == 64 || <mask_applied>) && !TARGET_AVX512DQ)
> +    {
> +      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
> +      ops = "p";
> +    }
> +
> +  snprintf (buf, sizeof (buf),
> +          "v%s<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}",
> +          ops, suffix);
> +  return buf;
> +}
> +  [(set_attr "type" "sselog")
> +   (set_attr "prefix" "evex")
> +   (set_attr "mode" "<sseinsnmode>")])
> +
>  (define_expand "copysign<mode>3"
>    [(set (match_dup 4)
>         (and:VF
> @@ -3027,23 +3090,6 @@
>                ]
>                (const_string "TI")))])
>
> -;; There are no floating point xor for V16SF and V8DF in avx512f
> -;; but we need them for negation.  Instead we use int versions of
> -;; xor.  Maybe there could be a better way to do that.
> -
> -(define_mode_attr avx512flogicsuff
> -  [(V16SF "d") (V8DF "q")])
> -
> -(define_insn "avx512f_<logic><mode>"
> -  [(set (match_operand:VF_512 0 "register_operand" "=v")
> -       (fpint_logic:VF_512
> -         (match_operand:VF_512 1 "register_operand" "v")
> -         (match_operand:VF_512 2 "nonimmediate_operand" "vm")))]
> -  "TARGET_AVX512F"
> -  "vp<logic><avx512flogicsuff>\t{%2, %1, %0|%0, %1, %2}"
> -  [(set_attr "type" "sselog")
> -   (set_attr "prefix" "evex")])
> -
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>  ;;
>  ;; FMA floating point multiply/accumulate instructions.  These include
> @@ -10674,16 +10720,31 @@
>      {
>      case MODE_XI:
>        gcc_assert (TARGET_AVX512F);
> -
> -      tmp = "pandn<ssemodesuffix>";
> -      break;
> -
>      case MODE_OI:
> -      gcc_assert (TARGET_AVX2);
> +      gcc_assert (TARGET_AVX2 || TARGET_AVX512VL);
>      case MODE_TI:
> -      gcc_assert (TARGET_SSE2);
> -
> -      tmp = "pandn";
> +      gcc_assert (TARGET_SSE2 || TARGET_AVX512VL);
> +      switch (<MODE>mode)
> +      {
> +        case V16SImode:
> +        case V8DImode:
> +          if (TARGET_AVX512F)
> +          {
> +            tmp = "pandn<ssemodesuffix>";
> +            break;
> +          }
> +        case V8SImode:
> +        case V4DImode:
> +        case V4SImode:
> +        case V2DImode:
> +          if (TARGET_AVX512VL)
> +          {
> +            tmp = "pandn<ssemodesuffix>";
> +            break;
> +          }
> +        default:
> +          tmp = TARGET_AVX512VL ? "pandnq" : "pandn";
> +      }
>        break;
>
>     case MODE_V16SF:
> @@ -10798,16 +10859,31 @@
>      {
>      case MODE_XI:
>        gcc_assert (TARGET_AVX512F);
> -
> -      tmp = "p<logic><ssemodesuffix>";
> -      break;
> -
>      case MODE_OI:
> -      gcc_assert (TARGET_AVX2);
> +      gcc_assert (TARGET_AVX2 || TARGET_AVX512VL);
>      case MODE_TI:
> -      gcc_assert (TARGET_SSE2);
> -
> -      tmp = "p<logic>";
> +      gcc_assert (TARGET_SSE2 || TARGET_AVX512VL);
> +      switch (<MODE>mode)
> +      {
> +        case V16SImode:
> +        case V8DImode:
> +          if (TARGET_AVX512F)
> +          {
> +            tmp = "p<logic><ssemodesuffix>";
> +            break;
> +          }
> +        case V8SImode:
> +        case V4DImode:
> +        case V4SImode:
> +        case V2DImode:
> +          if (TARGET_AVX512VL)
> +          {
> +            tmp = "p<logic><ssemodesuffix>";
> +            break;
> +          }
> +        default:
> +          tmp = TARGET_AVX512VL ? "p<logic>q" : "p<logic>";
> +      }
>        break;
>
>     case MODE_V16SF:
Kirill Yukhin Oct. 3, 2014, 10:49 a.m. UTC | #2
Hello Uroš,
On 29 Sep 10:00, Uros Bizjak wrote:
> > +  /* There is no vandnp[sd] in avx512f.  Use vpandn[qd].  */
> > +  if (!TARGET_AVX512DQ)
> 
> All other patterns also have "<mask_applied> &&" condition here. Is
> the above condition correct?
I think this is correct since in this pattern we use AVX-512 only modes
in iterator, so no chance to emit anything else but EVEX insn.
In say, previous pattern we use modes are enabled for previous ISA extensions,
so we emit this hack when masking (AVX-512 specific feature) is used.

--
Thanks, K
Uros Bizjak Oct. 3, 2014, 11:05 a.m. UTC | #3
On Fri, Oct 3, 2014 at 12:49 PM, Kirill Yukhin <kirill.yukhin@gmail.com> wrote:
> Hello Uroš,
> On 29 Sep 10:00, Uros Bizjak wrote:
>> > +  /* There is no vandnp[sd] in avx512f.  Use vpandn[qd].  */
>> > +  if (!TARGET_AVX512DQ)
>>
>> All other patterns also have "<mask_applied> &&" condition here. Is
>> the above condition correct?
> I think this is correct since in this pattern we use AVX-512 only modes
> in iterator, so no chance to emit anything else but EVEX insn.
> In say, previous pattern we use modes are enabled for previous ISA extensions,
> so we emit this hack when masking (AVX-512 specific feature) is used.

Thanks for the explanation, the patch is OK.

Thanks,
Uros.
diff mbox

Patch

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 91d6778..9835234 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -2687,15 +2687,15 @@ 
 ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(define_insn "<sse>_andnot<mode>3"
-  [(set (match_operand:VF 0 "register_operand" "=x,v")
-	(and:VF
-	  (not:VF
-	    (match_operand:VF 1 "register_operand" "0,v"))
-	  (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
-  "TARGET_SSE"
+(define_insn "<sse>_andnot<mode>3<mask_name>"
+  [(set (match_operand:VF_128_256 0 "register_operand" "=x,v")
+	(and:VF_128_256
+	  (not:VF_128_256
+	    (match_operand:VF_128_256 1 "register_operand" "0,v"))
+	  (match_operand:VF_128_256 2 "nonimmediate_operand" "xm,vm")))]
+  "TARGET_SSE && <mask_avx512vl_condition>"
 {
-  static char buf[32];
+  static char buf[128];
   const char *ops;
   const char *suffix;
 
@@ -2715,17 +2715,17 @@ 
       ops = "andn%s\t{%%2, %%0|%%0, %%2}";
       break;
     case 1:
-      ops = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+      ops = "vandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
       break;
     default:
       gcc_unreachable ();
     }
 
-  /* There is no vandnp[sd].  Use vpandnq.  */
-  if (<MODE_SIZE> == 64)
+  /* There is no vandnp[sd] in avx512f.  Use vpandn[qd].  */
+  if (<mask_applied> && !TARGET_AVX512DQ)
     {
-      suffix = "q";
-      ops = "vpandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
+      ops = "vpandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
     }
 
   snprintf (buf, sizeof (buf), ops, suffix);
@@ -2745,30 +2745,63 @@ 
 	       ]
 	       (const_string "<MODE>")))])
 
-(define_expand "<code><mode>3"
+
+(define_insn "<sse>_andnot<mode>3<mask_name>"
+  [(set (match_operand:VF_512 0 "register_operand" "=v")
+	(and:VF_512
+	  (not:VF_512
+	    (match_operand:VF_512 1 "register_operand" "v"))
+	  (match_operand:VF_512 2 "nonimmediate_operand" "vm")))]
+  "TARGET_AVX512F"
+{
+  static char buf[128];
+  const char *ops;
+  const char *suffix;
+
+  suffix = "<ssemodesuffix>";
+  ops = "";
+
+  /* There is no vandnp[sd] in avx512f.  Use vpandn[qd].  */
+  if (!TARGET_AVX512DQ)
+    {
+      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
+      ops = "p";
+    }
+
+  snprintf (buf, sizeof (buf),
+	    "v%sandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}",
+	    ops, suffix);
+  return buf;
+}
+  [(set_attr "type" "sselog")
+   (set_attr "prefix" "evex")
+   (set_attr "mode" "<sseinsnmode>")])
+
+(define_expand "<code><mode>3<mask_name>"
   [(set (match_operand:VF_128_256 0 "register_operand")
-	(any_logic:VF_128_256
-	  (match_operand:VF_128_256 1 "nonimmediate_operand")
-	  (match_operand:VF_128_256 2 "nonimmediate_operand")))]
-  "TARGET_SSE"
+       (any_logic:VF_128_256
+         (match_operand:VF_128_256 1 "nonimmediate_operand")
+         (match_operand:VF_128_256 2 "nonimmediate_operand")))]
+  "TARGET_SSE && <mask_avx512vl_condition>"
   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
 
-(define_expand "<code><mode>3"
+(define_expand "<code><mode>3<mask_name>"
   [(set (match_operand:VF_512 0 "register_operand")
-       (fpint_logic:VF_512
+       (any_logic:VF_512
          (match_operand:VF_512 1 "nonimmediate_operand")
          (match_operand:VF_512 2 "nonimmediate_operand")))]
   "TARGET_AVX512F"
   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
 
-(define_insn "*<code><mode>3"
-  [(set (match_operand:VF 0 "register_operand" "=x,v")
-	(any_logic:VF
-	  (match_operand:VF 1 "nonimmediate_operand" "%0,v")
-	  (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
-  "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+(define_insn "*<code><mode>3<mask_name>"
+  [(set (match_operand:VF_128_256 0 "register_operand" "=x,v")
+	(any_logic:VF_128_256
+	  (match_operand:VF_128_256 1 "nonimmediate_operand" "%0,v")
+	  (match_operand:VF_128_256 2 "nonimmediate_operand" "xm,vm")))]
+  "TARGET_SSE && <mask_avx512vl_condition>
+   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
 {
-  static char buf[32];
+  static char buf[128];
   const char *ops;
   const char *suffix;
 
@@ -2788,17 +2821,17 @@ 
       ops = "<logic>%s\t{%%2, %%0|%%0, %%2}";
       break;
     case 1:
-      ops = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+      ops = "v<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
       break;
     default:
       gcc_unreachable ();
     }
 
-  /* There is no v<logic>p[sd].  Use vp<logic>q.  */
-  if (<MODE_SIZE> == 64)
+  /* There is no v<logic>p[sd] in avx512f.  Use vp<logic>[dq].  */
+  if (<mask_applied> && !TARGET_AVX512DQ)
     {
-      suffix = "q";
-      ops = "vp<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
+      ops = "vp<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
     }
 
   snprintf (buf, sizeof (buf), ops, suffix);
@@ -2818,6 +2851,36 @@ 
 	       ]
 	       (const_string "<MODE>")))])
 
+(define_insn "*<code><mode>3<mask_name>"
+  [(set (match_operand:VF_512 0 "register_operand" "=v")
+	(any_logic:VF_512
+	  (match_operand:VF_512 1 "nonimmediate_operand" "%v")
+	  (match_operand:VF_512 2 "nonimmediate_operand" "vm")))]
+  "TARGET_AVX512F && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+{
+  static char buf[128];
+  const char *ops;
+  const char *suffix;
+
+  suffix = "<ssemodesuffix>";
+  ops = "";
+
+  /* There is no v<logic>p[sd] in avx512f.  Use vp<logic>[dq].  */
+  if ((<MODE_SIZE> == 64 || <mask_applied>) && !TARGET_AVX512DQ)
+    {
+      suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
+      ops = "p";
+    }
+
+  snprintf (buf, sizeof (buf),
+	   "v%s<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}",
+	   ops, suffix);
+  return buf;
+}
+  [(set_attr "type" "sselog")
+   (set_attr "prefix" "evex")
+   (set_attr "mode" "<sseinsnmode>")])
+
 (define_expand "copysign<mode>3"
   [(set (match_dup 4)
 	(and:VF
@@ -3027,23 +3090,6 @@ 
 	       ]
 	       (const_string "TI")))])
 
-;; There are no floating point xor for V16SF and V8DF in avx512f
-;; but we need them for negation.  Instead we use int versions of
-;; xor.  Maybe there could be a better way to do that.
-
-(define_mode_attr avx512flogicsuff
-  [(V16SF "d") (V8DF "q")])
-
-(define_insn "avx512f_<logic><mode>"
-  [(set (match_operand:VF_512 0 "register_operand" "=v")
-	(fpint_logic:VF_512
-	  (match_operand:VF_512 1 "register_operand" "v")
-	  (match_operand:VF_512 2 "nonimmediate_operand" "vm")))]
-  "TARGET_AVX512F"
-  "vp<logic><avx512flogicsuff>\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "prefix" "evex")])
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
 ;; FMA floating point multiply/accumulate instructions.  These include
@@ -10674,16 +10720,31 @@ 
     {
     case MODE_XI:
       gcc_assert (TARGET_AVX512F);
-
-      tmp = "pandn<ssemodesuffix>";
-      break;
-
     case MODE_OI:
-      gcc_assert (TARGET_AVX2);
+      gcc_assert (TARGET_AVX2 || TARGET_AVX512VL);
     case MODE_TI:
-      gcc_assert (TARGET_SSE2);
-
-      tmp = "pandn";
+      gcc_assert (TARGET_SSE2 || TARGET_AVX512VL);
+      switch (<MODE>mode)
+      {
+        case V16SImode:
+        case V8DImode:
+          if (TARGET_AVX512F)
+          {
+            tmp = "pandn<ssemodesuffix>";
+            break;
+          }
+        case V8SImode:
+        case V4DImode:
+        case V4SImode:
+        case V2DImode:
+          if (TARGET_AVX512VL)
+          {
+            tmp = "pandn<ssemodesuffix>";
+            break;
+          }
+        default:
+          tmp = TARGET_AVX512VL ? "pandnq" : "pandn";
+      }
       break;
 
    case MODE_V16SF:
@@ -10798,16 +10859,31 @@ 
     {
     case MODE_XI:
       gcc_assert (TARGET_AVX512F);
-
-      tmp = "p<logic><ssemodesuffix>";
-      break;
-
     case MODE_OI:
-      gcc_assert (TARGET_AVX2);
+      gcc_assert (TARGET_AVX2 || TARGET_AVX512VL);
     case MODE_TI:
-      gcc_assert (TARGET_SSE2);
-
-      tmp = "p<logic>";
+      gcc_assert (TARGET_SSE2 || TARGET_AVX512VL);
+      switch (<MODE>mode)
+      {
+        case V16SImode:
+        case V8DImode:
+          if (TARGET_AVX512F)
+          {
+            tmp = "p<logic><ssemodesuffix>";
+            break;
+          }
+        case V8SImode:
+        case V4DImode:
+        case V4SImode:
+        case V2DImode:
+          if (TARGET_AVX512VL)
+          {
+            tmp = "p<logic><ssemodesuffix>";
+            break;
+          }
+        default:
+          tmp = TARGET_AVX512VL ? "p<logic>q" : "p<logic>";
+      }
       break;
 
    case MODE_V16SF: