diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index bbb54344eb7..ce5885e7bb1 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -6665,13 +6665,13 @@ [(set_attr "type" "neon_shift_imm_narrow_q")] ) -(define_insn "*aarch64_shrn_n_insn" +(define_insn "*aarch64_shrn_n_insn" [(set (match_operand: 0 "register_operand" "=w") (ALL_TRUNC: - (:VQN + (SHIFTRT:VQN (match_operand:VQN 1 "register_operand" "w") (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_"))))] - "TARGET_SIMD" + "TARGET_SIMD && AARCH64_VALID_SHRN_OP (, )" "shrn\t%0, %1, %2" [(set_attr "type" "neon_shift_imm_narrow_q")] ) diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 801f9ebc572..a01f1ee99d8 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -1297,4 +1297,9 @@ extern poly_uint16 aarch64_sve_vg; #define REG_ALLOC_ORDER {} #define ADJUST_REG_ALLOC_ORDER aarch64_adjust_reg_alloc_order () +#define AARCH64_VALID_SHRN_OP(T,S) \ +((T) == TRUNCATE \ + || ((T) == US_TRUNCATE && (S) == LSHIFTRT) \ + || ((T) == SS_TRUNCATE && (S) == ASHIFTRT)) + #endif /* GCC_AARCH64_H */ diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index acc7a3ec46e..15436c8ef37 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -2398,6 +2398,8 @@ ;; op prefix for shift right and narrow. (define_code_attr srn_op [(ashiftrt "r") (lshiftrt "")]) +(define_code_attr shrn_s [(ashiftrt "s") (lshiftrt "")]) + ;; Map shift operators onto underlying bit-field instructions (define_code_attr bfshift [(ashift "ubfiz") (ashiftrt "sbfx") (lshiftrt "ubfx") (rotatert "extr")])