If the target does not support floating-point, we register FP vector
types as 'void' (see register_vector_type).

The leads to warnings about 'pure attribute on function returning
void' when we declare the various load intrinsics because their
call_properties say CP_READ_MEMORY (thus giving them the 'pure'
attribute), but their return type is void.  This happens for instance
in gcc.target/arm/pr112337.c, depending on how GCC is built (I didn't
notice the warnings because arm_mve.h is considered as a system
include in my environment, and the warning is not emitted, but CI
reported it).

To avoid such warnings, declare floating-point scalar and vector types
even if the target does not have an FPU.

Note that since an FPU can be activated via #pragma GCC target
("arch=armv8.1-m.main+mve.fp" for instance), it means that such types
cannot appear and disappear withing a single TU, they have to be
available in all contexts.  This implies a noteworthy change for
__fp16: it not longer depends on using -mfp16-format=ieee or
alternative.  Also note that if the target ISA has the fp16 bit set,
we already silently activate -mfp16-format=ieee (with an error if
-mfp16-format=alternative was supplied).  The patch now enforces
-mfp16-format=none if the option was used.

In arm-mve-builtins.cc (register_builtin_types, register_vector_type,
register_builtin_tuple_types), this means simply removing the early
exits.  However, for this to work, we need to update
arm_vector_mode_supported_p, so that vector floating-point types are
always defined, and __fp16 must always be registered by
arm_init_fp16_builtins (as it is the base type for vectors of
float16_t.  Another side effect is that the declaration of float16_t
and float32_t typedefs is now unconditional.

The new tests verify that:
- we emit an error if the code tries to use floating-point intrinsics
  and the target does not have the floating-point extension
- we emit the expected code when activating the floating-point
  expected via a pragma
- we emit the expected code when the target supports floating-point
  (no pragma needed)
- we apply -mfp16-format=none where we used to default to ieee

An update is needed in g++.target/arm/mve/general-c++/nomve_fp_1.c,
because the error message now correctly uses float16x8_t instead of
void as return type.

The patch removes gcc.target/arm/fp16-compile-none-1.c which tests
that using __fp16 produces an error with -mfp16-format=none, since it
is no longer the case.

gcc/ChangeLog:

        PR target/117814
        * config/arm/arm-builtins.cc (arm_init_fp16_builtins): Always
        register __fp16 type.
        * config/arm/arm-mve-builtins.cc (register_builtin_tuple_types):
        Remove special handling when TARGET_HAVE_MVE_FLOAT is false.
        (register_vector_type): Likewise.
        (register_builtin_tuple_types): Likewise.
        * config/arm/arm-opts.h (arm_fp16_format_type): Add
        ARM_FP16_FORMAT_DEFAULT.
        * config/arm/arm.cc (arm_vector_mode_supported_p): Accept
        floating-point vector modes even if TARGET_HAVE_MVE_FLOAT is
        false.
        (arm_option_reconfigure_globals): Apply ARM_FP16_FORMAT_NONE if
        requested.
        * config/arm/arm.opt (mfp16-format): Default to
        ARM_FP16_FORMAT_DEFAULT.
        * config/arm/arm_mve_types.h (float16_t, float32_t): Define
        unconditionally.
        * doc/extend.texi (Half-precision Floating-point): __fp16 is now
        always available on arm.  More x86 paragraph closer to the rest of
        the x86 information.
        * doc/sourcebuild.texi (ARM-specific attributes): Document
        arm_v8_1m_mve_nofp_ok.

gcc/testsuite/ChangeLog:

        PR target/117814
        * gcc.target/arm/mve/intrinsics/pr117814-f16.c: New test.
        * gcc.target/arm/mve/intrinsics/pr117814-2-f16.c: New test.
        * gcc.target/arm/mve/intrinsics/pr117814-3-f16.c: New test.
        * gcc.target/arm/mve/intrinsics/pr117814-4-f16.c: New test.
        * gcc.target/arm/mve/intrinsics/pr117814-f32.c: New test.
        * gcc.target/arm/mve/intrinsics/pr117814-2-f32.c: New test.
        * gcc.target/arm/mve/intrinsics/pr117814-3-f32.c: New test.
        * gcc.target/arm/fp16-compile-none-1.c: Delete.
        * g++.target/arm/mve/general-c++/nomve_fp_1.c: Fix expected error
        message.
        * lib/target-supports.exp
        (check_effective_target_arm_v8_1m_mve_nofp_ok_nocache): New.
        (check_effective_target_arm_v8_1m_mve_nofp_ok): New.
        (add_options_for_arm_v8_1m_mve_nofp): New.
---
 gcc/config/arm/arm-builtins.cc                |  4 +-
 gcc/config/arm/arm-mve-builtins.cc            | 22 +--------
 gcc/config/arm/arm-opts.h                     |  1 +
 gcc/config/arm/arm.cc                         | 14 +++---
 gcc/config/arm/arm.opt                        |  2 +-
 gcc/config/arm/arm_mve_types.h                |  2 -
 gcc/doc/extend.texi                           | 29 ++++++-----
 gcc/doc/sourcebuild.texi                      |  6 +++
 .../arm/mve/general-c++/nomve_fp_1.c          |  2 +-
 .../gcc.target/arm/fp16-compile-none-1.c      |  7 ---
 .../arm/mve/intrinsics/pr117814-2-f16.c       | 30 ++++++++++++
 .../arm/mve/intrinsics/pr117814-2-f32.c       | 30 ++++++++++++
 .../arm/mve/intrinsics/pr117814-3-f16.c       | 21 ++++++++
 .../arm/mve/intrinsics/pr117814-3-f32.c       | 21 ++++++++
 .../arm/mve/intrinsics/pr117814-4-f16.c       | 23 +++++++++
 .../arm/mve/intrinsics/pr117814-f16.c         | 22 +++++++++
 .../arm/mve/intrinsics/pr117814-f32.c         | 22 +++++++++
 gcc/testsuite/lib/target-supports.exp         | 49 +++++++++++++++++++
 18 files changed, 255 insertions(+), 52 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.target/arm/fp16-compile-none-1.c
 create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f16.c
 create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f32.c
 create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f16.c
 create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f32.c
 create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-4-f16.c
 create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f16.c
 create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f32.c

diff --git a/gcc/config/arm/arm-builtins.cc b/gcc/config/arm/arm-builtins.cc
index e860607686c..8f0aae4cff1 100644
--- a/gcc/config/arm/arm-builtins.cc
+++ b/gcc/config/arm/arm-builtins.cc
@@ -2443,9 +2443,7 @@ arm_init_fp16_builtins (void)
   arm_fp16_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (arm_fp16_type_node) = GET_MODE_PRECISION (HFmode);
   layout_type (arm_fp16_type_node);
-  if (arm_fp16_format)
-    (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node,
-                                              "__fp16");
+  (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node, "__fp16");
 }
 
 void
diff --git a/gcc/config/arm/arm-mve-builtins.cc 
b/gcc/config/arm/arm-mve-builtins.cc
index 42b53cc05e7..b37c91c541b 100644
--- a/gcc/config/arm/arm-mve-builtins.cc
+++ b/gcc/config/arm/arm-mve-builtins.cc
@@ -410,8 +410,6 @@ register_builtin_types ()
 #include "arm-mve-builtins.def"
   for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
     {
-      if (vector_types[i].requires_float && !TARGET_HAVE_MVE_FLOAT)
-       continue;
       tree eltype = scalar_types[i];
       tree vectype;
       if (eltype == boolean_type_node)
@@ -433,18 +431,6 @@ register_builtin_types ()
 static void
 register_vector_type (vector_type_index type)
 {
-
-  /* If the target does not have the mve.fp extension, but the type requires
-     it, then it needs to be assigned a non-dummy type so that functions
-     with those types in their signature can be registered.  This allows for
-     diagnostics about the missing extension, rather than about a missing
-     function definition.  */
-  if (vector_types[type].requires_float && !TARGET_HAVE_MVE_FLOAT)
-    {
-      acle_vector_types[0][type] = void_type_node;
-      return;
-    }
-
   tree vectype = abi_vector_types[type];
   tree id = get_identifier (vector_types[type].acle_name);
   tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
@@ -470,13 +456,7 @@ register_builtin_tuple_types (vector_type_index type)
 {
   const vector_type_info* info = &vector_types[type];
 
-  /* If the target does not have the mve.fp extension, but the type requires
-     it, then it needs to be assigned a non-dummy type so that functions
-     with those types in their signature can be registered.  This allows for
-     diagnostics about the missing extension, rather than about a missing
-     function definition.  */
-  if (scalar_types[type] == boolean_type_node
-      || (info->requires_float && !TARGET_HAVE_MVE_FLOAT))
+  if (scalar_types[type] == boolean_type_node)
     {
       for (unsigned int num_vectors = 2; num_vectors <= 4; num_vectors += 2)
        acle_vector_types[num_vectors >> 1][type] = void_type_node;
diff --git a/gcc/config/arm/arm-opts.h b/gcc/config/arm/arm-opts.h
index 06a1939d087..f3e7568699f 100644
--- a/gcc/config/arm/arm-opts.h
+++ b/gcc/config/arm/arm-opts.h
@@ -35,6 +35,7 @@
  */
 enum arm_fp16_format_type
 {
+  ARM_FP16_FORMAT_DEFAULT = -1,
   ARM_FP16_FORMAT_NONE = 0,
   ARM_FP16_FORMAT_IEEE = 1,
   ARM_FP16_FORMAT_ALTERNATIVE = 2
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 5649986868b..984eb2376f5 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -3936,13 +3936,19 @@ arm_option_reconfigure_globals (void)
   arm_arch_bf16 = bitmap_bit_p (arm_active_target.isa, isa_bit_bf16);
 
   arm_fp16_inst = bitmap_bit_p (arm_active_target.isa, isa_bit_fp16);
-  if (arm_fp16_inst)
+
+  /* Set arm_fp16_format to IEEE if the target has fp16 support unless user
+     forced ARM_FP16_FORMAT_NONE.  */
+  if (arm_fp16_inst && (arm_fp16_format != ARM_FP16_FORMAT_NONE))
     {
       if (arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
        error ("selected fp16 options are incompatible");
       arm_fp16_format = ARM_FP16_FORMAT_IEEE;
     }
 
+  if (arm_fp16_format == ARM_FP16_FORMAT_DEFAULT)
+    arm_fp16_format = ARM_FP16_FORMAT_NONE;
+
   arm_arch_cde = 0;
   arm_arch_cde_coproc = 0;
   int cde_bits[] = {isa_bit_cdecp0, isa_bit_cdecp1, isa_bit_cdecp2,
@@ -29804,11 +29810,7 @@ arm_vector_mode_supported_p (machine_mode mode)
     return true;
 
   if (TARGET_HAVE_MVE
-      && (VALID_MVE_SI_MODE (mode) || VALID_MVE_PRED_MODE (mode)))
-    return true;
-
-  if (TARGET_HAVE_MVE_FLOAT
-      && (mode == V2DFmode || mode == V4SFmode || mode == V8HFmode))
+      && (VALID_MVE_MODE (mode) || VALID_MVE_PRED_MODE (mode)))
     return true;
 
   return false;
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 042cb54e05b..27330ec6225 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -142,7 +142,7 @@ Target Var(TARGET_FLIP_THUMB) Undocumented
 Switch ARM/Thumb modes on alternating functions for compiler testing.
 
 mfp16-format=
-Target RejectNegative Joined Enum(arm_fp16_format_type) Var(arm_fp16_format) 
Init(ARM_FP16_FORMAT_NONE)
+Target RejectNegative Joined Enum(arm_fp16_format_type) Var(arm_fp16_format) 
Init(ARM_FP16_FORMAT_DEFAULT)
 Specify the __fp16 floating-point format.
 
 Enum
diff --git a/gcc/config/arm/arm_mve_types.h b/gcc/config/arm/arm_mve_types.h
index 42e74666e80..d1889c68ac5 100644
--- a/gcc/config/arm/arm_mve_types.h
+++ b/gcc/config/arm/arm_mve_types.h
@@ -26,10 +26,8 @@
 #ifndef _GCC_ARM_MVE_TYPES_H
 #define _GCC_ARM_MVE_TYPES_H
 
-#if (__ARM_FEATURE_MVE & 2) /* MVE Floating point.  */
 typedef __fp16 float16_t;
 typedef float float32_t;
-#endif
 
 #pragma GCC arm "arm_mve_types.h"
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 1e1b4cc837d..2a542233c70 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1170,17 +1170,18 @@ typedef _Complex float __attribute__((mode(IC))) 
_Complex_ibm128;
 @cindex @code{__fp16} data type
 @cindex @code{__Float16} data type
 
-On ARM and AArch64 targets, GCC supports half-precision (16-bit) floating
-point via the @code{__fp16} type defined in the ARM C Language Extensions.
-On ARM systems, you must enable this type explicitly with the
-@option{-mfp16-format} command-line option in order to use it.
-On x86 targets with SSE2 enabled, GCC supports half-precision (16-bit)
-floating point via the @code{_Float16} type. For C++, x86 provides a builtin
-type named @code{_Float16} which contains same data format as C.
-
-ARM targets support two incompatible representations for half-precision
-floating-point values.  You must choose one of the representations and
-use it consistently in your program.
+On ARM and AArch64 targets, GCC supports half-precision (16-bit)
+floating point via the @code{__fp16} type defined in the ARM C
+Language Extensions.  On ARM systems, the @option{-mfp16-format}
+command-line option selects which format to use when the target
+supports several of them.
+
+Most ARM targets support two incompatible representations for
+half-precision floating-point values.  You must choose one of the
+representations and use it consistently in your program, unless your
+target only supports IEEE 754-2008 format (for instance
+@code{armv8.2-a+fp16} and @code{armv8.1-m.main+mve.fp}) in which case
+it is the default and only acceptable setting.
 
 Specifying @option{-mfp16-format=ieee} selects the IEEE 754-2008 format.
 This format can represent normalized values in the range of @math{2^{-14}} to 
65504.
@@ -1220,6 +1221,12 @@ calls.
 It is recommended that portable code use the @code{_Float16} type defined
 by ISO/IEC TS 18661-3:2015.  @xref{Floating Types}.
 
+
+On x86 targets with SSE2 enabled, GCC supports half-precision (16-bit)
+floating point via the @code{_Float16} type.  For C++, x86 provides a
+builtin type named @code{_Float16} which contains same data format as
+C.
+
 On x86 targets with SSE2 enabled, without @option{-mavx512fp16},
 all operations will be emulated by software emulation and the @code{float}
 instructions. The default behavior for @code{FLT_EVAL_METHOD} is to keep the
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index b5c1b23e527..ba4214f9724 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2204,6 +2204,12 @@ the Half-precision floating-point instructions (HP), 
Floating-point Extension
 (FP) along with M-Profile Vector Extension (MVE). Some multilibs may be
 incompatible with these options.
 
+@item arm_v8_1m_mve_nofp_ok
+ARM target supports options to generate instructions from ARMv8.1-M
+with the M-Profile Vector Extension (MVE) but without the
+Half-precision floating-point instructions (HP) and Floating-point
+Extension (FP). Some multilibs may be incompatible with these options.
+
 @item arm_mve_hw
 Test system supports executing MVE instructions.
 
diff --git a/gcc/testsuite/g++.target/arm/mve/general-c++/nomve_fp_1.c 
b/gcc/testsuite/g++.target/arm/mve/general-c++/nomve_fp_1.c
index fd8c05b0eed..4b91e0c6327 100644
--- a/gcc/testsuite/g++.target/arm/mve/general-c++/nomve_fp_1.c
+++ b/gcc/testsuite/g++.target/arm/mve/general-c++/nomve_fp_1.c
@@ -12,6 +12,6 @@
 void
 f1 (uint8x16_t v)
 {
-  vreinterpretq_f16 (v); /* { dg-error {ACLE function 'void 
vreinterpretq_f16\(uint8x16_t\)' requires ISA extension 'mve.fp'} } */
+  vreinterpretq_f16 (v); /* { dg-error {ACLE function 'float16x8_t 
vreinterpretq_f16\(uint8x16_t\)' requires ISA extension 'mve.fp'} } */
   /* { dg-message {note: you can enable mve.fp by using the command-line 
option '-march', or by using the 'target' attribute or pragma} "" {target 
*-*-*} .-1 } */
 }
diff --git a/gcc/testsuite/gcc.target/arm/fp16-compile-none-1.c 
b/gcc/testsuite/gcc.target/arm/fp16-compile-none-1.c
deleted file mode 100644
index 9472249e2e2..00000000000
--- a/gcc/testsuite/gcc.target/arm/fp16-compile-none-1.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target arm_fp16_none_ok } */
-/* { dg-options "-mfp16-format=none" } */
-
-/* __fp16 type name is not recognized unless you explicitly enable it
-   by selecting -mfp16-format=ieee or -mfp16-format=alternative.  */
-__fp16 xx = 0.0;  /* { dg-error "unknown type name" } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f16.c
new file mode 100644
index 00000000000..046cad030d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f16.c
@@ -0,0 +1,30 @@
+/* Check that we can compile if the target does not support floating-point, but
+   we use a pragma to enable FP support locally.  */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma GCC target ("arch=armv8.1-m.main+mve.fp")
+
+/*
+**foo:
+**     ...
+**     vldrh.16        q[0-9]+, \[(?:ip|fp|r[0-9]+)\](?:       @.*|) 
+**     ...
+*/
+float16x8_t
+foo (float16_t const *base)
+{
+  return vld1q_f16 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f32.c
new file mode 100644
index 00000000000..6856e8e6a08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-2-f32.c
@@ -0,0 +1,30 @@
+/* Check that we can compile if the target does not support floating-point, but
+   we use a pragma to enable FP support locally.  */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma GCC target ("arch=armv8.1-m.main+mve.fp")
+
+/*
+**foo:
+**     ...
+**     vldrw.32        q[0-9]+, \[(?:ip|fp|r[0-9]+)\](?:       @.*|)
+**     ...
+*/
+float32x4_t
+foo (float32_t const *base)
+{
+  return vld1q_f32 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f16.c
new file mode 100644
index 00000000000..bcb0dd65416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f16.c
@@ -0,0 +1,21 @@
+/* Check that we can compile if the target supports floating-point.  */
+
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float16x8_t
+foo (float16_t const *base)
+{
+  return vld1q_f16 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f32.c
new file mode 100644
index 00000000000..7e02816d505
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-3-f32.c
@@ -0,0 +1,21 @@
+/* Check that we can compile if the target supports floating-point.  */
+
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float32x4_t
+foo (float32_t const *base)
+{
+  return vld1q_f32 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-4-f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-4-f16.c
new file mode 100644
index 00000000000..b266f1b94e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-4-f16.c
@@ -0,0 +1,23 @@
+/* Check that -mfp16-format=none works.  */
+
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O2 -mfp16-format=none" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float16x8_t
+foo (float16_t const *base)
+{
+  return vld1q_f16 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not {eabi_attribute 38,} } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f16.c
new file mode 100644
index 00000000000..88930c1a3eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f16.c
@@ -0,0 +1,22 @@
+/* Check that we get an error if the target does not support floating-point: we
+   force +mve to cancel a possible implicit +mve.fp.  */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float16x8_t
+foo (float16_t const *base)
+{
+  return vld1q_f16 (base);  /* { dg-error {ACLE function '.*vld1q_f16.*' 
requires ISA extension 'mve.fp'} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f32.c
new file mode 100644
index 00000000000..814e781fa5d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr117814-f32.c
@@ -0,0 +1,22 @@
+/* Check that we get an error if the target does not support floating-point: we
+   force +mve to cancel a possible implicit +mve.fp.  */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float32x4_t
+foo (float32_t const *base)
+{
+  return vld1q_f32 (base);  /* { dg-error {ACLE function '.*vld1q_f32.*' 
requires ISA extension 'mve.fp'} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 939ef3a4119..4f257cfe052 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6699,6 +6699,55 @@ proc add_options_for_arm_v8_1m_mve { flags } {
     return "$flags $et_arm_v8_1m_mve_flags"
 }
 
+# Return 1 if the target supports ARMv8.1-M MVE without floating point
+# instructions, 0 otherwise.  The test is valid for ARM.
+# Record the command line options needed.
+
+proc check_effective_target_arm_v8_1m_mve_nofp_ok_nocache { } {
+    global et_arm_v8_1m_mve_nofp_flags
+    set et_arm_v8_1m_mve_nofp_flags ""
+
+    if { ![istarget arm*-*-*] } {
+       return 0;
+    }
+
+    # Iterate through sets of options to find the compiler flags that
+    # need to be added to the -march option.
+    foreach flags {"" "-mfloat-abi=softfp -mfpu=auto -mcpu=unset 
-march=armv8.1-m.main+mve" "-mfloat-abi=hard -mfpu=auto -mcpu=unset 
-march=armv8.1-m.main+mve"} {
+       if { [check_no_compiler_messages_nocache \
+                 arm_v8_1m_mve_ok object {
+           #if !defined (__ARM_FEATURE_MVE)
+           #error "__ARM_FEATURE_MVE not defined"
+           #endif
+           #if (__ARM_FEATURE_MVE & 2)
+           #error "__ARM_FEATURE_MVE for floating point defined"
+           #endif
+           #if __ARM_BIG_ENDIAN
+           #error "MVE intrinsics are not supported in Big-Endian mode."
+           #endif
+           #include <arm_mve.h>
+       } "$flags -mthumb"] } {
+           set et_arm_v8_1m_mve_nofp_flags "$flags -mthumb --save-temps"
+           return 1
+       }
+    }
+
+    return 0;
+}
+
+proc check_effective_target_arm_v8_1m_mve_nofp_ok { } {
+    return [check_cached_effective_target arm_v8_1m_mve_nofp_ok \
+               check_effective_target_arm_v8_1m_mve_nofp_ok_nocache]
+}
+
+proc add_options_for_arm_v8_1m_mve_nofp { flags } {
+    if { ! [check_effective_target_arm_v8_1m_mve_nofp_ok] } {
+       return "$flags"
+    }
+    global et_arm_v8_1m_mve_nofp_flags
+    return "$flags $et_arm_v8_1m_mve_nofp_flags"
+}
+
 proc check_effective_target_arm_v8_2a_dotprod_neon_ok { } {
     return [check_cached_effective_target arm_v8_2a_dotprod_neon_ok \
                check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache]
-- 
2.34.1

Reply via email to