diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 254c4e3..886ad66 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2664,17 +2664,34 @@ proc check_effective_target_arm_vect_no_misalign { } {
 
 
 # Return 1 if this is an ARM target supporting -mfpu=vfp
-# -mfloat-abi=softfp.  Some multilibs may be incompatible with these
-# options.
+# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
+# incompatible with these options.  Also set et_arm_vfp_flags to the
+# best options to add.
 
-proc check_effective_target_arm_vfp_ok { } {
+proc check_effective_target_arm_vfp_ok_nocache { } {
+    global et_arm_vfp_flags
+    set et_arm_vfp_flags ""
     if { [check_effective_target_arm32] } {
-	return [check_no_compiler_messages arm_vfp_ok object {
-	    int dummy;
-	} "-mfpu=vfp -mfloat-abi=softfp"]
-    } else {
-	return 0
+	foreach flags {"-mfpu=vfp" "-mfpu=vfp -mfloat-abi=softfp" "-mfpu=vfp -mfloat-abi=hard"} {
+	    if { [check_no_compiler_messages_nocache arm_vfp_ok object {
+		#ifndef __ARM_FP
+		#error __ARM_FP not defined
+		#endif
+		#ifdef __ARM_NEON_FP
+		#error __ARM_NEON_FP defined
+		#endif
+	    } "$flags" ] } {
+		set et_arm_vfp_flags $flags
+		return 1
+	    }
+	}
     }
+    return 0
+}
+
+proc check_effective_target_arm_vfp_ok { } {
+    return [check_cached_effective_target arm_vfp_ok \
+		check_effective_target_arm_vfp_ok_nocache]
 }
 
 # Return 1 if this is an ARM target supporting -mfpu=vfp3
@@ -2721,6 +2738,47 @@ proc check_effective_target_arm_hard_vfp_ok { } {
     }
 }
 
+# Return 1 if this is an ARM target defining __ARM_FP. We may need
+# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
+# incompatible with these options.  Also set et_arm_fp_flags to the
+# best options to add.
+
+proc check_effective_target_arm_fp_ok_nocache { } {
+    global et_arm_fp_flags
+    set et_arm_fp_flags ""
+    if { [check_effective_target_arm32] } {
+	foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} {
+	    if { [check_no_compiler_messages_nocache arm_fp_ok object {
+		#ifndef __ARM_FP
+		#error __ARM_FP not defined
+		#endif
+	    } "$flags"] } {
+		set et_arm_fp_flags $flags
+		return 1
+	    }
+	}
+    }
+
+    return 0
+}
+
+proc check_effective_target_arm_fp_ok { } {
+    return [check_cached_effective_target arm_fp_ok \
+		check_effective_target_arm_fp_ok_nocache]
+}
+
+# Add the options needed to define __ARM_FP.  We need either
+# -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already
+# specified by the multilib, use it.
+
+proc add_options_for_arm_fp { flags } {
+    if { ! [check_effective_target_arm_fp_ok] } {
+	return "$flags"
+    }
+    global et_arm_fp_flags
+    return "$flags $et_arm_fp_flags"
+}
+
 # Return 1 if this is an ARM target that supports DSP multiply with
 # current multilib flags.
 
@@ -2753,7 +2811,7 @@ proc check_effective_target_arm_unaligned { } {
 proc check_effective_target_arm_crypto_ok_nocache { } {
     global et_arm_crypto_flags
     set et_arm_crypto_flags ""
-    if { [check_effective_target_arm32] } {
+    if { [check_effective_target_arm_v8_neon_ok] } {
 	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} {
 	    if { [check_no_compiler_messages_nocache arm_crypto_ok object {
 		#include "arm_neon.h"
@@ -2779,6 +2837,54 @@ proc check_effective_target_arm_crypto_ok { } {
 		check_effective_target_arm_crypto_ok_nocache]
 }
 
+# Return 1 if this is an ARM target supporting pragma target
+# -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp or equivalent options.
+# Some multilibs may be incompatible with these options.  Also set
+# et_arm_crypto_pragma_flags to the best options to add.
+
+proc check_effective_target_arm_crypto_pragma_ok_nocache { } {
+    global et_arm_crypto_pragma_flags
+    set et_arm_crypto_pragma_flags ""
+    if { [check_effective_target_arm_v8_neon_ok] } {
+	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} {
+	    if { [check_no_compiler_messages_nocache arm_crypto_pragmaok object {
+		#pragma GCC target ("fpu=crypto-neon-fp-armv8")
+		#include "arm_neon.h"
+		uint8x16_t
+		foo (uint8x16_t a, uint8x16_t b)
+		{
+	          return vaeseq_u8 (a, b);
+		}
+	    } "[add_options_for_arm_v8_neon ""] $flags"] } {
+		set et_arm_crypto_pragma_flags "[add_options_for_arm_v8_neon ""] $flags"
+		return 1
+	    }
+	}
+    }
+
+    return 0
+}
+
+# Return 1 if this is an ARM target supporting pragma target
+# -mfpu=crypto-neon-fp-armv8.
+
+proc check_effective_target_arm_crypto_pragma_ok { } {
+    return [check_cached_effective_target arm_crypto_pragma_ok \
+		check_effective_target_arm_crypto_pragma_ok_nocache]
+}
+
+# Add the options needed for VFP.  We need either -mfloat-abi=softfp
+# or -mfloat-abi=hard, but if one is already specified by the
+# multilib, use it.
+
+proc add_options_for_arm_vfp { flags } {
+    if { ! [check_effective_target_arm_vfp_ok] } {
+	return "$flags"
+    }
+    global et_arm_vfp_flags
+    return "$flags $et_arm_vfp_flags"
+}
+
 # Add options for crypto extensions.
 proc add_options_for_arm_crypto { flags } {
     if { ! [check_effective_target_arm_crypto_ok] } {
@@ -2897,8 +3003,8 @@ proc check_effective_target_arm_crc_ok { } {
 
 # Return 1 if this is an ARM target supporting -mfpu=neon-fp16
 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
-# incompatible with these options.  Also set et_arm_neon_flags to the
-# best options to add.
+# incompatible with these options.  Also set et_arm_neon_fp16_flags to
+# the best options to add.
 
 proc check_effective_target_arm_neon_fp16_ok_nocache { } {
     global et_arm_neon_fp16_flags
diff --git a/gcc/testsuite/gcc.target/arm/attr-crypto.c b/gcc/testsuite/gcc.target/arm/attr-crypto.c
index 1db5984..b703fbc 100644
--- a/gcc/testsuite/gcc.target/arm/attr-crypto.c
+++ b/gcc/testsuite/gcc.target/arm/attr-crypto.c
@@ -1,6 +1,10 @@
 /* { dg-do compile } */
-/* { dg-require-effective-target arm_crypto_ok } */
-/* { dg-options "-O2 -mfloat-abi=softfp" } */
+/* Make sure we can force fpu=vfp before switching using the
+   pragma.  */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-require-effective-target arm_crypto_pragma_ok } */
+/* { dg-options "-O2 -march=armv8-a" } */
+/* { dg-add-options arm_vfp } */
 
 #pragma GCC target ("fpu=crypto-neon-fp-armv8")
 
diff --git a/gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c b/gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c
index 6ac32fc..05dc579 100644
--- a/gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c
+++ b/gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c
@@ -1,7 +1,9 @@
 /* Check that calling a neon builtin from a function compiled with vfp fails.  */
 /* { dg-do compile } */
+/* { dg-require-effective-target arm_fp_ok } */
 /* { dg-require-effective-target arm_neon_ok } */
-/* { dg-options "-O2 -mfloat-abi=softfp" } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_fp } */
 
 #include <arm_neon.h>
 
@@ -12,6 +14,5 @@ foo (uint8x16_t *p)
   *p = vmovq_n_u8 (3); /* { dg-message "called from here" } */
 }
 
-/* { dg-error "inlining failed in call to always_inline" "" { target *-*-* } 0 }
- */
+/* { dg-error "inlining failed in call to always_inline" "" { target *-*-* } 0 } */
 
diff --git a/gcc/testsuite/gcc.target/arm/attr-neon-fp16.c b/gcc/testsuite/gcc.target/arm/attr-neon-fp16.c
index 3cf8918..984992f 100644
--- a/gcc/testsuite/gcc.target/arm/attr-neon-fp16.c
+++ b/gcc/testsuite/gcc.target/arm/attr-neon-fp16.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
-/* { dg-require-effective-target arm_neon_ok } */
-/* { dg-options "-mfp16-format=ieee -mfloat-abi=softfp" } */
+/* { dg-require-effective-target arm_fp_ok } */
+/* { dg-options "-mfp16-format=ieee" } */
+/* { dg-add-options arm_fp } */
 
 #include "arm_neon.h"
 
diff --git a/gcc/testsuite/gcc.target/arm/attr-neon2.c b/gcc/testsuite/gcc.target/arm/attr-neon2.c
index 819fad4..79133e5 100644
--- a/gcc/testsuite/gcc.target/arm/attr-neon2.c
+++ b/gcc/testsuite/gcc.target/arm/attr-neon2.c
@@ -1,6 +1,8 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_neon_ok } */
-/* { dg-options "-O2 -mfloat-abi=softfp -mfpu=vfp" } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_vfp } */
 
 #pragma GCC target ("fpu=neon")
 #include <arm_neon.h>
diff --git a/gcc/testsuite/gcc.target/arm/attr-neon3.c b/gcc/testsuite/gcc.target/arm/attr-neon3.c
index 30a1479..0d31fb5 100644
--- a/gcc/testsuite/gcc.target/arm/attr-neon3.c
+++ b/gcc/testsuite/gcc.target/arm/attr-neon3.c
@@ -1,6 +1,8 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_crypto_ok } */
-/* { dg-options "-O2 -mfloat-abi=softfp -mfpu=vfp" } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_vfp } */
 
 #include <arm_neon.h>
 
