diff mbox series

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

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

Commit Message

Kong, Lingling May 29, 2024, 5:10 a.m. UTC
gcc/ChangeLog:

	* config/i386/i386.md (nf_nonf_attr): New subst_attr.
	(nf_nonf_x64_attr): 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                | 173 +++++++++++++------------
 gcc/config/i386/sse.md                 |  11 ++
 gcc/testsuite/gcc.target/i386/apx-nf.c |  12 ++
 3 files changed, 114 insertions(+), 82 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/apx-nf.c
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1eeadaddeba..d3cb224abad 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)))
 
@@ -6449,6 +6450,8 @@ 
 (define_subst_attr "nf_condition" "nf_subst" "TARGET_APX_NF" "true")
 (define_subst_attr "nf_mem_constraint" "nf_subst" "je" "m")
 (define_subst_attr "nf_applied" "nf_subst" "true" "false")
+(define_subst_attr "nf_nonf_attr" "nf_subst"  "noapx_nf" "*")
+(define_subst_attr "nf_nonf_x64_attr" "nf_subst" "noapx_nf" "x64")
 
 (define_subst "nf_subst"
   [(set (match_operand:SWI 0)
@@ -7893,20 +7896,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 +11799,28 @@ 
 }
 [(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_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_nonf_x64_attr>,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 +11828,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 +11899,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_nonf_attr>")
+	       (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 +11934,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 +12810,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 +12972,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 +13543,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 0f4fbcb2c5d..cdf11a68bc5 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -1986,6 +1986,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
new file mode 100644
index 00000000000..f33a994f0b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/apx-nf.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapx-features=egpr,push2pop2,ndd,ppx,nf -march=x86-64 -O2" } */
+/* { dg-final { scan-assembler-times "\{nf\} and" 1 } } */
+/* { dg-final { scan-assembler-times "\{nf\} or" 1 } } */
+
+struct B { unsigned bit0 : 1; unsigned bit1 : 1; };
+
+void
+foo (struct B *b)
+{
+    b->bit0 = b->bit0 | b->bit1;
+}