diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 48eddf64e05..5715db4e1e1 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1818,6 +1818,40 @@ [(set_attr "type" "neon_shift_imm_narrow_q")] ) +(define_insn "*aarch64_shrn_vect" + [(set (match_operand: 0 "register_operand" "=w") + (truncate: + (SHIFTRT:VQN (match_operand:VQN 1 "register_operand" "w") + (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_"))))] + "TARGET_SIMD" + "shrn\\t%0., %1., %2" + [(set_attr "type" "neon_shift_imm_narrow_q")] +) + +(define_insn "*aarch64_shrn2_vect_le" + [(set (match_operand: 0 "register_operand" "=w") + (vec_concat: + (match_operand: 1 "register_operand" "0") + (truncate: + (SHIFTRT:VQN (match_operand:VQN 2 "register_operand" "w") + (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_")))))] + "TARGET_SIMD && !BYTES_BIG_ENDIAN" + "shrn2\\t%0., %2., %3" + [(set_attr "type" "neon_shift_imm_narrow_q")] +) + +(define_insn "*aarch64_shrn2_vect_be" + [(set (match_operand: 0 "register_operand" "=w") + (vec_concat: + (truncate: + (SHIFTRT:VQN (match_operand:VQN 2 "register_operand" "w") + (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_"))) + (match_operand: 1 "register_operand" "0")))] + "TARGET_SIMD && BYTES_BIG_ENDIAN" + "shrn2\\t%0., %2., %3" + [(set_attr "type" "neon_shift_imm_narrow_q")] +) + (define_expand "aarch64_shrn" [(set (match_operand: 0 "register_operand") (truncate: diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index e4af27b058c..aee32dc4e30 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -2003,6 +2003,9 @@ ;; Op prefix for shift right and accumulate. (define_code_attr sra_op [(ashiftrt "s") (lshiftrt "u")]) +;; op prefix for shift right and narrow. +(define_code_attr srn_op [(ashiftrt "r") (lshiftrt "")]) + ;; Map shift operators onto underlying bit-field instructions (define_code_attr bfshift [(ashift "ubfiz") (ashiftrt "sbfx") (lshiftrt "ubfx") (rotatert "extr")]) diff --git a/gcc/testsuite/gcc.target/aarch64/shrn-combine-1.c b/gcc/testsuite/gcc.target/aarch64/shrn-combine-1.c new file mode 100644 index 00000000000..a28524662ed --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/shrn-combine-1.c @@ -0,0 +1,13 @@ +/* { dg-do assemble } */ +/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */ + +#define TYPE char + +void foo (unsigned TYPE * restrict a, TYPE * restrict d, int n) +{ + for( int i = 0; i < n; i++ ) + d[i] = (a[i] * a[i]) >> 2; +} + +/* { dg-final { scan-assembler-times {\tshrn\t} 1 } } */ +/* { dg-final { scan-assembler-times {\tshrn2\t} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/shrn-combine-2.c b/gcc/testsuite/gcc.target/aarch64/shrn-combine-2.c new file mode 100644 index 00000000000..012135b424f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/shrn-combine-2.c @@ -0,0 +1,13 @@ +/* { dg-do assemble } */ +/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */ + +#define TYPE short + +void foo (unsigned TYPE * restrict a, TYPE * restrict d, int n) +{ + for( int i = 0; i < n; i++ ) + d[i] = (a[i] * a[i]) >> 2; +} + +/* { dg-final { scan-assembler-times {\tshrn\t} 1 } } */ +/* { dg-final { scan-assembler-times {\tshrn2\t} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/shrn-combine-3.c b/gcc/testsuite/gcc.target/aarch64/shrn-combine-3.c new file mode 100644 index 00000000000..8b5b360de62 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/shrn-combine-3.c @@ -0,0 +1,13 @@ +/* { dg-do assemble } */ +/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */ + +#define TYPE int + +void foo (unsigned long long * restrict a, TYPE * restrict d, int n) +{ + for( int i = 0; i < n; i++ ) + d[i] = a[i] >> 3; +} + +/* { dg-final { scan-assembler-times {\tshrn\t} 1 } } */ +/* { dg-final { scan-assembler-times {\tshrn2\t} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/shrn-combine-4.c b/gcc/testsuite/gcc.target/aarch64/shrn-combine-4.c new file mode 100644 index 00000000000..fedca7621e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/shrn-combine-4.c @@ -0,0 +1,13 @@ +/* { dg-do assemble } */ +/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */ + +#define TYPE long long + +void foo (unsigned TYPE * restrict a, TYPE * restrict d, int n) +{ + for( int i = 0; i < n; i++ ) + d[i] = (a[i] * a[i]) >> 2; +} + +/* { dg-final { scan-assembler-not {\tshrn\t} } } */ +/* { dg-final { scan-assembler-not {\tshrn2\t} } } */