diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 47a52482149f9ead50bbeba9b886ce26aff18adb..3f7893e67d0facb000ad8199e105ff780d49f8a9 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -2035,23 +2035,31 @@ (define_insn "aarch64_rshrn2<mode>_insn_le"
   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
 	(vec_concat:<VNARROWQ2>
 	  (match_operand:<VNARROWQ> 1 "register_operand" "0")
-	  (unspec:<VNARROWQ> [(match_operand:VQN 2 "register_operand" "w")
-	    (match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")]
-		UNSPEC_RSHRN)))]
-  "TARGET_SIMD && !BYTES_BIG_ENDIAN"
-  "rshrn2\\t%0.<V2ntype>, %2.<Vtype>, %3"
+	  (truncate:<VNARROWQ>
+	    (lshiftrt:VQN
+	      (plus:VQN (match_operand:VQN 2 "register_operand" "w")
+			(match_operand:VQN 3 "aarch64_simd_rshrn_imm_vec"))
+	      (match_operand:VQN 4 "aarch64_simd_shift_imm_vec_<vn_mode>")))))]
+  "TARGET_SIMD && !BYTES_BIG_ENDIAN
+   && INTVAL (CONST_VECTOR_ELT (operands[3], 0))
+      == (HOST_WIDE_INT_1 << (INTVAL (CONST_VECTOR_ELT (operands[4], 0)) - 1))"
+  "rshrn2\\t%0.<V2ntype>, %2.<Vtype>, %4"
   [(set_attr "type" "neon_shift_imm_narrow_q")]
 )
 
 (define_insn "aarch64_rshrn2<mode>_insn_be"
   [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
 	(vec_concat:<VNARROWQ2>
-	  (unspec:<VNARROWQ> [(match_operand:VQN 2 "register_operand" "w")
-		(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")]
-		  UNSPEC_RSHRN)
+	  (truncate:<VNARROWQ>
+	    (lshiftrt:VQN
+	      (plus:VQN (match_operand:VQN 2 "register_operand" "w")
+			(match_operand:VQN 3 "aarch64_simd_rshrn_imm_vec"))
+	      (match_operand:VQN 4 "aarch64_simd_shift_imm_vec_<vn_mode>")))
 	  (match_operand:<VNARROWQ> 1 "register_operand" "0")))]
-  "TARGET_SIMD && BYTES_BIG_ENDIAN"
-  "rshrn2\\t%0.<V2ntype>, %2.<Vtype>, %3"
+  "TARGET_SIMD && BYTES_BIG_ENDIAN
+   && INTVAL (CONST_VECTOR_ELT (operands[3], 0))
+      == (HOST_WIDE_INT_1 << (INTVAL (CONST_VECTOR_ELT (operands[4], 0)) - 1))"
+  "rshrn2\\t%0.<V2ntype>, %2.<Vtype>, %4"
   [(set_attr "type" "neon_shift_imm_narrow_q")]
 )
 
@@ -2070,17 +2078,24 @@ (define_expand "aarch64_rshrn2<mode>"
       }
     else
       {
+	rtx shft
+	  = aarch64_simd_gen_const_vector_dup (<MODE>mode,
+					       HOST_WIDE_INT_1U
+					        << (INTVAL (operands[3]) - 1));
+
 	operands[3] = aarch64_simd_gen_const_vector_dup (<MODE>mode,
 							 INTVAL (operands[3]));
 	if (BYTES_BIG_ENDIAN)
 	  emit_insn (gen_aarch64_rshrn2<mode>_insn_be (operands[0],
 						       operands[1],
 						       operands[2],
+						       shft,
 						       operands[3]));
 	else
 	  emit_insn (gen_aarch64_rshrn2<mode>_insn_le (operands[0],
 						       operands[1],
 						       operands[2],
+						       shft,
 						       operands[3]));
       }
     DONE;
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 803366eed551f192e50f20b300c0d1f7e842e9fc..0f144f98c9d68f30b0721d24b6f24568a57c19a0 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -231,7 +231,6 @@ (define_c_enum "unspec" [
     UNSPEC_SSP_SYSREG
     UNSPEC_SP_SET
     UNSPEC_SP_TEST
-    UNSPEC_RSHRN
     UNSPEC_RSQRT
     UNSPEC_RSQRTE
     UNSPEC_RSQRTS
