diff mbox series

[v2,2/8,APX,NF] Support APX NF for {sub/and/or/xor/neg}

Message ID BN9PR11MB5483210ADDA6593A03C74A83ECEB2@BN9PR11MB5483.namprd11.prod.outlook.com
State New
Headers show
Series [v2,1/8,APX,NF] : Support APX NF add | expand

Commit Message

Kong, Lingling May 22, 2024, 8:35 a.m. UTC
gcc/ChangeLog:

               * config/i386/i386.md (nf_and_applied): New subst_attr.
               (nf_x64_and_applied): Ditto.
               (*sub<mode>_1_nf): New define_insn.
               (*anddi_1_nf): Ditto.
               (*and<mode>_1_nf): Ditto.
               (*<code>qi_1_nf): Ditto.
               (*<code><mode>_1_nf): Ditto.
               (*neg<mode>_1_nf): Ditto.
               * config/i386/sse.md : New define_split.

gcc/testsuite/ChangeLog:

               * gcc.target/i386/apx-nf.c: Add test.
---
gcc/config/i386/i386.md                | 174 +++++++++++++------------
gcc/config/i386/sse.md                 |  11 ++
gcc/testsuite/gcc.target/i386/apx-nf.c |   9 ++
3 files changed, 112 insertions(+), 82 deletions(-)

Comments

Kong, Lingling May 22, 2024, 8:55 a.m. UTC | #1
Cc Uros.

From: Kong, Lingling <lingling.kong@intel.com>
Sent: Wednesday, May 22, 2024 4:35 PM
To: gcc-patches@gcc.gnu.org
Cc: Liu, Hongtao <hongtao.liu@intel.com>; Kong, Lingling <lingling.kong@intel.com>
Subject: [PATCH v2 2/8] [APX NF] Support APX NF for {sub/and/or/xor/neg}

gcc/ChangeLog:

               * config/i386/i386.md (nf_and_applied): New subst_attr.
               (nf_x64_and_applied): Ditto.
               (*sub<mode>_1_nf): New define_insn.
               (*anddi_1_nf): Ditto.
               (*and<mode>_1_nf): Ditto.
               (*<code>qi_1_nf): Ditto.
               (*<code><mode>_1_nf): Ditto.
               (*neg<mode>_1_nf): Ditto.
               * config/i386/sse.md : New define_split.

gcc/testsuite/ChangeLog:

               * gcc.target/i386/apx-nf.c: Add test.
---
gcc/config/i386/i386.md                | 174 +++++++++++++------------
gcc/config/i386/sse.md                 |  11 ++
gcc/testsuite/gcc.target/i386/apx-nf.c |   9 ++
3 files changed, 112 insertions(+), 82 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index bae344518bd..099d7f35c8f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -575,7 +575,7 @@
                                 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
                                 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
                                 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl,
-                                 vaes_avx512vl"
+                                vaes_avx512vl,noapx_nf"
   (const_string "base"))

 ;; The (bounding maximum) length of an instruction immediate.
@@ -981,6 +981,7 @@
                 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
               (eq_attr "mmx_isa" "avx")
                 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
+             (eq_attr "isa" "noapx_nf") (symbol_ref "!TARGET_APX_NF")
              ]
              (const_int 1)))

@@ -7893,20 +7894,21 @@
   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])

-(define_insn "*sub<mode>_1"
-  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
+(define_insn "*sub<mode>_1<nf_name>"
+  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r<nf_mem_constraint>,<r>,r,r,r")
              (minus:SWI
-                (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,rjM,r")
-                (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+               (match_operand:SWI 1 "nonimmediate_operand" "0,0,0,rm,rjM,r")
+               (match_operand:SWI 2 "<general_operand>" "<r>,<i>,<m>,r,<i>,<m>")))]
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
+  && <nf_condition>"
   "@
-  sub{<imodesuffix>}\t{%2, %0|%0, %2}
-  sub{<imodesuffix>}\t{%2, %0|%0, %2}
-  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
    (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])

@@ -11795,27 +11797,31 @@
}
[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])

-(define_insn "*anddi_1"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,r,?k")
+(define_subst_attr "nf_and_applied" "nf_subst"  "noapx_nf" "*")
+(define_subst_attr "nf_x64_and_applied" "nf_subst" "noapx_nf" "x64")
+
+(define_insn "*anddi_1<nf_name>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r<nf_mem_constraint>,r,r,r,r,r,?k")
              (and:DI
-              (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,rjM,r,qm,k")
-              (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,r,e,m,L,k")))
-   (clobber (reg:CC FLAGS_REG))]
+             (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,0,rm,rjM,r,qm,k")
+             (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,r,e,m,r,e,m,L,k")))]
   "TARGET_64BIT
-   && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
+   && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   and{l}\t{%k2, %k0|%k0, %k2}
-   and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
-   and{q}\t{%2, %0|%0, %2}
-   and{q}\t{%2, %0|%0, %2}
-   and{q}\t{%2, %1, %0|%0, %1, %2}
-   and{q}\t{%2, %1, %0|%0, %1, %2}
-   and{q}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
+   <nf_prefix>and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
+   <nf_prefix>and{q}\t{%2, %0|%0, %2}
+   <nf_prefix>and{q}\t{%2, %0|%0, %2}
+   <nf_prefix>and{q}\t{%2, %0|%0, %2}
+   <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
    #
    #"
-  [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,apx_ndd,x64,avx512bw")
-   (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
-   (set_attr "length_immediate" "*,*,*,*,*,*,*,0,*")
+  [(set_attr "isa" "x64,apx_ndd,x64,x64,x64,apx_ndd,apx_ndd,apx_ndd,<nf_x64_and_applied>,avx512bw")
+   (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
+   (set_attr "length_immediate" "*,*,*,*,*,*,*,*,0,*")
    (set (attr "prefix_rex")
      (if_then_else
        (and (eq_attr "type" "imovx")
@@ -11823,7 +11829,7 @@
                              (match_operand 1 "ext_QIreg_operand")))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,SI,DI")])
+   (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,DI,SI,DI")])

 (define_insn_and_split "*anddi_1_btr"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
@@ -11894,31 +11900,34 @@
    (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
    (set_attr "mode" "SI")])

-(define_insn "*and<mode>_1"
-  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,r,Ya,?k")
-              (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,rjM,r,qm,k")
-                                (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,L,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
+(define_insn "*and<mode>_1<nf_name>"
+  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,Ya,?k")
+             (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,qm,k")
+                               (match_operand:SWI24 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,L,k")))]
+  "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   and{<imodesuffix>}\t{%2, %0|%0, %2}
-   and{<imodesuffix>}\t{%2, %0|%0, %2}
-   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
    #
    #"
   [(set (attr "isa")
-              (cond [(eq_attr "alternative" "2,3,4")
+             (cond [(eq_attr "alternative" "3,4,5")
                              (const_string "apx_ndd")
                     (eq_attr "alternative" "6")
+                            (const_string "<nf_and_applied>")
+                    (eq_attr "alternative" "7")
                              (if_then_else (eq_attr "mode" "SI")
                                (const_string "avx512bw")
                                (const_string "avx512f"))
                    ]
                    (const_string "*")))
-   (set_attr "type" "alu,alu,alu,alu,alu,imovx,msklog")
-   (set_attr "length_immediate" "*,*,*,*,*,0,*")
+   (set_attr "type" "alu,alu,alu,alu,alu,alu,imovx,msklog")
+   (set_attr "length_immediate" "*,*,*,*,*,*,0,*")
    (set (attr "prefix_rex")
      (if_then_else
        (and (eq_attr "type" "imovx")
@@ -11926,20 +11935,20 @@
                              (match_operand 1 "ext_QIreg_operand")))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
+   (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])

-(define_insn "*andqi_1"
+(define_insn "*andqi_1<nf_name>"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
              (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
-                             (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)"
+                            (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
+  "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   and{b}\t{%2, %0|%0, %2}
-   and{b}\t{%2, %0|%0, %2}
-   and{l}\t{%k2, %k0|%k0, %k2}
-   and{b}\t{%2, %1, %0|%0, %1, %2}
-   and{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{b}\t{%2, %0|%0, %2}
+   <nf_prefix>and{b}\t{%2, %0|%0, %2}
+   <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
+   <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
    #"
   [(set_attr "type" "alu,alu,alu,alu,alu,msklog")
    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,*")
@@ -12802,22 +12811,23 @@
}
[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])

-(define_insn "*<code><mode>_1"
-  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,r,?k")
+(define_insn "*<code><mode>_1<nf_name>"
+  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,?k")
              (any_or:SWI248
-              (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,rjM,r,k")
-              (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
+             (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,k")
+             (match_operand:SWI248 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,k")))]
+  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
-   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
-   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
    #"
-  [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
-   (set_attr "type" "alu, alu, alu, alu, alu, msklog")
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
+   (set_attr "type" "alu,alu, alu, alu, alu, alu, msklog")
    (set_attr "mode" "<MODE>")])

 (define_insn_and_split "*notxor<mode>_1"
@@ -12963,18 +12973,18 @@
    (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "SI")])

-(define_insn "*<code>qi_1"
+(define_insn "*<code>qi_1<nf_name>"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
              (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
-                                (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)"
+                               (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
+  "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   <logic>{b}\t{%2, %0|%0, %2}
-   <logic>{b}\t{%2, %0|%0, %2}
-   <logic>{l}\t{%k2, %k0|%k0, %k2}
-   <logic>{b}\t{%2, %1, %0|%0, %1, %2}
-   <logic>{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{l}\t{%k2, %k0|%k0, %k2}
+   <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
    #"
   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
    (set_attr "type" "alu,alu,alu,alu,alu,msklog")
@@ -13534,14 +13544,14 @@
                                                  (const_int 0)))
      (clobber (reg:CC FLAGS_REG))])])

-(define_insn "*neg<mode>_1"
+(define_insn "*neg<mode>_1<nf_name>"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
-              (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
+             (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))]
+  "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-  neg{<imodesuffix>}\t%0
-  neg{<imodesuffix>}\t{%1, %0|%0, %1}"
+  <nf_prefix>neg{<imodesuffix>}\t%0
+  <nf_prefix>neg{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "negnot")
    (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "<MODE>")])
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index f57f36ae380..72d4556f47d 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -2005,6 +2005,17 @@
                 ]
                 (const_string "<MODE>")))])

+(define_split
+  [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand")
+             (any_logic:SWI1248_AVX512BW
+               (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand")
+               (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand")))]
+  "TARGET_AVX512F && reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+                (any_logic:SWI1248_AVX512BW (match_dup 1) (match_dup 2)))
+      (unspec [(const_int 0)] UNSPEC_MASKOP)])])
+
(define_split
   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand")
              (any_logic:SWI1248_AVX512BW
diff --git a/gcc/testsuite/gcc.target/i386/apx-nf.c b/gcc/testsuite/gcc.target/i386/apx-nf.c
index 3adc7a27902..608dbf8f5f7 100644
--- a/gcc/testsuite/gcc.target/i386/apx-nf.c
+++ b/gcc/testsuite/gcc.target/i386/apx-nf.c
@@ -1,6 +1,15 @@
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-mapx-features=egpr,push2pop2,ndd,ppx,nf -march=x86-64 -O2" } */
/* { dg-final { scan-assembler-times "\{nf\} add" 4 } } */
+/* { dg-final { scan-assembler-times "\{nf\} and" 1 } } */
+/* { dg-final { scan-assembler-times "\{nf\} or" 1 } } */

 #include "apx-ndd.c"

+struct B { unsigned bit0 : 1; unsigned bit1 : 1; };
+
+void
+foo (struct B *b)
+{
+    b->bit0 = b->bit0 | b->bit1;
+}
--
2.31.1
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index bae344518bd..099d7f35c8f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -575,7 +575,7 @@ 
                                 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
                                 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
                                 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl,
-                                 vaes_avx512vl"
+                                vaes_avx512vl,noapx_nf"
   (const_string "base"))
 ;; The (bounding maximum) length of an instruction immediate.
@@ -981,6 +981,7 @@ 
                 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
               (eq_attr "mmx_isa" "avx")
                 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
+             (eq_attr "isa" "noapx_nf") (symbol_ref "!TARGET_APX_NF")
              ]
              (const_int 1)))
@@ -7893,20 +7894,21 @@ 
   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
-(define_insn "*sub<mode>_1"
-  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
+(define_insn "*sub<mode>_1<nf_name>"
+  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r<nf_mem_constraint>,<r>,r,r,r")
              (minus:SWI
-                (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,rjM,r")
-                (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+               (match_operand:SWI 1 "nonimmediate_operand" "0,0,0,rm,rjM,r")
+               (match_operand:SWI 2 "<general_operand>" "<r>,<i>,<m>,r,<i>,<m>")))]
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
+  && <nf_condition>"
   "@
-  sub{<imodesuffix>}\t{%2, %0|%0, %2}
-  sub{<imodesuffix>}\t{%2, %0|%0, %2}
-  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
    (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
@@ -11795,27 +11797,31 @@ 
}
[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
-(define_insn "*anddi_1"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,r,?k")
+(define_subst_attr "nf_and_applied" "nf_subst"  "noapx_nf" "*")
+(define_subst_attr "nf_x64_and_applied" "nf_subst" "noapx_nf" "x64")
+
+(define_insn "*anddi_1<nf_name>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r<nf_mem_constraint>,r,r,r,r,r,?k")
              (and:DI
-              (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,rjM,r,qm,k")
-              (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,r,e,m,L,k")))
-   (clobber (reg:CC FLAGS_REG))]
+             (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,0,rm,rjM,r,qm,k")
+             (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,r,e,m,r,e,m,L,k")))]
   "TARGET_64BIT
-   && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
+   && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   and{l}\t{%k2, %k0|%k0, %k2}
-   and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
-   and{q}\t{%2, %0|%0, %2}
-   and{q}\t{%2, %0|%0, %2}
-   and{q}\t{%2, %1, %0|%0, %1, %2}
-   and{q}\t{%2, %1, %0|%0, %1, %2}
-   and{q}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
+   <nf_prefix>and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
+   <nf_prefix>and{q}\t{%2, %0|%0, %2}
+   <nf_prefix>and{q}\t{%2, %0|%0, %2}
+   <nf_prefix>and{q}\t{%2, %0|%0, %2}
+   <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
    #
    #"
-  [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,apx_ndd,x64,avx512bw")
-   (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
-   (set_attr "length_immediate" "*,*,*,*,*,*,*,0,*")
+  [(set_attr "isa" "x64,apx_ndd,x64,x64,x64,apx_ndd,apx_ndd,apx_ndd,<nf_x64_and_applied>,avx512bw")
+   (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
+   (set_attr "length_immediate" "*,*,*,*,*,*,*,*,0,*")
    (set (attr "prefix_rex")
      (if_then_else
        (and (eq_attr "type" "imovx")
@@ -11823,7 +11829,7 @@ 
                              (match_operand 1 "ext_QIreg_operand")))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,SI,DI")])
+   (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,DI,SI,DI")])
 (define_insn_and_split "*anddi_1_btr"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
@@ -11894,31 +11900,34 @@ 
    (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
    (set_attr "mode" "SI")])
-(define_insn "*and<mode>_1"
-  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,r,Ya,?k")
-              (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,rjM,r,qm,k")
-                                (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,L,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
+(define_insn "*and<mode>_1<nf_name>"
+  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,Ya,?k")
+             (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,qm,k")
+                               (match_operand:SWI24 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,L,k")))]
+  "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   and{<imodesuffix>}\t{%2, %0|%0, %2}
-   and{<imodesuffix>}\t{%2, %0|%0, %2}
-   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
    #
    #"
   [(set (attr "isa")
-              (cond [(eq_attr "alternative" "2,3,4")
+             (cond [(eq_attr "alternative" "3,4,5")
                              (const_string "apx_ndd")
                     (eq_attr "alternative" "6")
+                            (const_string "<nf_and_applied>")
+                    (eq_attr "alternative" "7")
                              (if_then_else (eq_attr "mode" "SI")
                                (const_string "avx512bw")
                                (const_string "avx512f"))
                    ]
                    (const_string "*")))
-   (set_attr "type" "alu,alu,alu,alu,alu,imovx,msklog")
-   (set_attr "length_immediate" "*,*,*,*,*,0,*")
+   (set_attr "type" "alu,alu,alu,alu,alu,alu,imovx,msklog")
+   (set_attr "length_immediate" "*,*,*,*,*,*,0,*")
    (set (attr "prefix_rex")
      (if_then_else
        (and (eq_attr "type" "imovx")
@@ -11926,20 +11935,20 @@ 
                              (match_operand 1 "ext_QIreg_operand")))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
+   (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
-(define_insn "*andqi_1"
+(define_insn "*andqi_1<nf_name>"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
              (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
-                             (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)"
+                            (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
+  "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   and{b}\t{%2, %0|%0, %2}
-   and{b}\t{%2, %0|%0, %2}
-   and{l}\t{%k2, %k0|%k0, %k2}
-   and{b}\t{%2, %1, %0|%0, %1, %2}
-   and{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{b}\t{%2, %0|%0, %2}
+   <nf_prefix>and{b}\t{%2, %0|%0, %2}
+   <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
+   <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
    #"
   [(set_attr "type" "alu,alu,alu,alu,alu,msklog")
    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,*")
@@ -12802,22 +12811,23 @@ 
}
[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
-(define_insn "*<code><mode>_1"
-  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,r,?k")
+(define_insn "*<code><mode>_1<nf_name>"
+  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,?k")
              (any_or:SWI248
-              (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,rjM,r,k")
-              (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
+             (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,k")
+             (match_operand:SWI248 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,k")))]
+  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
-   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
-   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
-   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
    #"
-  [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
-   (set_attr "type" "alu, alu, alu, alu, alu, msklog")
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
+   (set_attr "type" "alu,alu, alu, alu, alu, alu, msklog")
    (set_attr "mode" "<MODE>")])
 (define_insn_and_split "*notxor<mode>_1"
@@ -12963,18 +12973,18 @@ 
    (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "SI")])
-(define_insn "*<code>qi_1"
+(define_insn "*<code>qi_1<nf_name>"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
              (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
-                                (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)"
+                               (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
+  "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-   <logic>{b}\t{%2, %0|%0, %2}
-   <logic>{b}\t{%2, %0|%0, %2}
-   <logic>{l}\t{%k2, %k0|%k0, %k2}
-   <logic>{b}\t{%2, %1, %0|%0, %1, %2}
-   <logic>{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
+   <nf_prefix><logic>{l}\t{%k2, %k0|%k0, %k2}
+   <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
+   <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
    #"
   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
    (set_attr "type" "alu,alu,alu,alu,alu,msklog")
@@ -13534,14 +13544,14 @@ 
                                                  (const_int 0)))
      (clobber (reg:CC FLAGS_REG))])])
-(define_insn "*neg<mode>_1"
+(define_insn "*neg<mode>_1<nf_name>"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
-              (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
+             (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))]
+  "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)
+   && <nf_condition>"
   "@
-  neg{<imodesuffix>}\t%0
-  neg{<imodesuffix>}\t{%1, %0|%0, %1}"
+  <nf_prefix>neg{<imodesuffix>}\t%0
+  <nf_prefix>neg{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "negnot")
    (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "<MODE>")])
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index f57f36ae380..72d4556f47d 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -2005,6 +2005,17 @@ 
                 ]
                 (const_string "<MODE>")))])
+(define_split
+  [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand")
+             (any_logic:SWI1248_AVX512BW
+               (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand")
+               (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand")))]
+  "TARGET_AVX512F && reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+                (any_logic:SWI1248_AVX512BW (match_dup 1) (match_dup 2)))
+      (unspec [(const_int 0)] UNSPEC_MASKOP)])])
+
(define_split
   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand")
              (any_logic:SWI1248_AVX512BW
diff --git a/gcc/testsuite/gcc.target/i386/apx-nf.c b/gcc/testsuite/gcc.target/i386/apx-nf.c
index 3adc7a27902..608dbf8f5f7 100644
--- a/gcc/testsuite/gcc.target/i386/apx-nf.c
+++ b/gcc/testsuite/gcc.target/i386/apx-nf.c
@@ -1,6 +1,15 @@ 
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-mapx-features=egpr,push2pop2,ndd,ppx,nf -march=x86-64 -O2" } */
/* { dg-final { scan-assembler-times "\{nf\} add" 4 } } */
+/* { dg-final { scan-assembler-times "\{nf\} and" 1 } } */
+/* { dg-final { scan-assembler-times "\{nf\} or" 1 } } */
 #include "apx-ndd.c"
+struct B { unsigned bit0 : 1; unsigned bit1 : 1; };
+
+void
+foo (struct B *b)
+{
+    b->bit0 = b->bit0 | b->bit1;
+}
--
2.31.1