[AARCH64,SVE] Add extract_last for mask/predicates mode register

Message ID 153133c9-4e28-8cfc-9eb7-38568ffed7ab@foss.arm.com
State New
Headers show
Series
  • [AARCH64,SVE] Add extract_last for mask/predicates mode register
Related show

Commit Message

Renlin Li Nov. 8, 2018, 5:03 p.m.
Hi all,

As a follow up patch described here: https://gcc.gnu.org/ml/gcc-patches/2018-10/msg02016.html

Mask/predicate type of data could be used as general data.

In sve ISA, we don't have operations which could directly extract element from a
predicate. The default code-gen for such use is in-efficient, it use
memory to reload the predicate into a scalar GPR.

Here, an EXTRACT_LAST pattern is added to support mask mode.
So that,
EXTRACT_LAST (mask_1, mask_2)
will expands to is:
mov Z0, mask_2, 1
lastb W0, mask_1, Z0

aarch64-sve test Okay.
Okay to commit?

There might be more cases need to be discovered/fixed.

Regards,
Renlin

gcc/ChangeLog:

2018-11-08  Renlin Li  <renlin.li@arm.com>

	* config/aarch64/aarch64-sve.md (extract_last): Add new modes.
	* config/aarch64/iterators.md (PREDV): predicate mode to vector mode mapping.
	(predv): Likewise, lower case.

gcc/testsuite/ChangeLog:

2018-11-08  Renlin Li  <renlin.li@arm.com>

	* gcc.target/aarch64/sve/pr87815.c: Update.

Patch

diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index 5cd591b94335cde2230decf632f65c0faf33c4de..0550a2bd4b1b552159fad298342876afdd34303b 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -615,6 +615,28 @@ 
    lastb\t%<Vetype>0, %1, %2.<Vetype>"
 )
 
+(define_insn_and_split "extract_last_<mode>"
+  [(set (match_operand:<VEL> 0 "register_operand" "=r")
+	(unspec:<VEL>
+	  [(match_operand:PRED_ALL 1 "register_operand" "Upl")
+	   (match_operand:PRED_ALL 2 "register_operand" "Upl")]
+	  UNSPEC_LASTB))
+   (clobber (match_scratch:<PREDV> 3 "=w"))]
+  "TARGET_SVE"
+  "#"
+  "&& true"
+  [(const_int 0)]
+  {
+    if (GET_CODE (operands[3]) == SCRATCH)
+      operands[3] = gen_reg_rtx (<PREDV>mode);
+    emit_insn (gen_aarch64_sve_dup<predv>_const (operands[3], operands[2],
+						 CONST1_RTX (<PREDV>mode),
+						 CONST0_RTX (<PREDV>mode)));
+    emit_insn (gen_extract_last_<predv> (operands[0], operands[1], operands[3]));
+    DONE;
+  }
+)
+
 (define_expand "vec_duplicate<mode>"
   [(parallel
     [(set (match_operand:SVE_ALL 0 "register_operand")
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index a43956054e82aaf651fb45d0ff254b248c02c644..3f01c0f611173f9cdfcc150fc6c88141e7b7ebf8 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -698,8 +698,10 @@ 
 			(V4HF "HF") (V8HF  "HF") (VNx8HF  "HF")
 			(V2SF "SF") (V4SF  "SF") (VNx4SF  "SF")
 			(DF   "DF") (V2DF  "DF") (VNx2DF  "DF")
-			(SI   "SI") (HI    "HI")
-			(QI   "QI")])
+			(SI   "SI")              (VNx16BI "QI")
+			(HI   "HI")              (VNx8BI  "HI")
+			(QI   "QI")              (VNx4BI  "SI")
+			                         (VNx2BI  "DI")])
 
 ;; Define element mode for each vector mode (lower case).
 (define_mode_attr Vel [(V8QI "qi") (V16QI "qi") (VNx16QI "qi")
@@ -1134,6 +1136,12 @@ 
 			 (VNx16SI "vnx4bi") (VNx16SF "vnx4bi")
 			 (VNx8DI "vnx2bi") (VNx8DF "vnx2bi")])
 
+(define_mode_attr PREDV [(VNx16BI "VNx16QI") (VNx8BI "VNx8HI")
+			 (VNx4BI  "VNx4SI")  (VNx2BI "VNx2DI")])
+
+(define_mode_attr predv [(VNx16BI "vnx16qi") (VNx8BI "vnx8hi")
+			 (VNx4BI  "vnx4si")  (VNx2BI "vnx2di")])
+
 ;; -------------------------------------------------------------------
 ;; Code Iterators
 ;; -------------------------------------------------------------------
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr87815.c b/gcc/testsuite/gcc.target/aarch64/sve/pr87815.c
index 628cedb2acce82a86b61944eb6184d7fdbb2d656..82e73a8211a1f84d799be6f3f9137e296c59792c 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/pr87815.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr87815.c
@@ -1,5 +1,5 @@ 
-/* { dg-do compile { target aarch64_asm_sve_ok } } */
-/* { dg-options "-O3" } */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-vect" } */
 int a, b, d;
 short e;
 
@@ -11,3 +11,6 @@  void f ()
       d = e && b;
     }
 }
+
+/* { dg-final { scan-tree-dump-times "EXTRACT_LAST" 1 "vect" } } */
+/* { dg-final { scan-assembler-times {lastb} 1 } } */