@@ -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")
@@ -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
;; -------------------------------------------------------------------
@@ -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 } } */