)
(define_insn "aarch64_simd_ashr<mode>"
- [(set (match_operand:VDQ_I 0 "register_operand" "=w")
- (ashiftrt:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
- (match_operand:VDQ_I 2 "aarch64_simd_rshift_imm" "Dr")))]
+ [(set (match_operand:VDQ_I 0 "register_operand" "=w,w")
+ (ashiftrt:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w,w")
+ (match_operand:VDQ_I 2 "aarch64_simd_rshift_imm" "D1,Dr")))]
"TARGET_SIMD"
- "sshr\t%0.<Vtype>, %1.<Vtype>, %2"
- [(set_attr "type" "neon_shift_imm<q>")]
+ "@
+ cmlt\t%0.<Vtype>, %1.<Vtype>, #0
+ sshr\t%0.<Vtype>, %1.<Vtype>, %2"
+ [(set_attr "type" "neon_compare<q>,neon_shift_imm<q>")]
)
(define_insn "*aarch64_simd_sra<mode>"
(match_test "aarch64_simd_shift_imm_p (op, GET_MODE (op),
true)")))
+(define_constraint "D1"
+ "@internal
+ A constraint that matches vector of immediates that is bits(mode)-1."
+ (and (match_code "const,const_vector")
+ (match_test "aarch64_const_vec_all_same_in_range_p (op,
+ GET_MODE_UNIT_BITSIZE (mode) - 1,
+ GET_MODE_UNIT_BITSIZE (mode) - 1)")))
+
(define_constraint "Dr"
"@internal
A constraint that matches vector of immediates for right shifts."
--- /dev/null
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#define TYPE char
+
+void e (signed TYPE * restrict a, signed TYPE *b, int n)
+{
+ for (int i = 0; i < n; i++)
+ b[i] = a[i] >> (sizeof(TYPE)*8)-1;
+}
+
+/* { dg-final { scan-assembler-times {\tcmlt\t} 1 } } */
+/* { dg-final { scan-assembler-not {\tsshr\t} } } */
+
--- /dev/null
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#define TYPE short
+
+void e (signed TYPE * restrict a, signed TYPE *b, int n)
+{
+ for (int i = 0; i < n; i++)
+ b[i] = a[i] >> (sizeof(TYPE)*8)-1;
+}
+
+/* { dg-final { scan-assembler-times {\tcmlt\t} 1 } } */
+/* { dg-final { scan-assembler-not {\tsshr\t} } } */
+
--- /dev/null
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#define TYPE int
+
+void e (signed TYPE * restrict a, signed TYPE *b, int n)
+{
+ for (int i = 0; i < n; i++)
+ b[i] = a[i] >> (sizeof(TYPE)*8)-1;
+}
+
+/* { dg-final { scan-assembler-times {\tcmlt\t} 1 } } */
+/* { dg-final { scan-assembler-not {\tsshr\t} } } */
+
--- /dev/null
+/* { dg-do assemble } */
+/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+
+#define TYPE long
+
+void e (signed TYPE * restrict a, signed TYPE *b, int n)
+{
+ for (int i = 0; i < n; i++)
+ b[i] = a[i] >> (sizeof(TYPE)*8)-1;
+}
+
+/* { dg-final { scan-assembler-times {\tcmlt\t} 1 } } */
+/* { dg-final { scan-assembler-not {\tsshr\t} } } */
+