diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 4f5898185f5..46c1b870aaf 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5514,21 +5514,21 @@
 ;; Bitfields
 ;; -------------------------------------------------------------------
 
-(define_expand "<optab>"
-  [(set (match_operand:DI 0 "register_operand")
-	(ANY_EXTRACT:DI (match_operand:DI 1 "register_operand")
+;; Defines extsv, extv patterns
+(define_expand "<optab><mode>"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+	(ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand")
 			(match_operand 2
-			  "aarch64_simd_shift_imm_offset_di")
-			(match_operand 3 "aarch64_simd_shift_imm_di")))]
+			  "aarch64_simd_shift_imm_offset_<mode>")
+			(match_operand 3 "aarch64_simd_shift_imm_<mode>")))]
   ""
   {
     if (!IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]),
-		   1, GET_MODE_BITSIZE (DImode) - 1))
+		   1, GET_MODE_BITSIZE (<MODE>mode)))
      FAIL;
   }
 )
 
-
 (define_insn "*<optab><mode>"
   [(set (match_operand:GPI 0 "register_operand" "=r")
 	(ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
@@ -5537,7 +5537,7 @@
 			 (match_operand 3
 			   "aarch64_simd_shift_imm_<mode>" "n")))]
   "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]),
-	     1, GET_MODE_BITSIZE (<MODE>mode) - 1)"
+	     1, GET_MODE_BITSIZE (<MODE>mode))"
   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
   [(set_attr "type" "bfx")]
 )
diff --git a/gcc/expmed.c b/gcc/expmed.c
index d7f8e9a5d767..926f4e8f1eaf 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1546,7 +1546,7 @@ extract_bit_field_using_extv (const extraction_insn *extv, rtx op0,
       if (REG_P (target)
 	  && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode))
 	{
-	  target = gen_lowpart (ext_mode, target);
+	  target = gen_lowpart_if_possible (ext_mode, target);
 	  if (partial_subreg_p (GET_MODE (spec_target), ext_mode))
 	    spec_target_subreg = target;
 	}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr86901.c b/gcc/testsuite/gcc.target/aarch64/pr86901.c
new file mode 100644
index 000000000000..5dd6fdf75f44
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr86901.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned int uint32_t;
+
+float g (float);
+
+static inline uint32_t
+top12 (float x)
+{
+  union
+  {
+    float f;
+    uint32_t i;
+  } u = {x};
+  return (u.i >> 20) & 0x7ff;
+}
+
+void
+f2 (float y, float *p)
+{
+  if (__builtin_expect (top12 (y) < top12 (1.0), 1))
+    *p = y * y;
+  else
+    g (y);
+}
+
+/* { dg-final { scan-assembler "fmov\tw" } } */
