diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in
index 44e6cc6bdb6..7090775aa7e 100644
--- a/gcc/config/arm/arm-cpus.in
+++ b/gcc/config/arm/arm-cpus.in
@@ -213,15 +213,18 @@ define fgroup ALL_CRYPTO	crypto
 # strip off 32 D-registers, but does not remove support for
 # double-precision FP.
 define fgroup ALL_SIMD_INTERNAL	fp_d32 neon ALL_CRYPTO
-define fgroup ALL_SIMD	ALL_SIMD_INTERNAL dotprod fp16fml
+define fgroup ALL_SIMD_EXTERNAL dotprod fp16fml
+define fgroup ALL_SIMD	ALL_SIMD_INTERNAL ALL_SIMD_EXTERNAL
 
 # List of all FPU bits to strip out if -mfpu is used to override the
 # default.  fp16 is deliberately missing from this list.
 define fgroup ALL_FPU_INTERNAL	vfpv2 vfpv3 vfpv4 fpv5 fp16conv fp_dbl ALL_SIMD_INTERNAL
-
 # Similarly, but including fp16 and other extensions that aren't part of
 # -mfpu support.
-define fgroup ALL_FP	fp16 ALL_FPU_INTERNAL
+define fgroup ALL_FPU_EXTERNAL fp16
+
+# Everything related to the FPU extensions (FP or SIMD).
+define fgroup ALL_FP	ALL_FPU_EXTERNAL ALL_FPU_INTERNAL ALL_SIMD
 
 define fgroup ARMv4       armv4 notm
 define fgroup ARMv4t      ARMv4 thumb
@@ -1301,7 +1304,7 @@ begin cpu cortex-a55
  cname cortexa55
  tune for cortex-a53
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  option nofp remove ALL_FP
  costs cortex_a53
@@ -1313,7 +1316,7 @@ begin cpu cortex-a75
  cname cortexa75
  tune for cortex-a57
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a73
  vendor 41
@@ -1324,7 +1327,7 @@ begin cpu cortex-a76
  cname cortexa76
  tune for cortex-a57
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
  vendor 41
@@ -1335,7 +1338,7 @@ begin cpu cortex-a76ae
  cname cortexa76ae
  tune for cortex-a57
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
  vendor 41
@@ -1346,7 +1349,7 @@ begin cpu cortex-a77
  cname cortexa77
  tune for cortex-a57
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
  vendor 41
@@ -1358,7 +1361,7 @@ begin cpu neoverse-n1
  alias !ares
  tune for cortex-a57
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
  vendor 41
@@ -1370,7 +1373,7 @@ begin cpu cortex-a75.cortex-a55
  cname cortexa75cortexa55
  tune for cortex-a53
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a73
 end cpu cortex-a75.cortex-a55
@@ -1379,7 +1382,7 @@ begin cpu cortex-a76.cortex-a55
  cname cortexa76cortexa55
  tune for cortex-a53
  tune flags LDSCHED
- architecture armv8.2-a+fp16+dotprod+simd
+ architecture armv8.2-a+fp16+dotprod
  option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
 end cpu cortex-a76.cortex-a55
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6eb2afbd85f..983852cc4e3 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3109,7 +3109,8 @@ arm_option_override_internal (struct gcc_options *opts,
 #endif
 }
 
-static sbitmap isa_all_fpubits;
+static sbitmap isa_all_fpubits_internal;
+static sbitmap isa_all_fpbits;
 static sbitmap isa_quirkbits;
 
 /* Configure a build target TARGET from the user-specified options OPTS and
@@ -3176,7 +3177,12 @@ arm_configure_build_target (struct arm_build_target *target,
 	  /* Ignore any bits that are quirk bits.  */
 	  bitmap_and_compl (isa_delta, isa_delta, isa_quirkbits);
 	  /* Ignore (for now) any bits that might be set by -mfpu.  */
-	  bitmap_and_compl (isa_delta, isa_delta, isa_all_fpubits);
+	  bitmap_and_compl (isa_delta, isa_delta, isa_all_fpubits_internal);
+
+	  /* And if the target ISA lacks floating point, ignore any
+	     extensions that depend on that.  */
+	  if (!bitmap_bit_p (target->isa, isa_bit_vfpv2))
+	    bitmap_and_compl (isa_delta, isa_delta, isa_all_fpbits);
 
 	  if (!bitmap_empty_p (isa_delta))
 	    {
@@ -3335,7 +3341,7 @@ arm_configure_build_target (struct arm_build_target *target,
       auto_sbitmap fpu_bits (isa_num_bits);
 
       arm_initialize_isa (fpu_bits, arm_selected_fpu->isa_bits);
-      bitmap_and_compl (target->isa, target->isa, isa_all_fpubits);
+      bitmap_and_compl (target->isa, target->isa, isa_all_fpubits_internal);
       bitmap_ior (target->isa, target->isa, fpu_bits);
     }
 
@@ -3361,16 +3367,20 @@ arm_configure_build_target (struct arm_build_target *target,
 static void
 arm_option_override (void)
 {
-  static const enum isa_feature fpu_bitlist[]
+  static const enum isa_feature fpu_bitlist_internal[]
     = { ISA_ALL_FPU_INTERNAL, isa_nobit };
+  static const enum isa_feature fp_bitlist[]
+    = { ISA_ALL_FP, isa_nobit };
   static const enum isa_feature quirk_bitlist[] = { ISA_ALL_QUIRKS, isa_nobit};
   cl_target_option opts;
 
   isa_quirkbits = sbitmap_alloc (isa_num_bits);
   arm_initialize_isa (isa_quirkbits, quirk_bitlist);
 
-  isa_all_fpubits = sbitmap_alloc (isa_num_bits);
-  arm_initialize_isa (isa_all_fpubits, fpu_bitlist);
+  isa_all_fpubits_internal = sbitmap_alloc (isa_num_bits);
+  isa_all_fpbits = sbitmap_alloc (isa_num_bits);
+  arm_initialize_isa (isa_all_fpubits_internal, fpu_bitlist_internal);
+  arm_initialize_isa (isa_all_fpbits, fp_bitlist);
 
   arm_active_target.isa = sbitmap_alloc (isa_num_bits);
 
@@ -27258,7 +27268,7 @@ arm_print_asm_arch_directives ()
 	     don't print anything if all the bits are part of the
 	     FPU specification.  */
 	  if (bitmap_subset_p (opt_bits, arm_active_target.isa)
-	      && !bitmap_subset_p (opt_bits, isa_all_fpubits))
+	      && !bitmap_subset_p (opt_bits, isa_all_fpubits_internal))
 	    asm_fprintf (asm_out_file, "\t.arch_extension %s\n", opt->name);
 	}
     }
@@ -31771,7 +31781,7 @@ arm_identify_fpu_from_isa (sbitmap isa)
   auto_sbitmap fpubits (isa_num_bits);
   auto_sbitmap cand_fpubits (isa_num_bits);
 
-  bitmap_and (fpubits, isa, isa_all_fpubits);
+  bitmap_and (fpubits, isa, isa_all_fpubits_internal);
 
   /* If there are no ISA feature bits relating to the FPU, we must be
      doing soft-float.  */
@@ -31831,7 +31841,7 @@ arm_declare_function_name (FILE *stream, const char *name, tree decl)
 		{
 		  arm_initialize_isa (opt_bits, opt->isa_bits);
 		  if (bitmap_subset_p (opt_bits, arm_active_target.isa)
-		      && !bitmap_subset_p (opt_bits, isa_all_fpubits))
+		      && !bitmap_subset_p (opt_bits, isa_all_fpubits_internal))
 		    asm_fprintf (asm_out_file, "\t.arch_extension %s\n",
 				 opt->name);
 		}
@@ -32504,28 +32514,28 @@ arm_test_cpu_arch_data (void)
 static void
 arm_test_fpu_data (void)
 {
-  auto_sbitmap isa_all_fpubits (isa_num_bits);
+  auto_sbitmap isa_all_fpubits_internal (isa_num_bits);
   auto_sbitmap fpubits (isa_num_bits);
   auto_sbitmap tmpset (isa_num_bits);
 
-  static const enum isa_feature fpu_bitlist[]
+  static const enum isa_feature fpu_bitlist_internal[]
     = { ISA_ALL_FPU_INTERNAL, isa_nobit };
-  arm_initialize_isa (isa_all_fpubits, fpu_bitlist);
+  arm_initialize_isa (isa_all_fpubits_internal, fpu_bitlist_internal);
 
   for (unsigned int i = 0; i < TARGET_FPU_auto; i++)
   {
     arm_initialize_isa (fpubits, all_fpus[i].isa_bits);
-    bitmap_and_compl (tmpset, isa_all_fpubits, fpubits);
-    bitmap_clear (isa_all_fpubits);
-    bitmap_copy (isa_all_fpubits, tmpset);
+    bitmap_and_compl (tmpset, isa_all_fpubits_internal, fpubits);
+    bitmap_clear (isa_all_fpubits_internal);
+    bitmap_copy (isa_all_fpubits_internal, tmpset);
   }
 
-  if (!bitmap_empty_p (isa_all_fpubits))
+  if (!bitmap_empty_p (isa_all_fpubits_internal))
     {
 	fprintf (stderr, "Error: found feature bits in the ALL_FPU_INTERAL"
 			 " group that are not defined by any FPU.\n"
 			 "       Check your arm-cpus.in.\n");
-	ASSERT_TRUE (bitmap_empty_p (isa_all_fpubits));
+	ASSERT_TRUE (bitmap_empty_p (isa_all_fpubits_internal));
     }
 }
 
