]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arm: [MVE intrinsics] Improve vdupq_n implementation
authorChristophe Lyon <christophe.lyon@arm.com>
Tue, 25 Jun 2024 13:47:23 +0000 (15:47 +0200)
committerChristophe Lyon <christophe.lyon@arm.com>
Wed, 16 Oct 2024 20:02:54 +0000 (22:02 +0200)
This patch makes the non-predicated vdupq_n MVE intrinsics use
vec_duplicate rather than an unspec.  This enables the compiler to
generate better code sequences (for instance using vmov when
possible).

The patch renames the existing mve_vdup<mode> pattern into
@mve_vdupq_n<mode>, and removes the now useless
@mve_<mve_insn>q_n_f<mode> and @mve_<mve_insn>q_n_<supf><mode> ones.

As a side-effect, it needs to update the mve_unpredicated_insn
predicates in @mve_<mve_insn>q_m_n_<supf><mode> and
@mve_<mve_insn>q_m_n_f<mode>.

Using vec_duplicates means the compiler is now able to use vmov in the
tests with an immediate argument in vdupq_n_[su]{8,16,32}.c:
vmov.i8 q0,#0x1

However, this is only possible when the immediate has a suitable value
(MVE encoding constraints, see imm_for_neon_mov_operand predicate).

Provided we adjust the cost computations in arm_rtx_costs_internal(),
when the immediate does not meet the vmov constraints, we now generate:
mov r0, #imm
vdup.xx q0,r0

or
ldr r0, .L4
vdup.32 q0,r0
in the f32 case (with 1.1 as immediate).

Without the cost adjustment, we would generate:
vldr.64 d0, .L4
vldr.64 d1, .L4+8
and an associated literal pool entry.

Regarding the testsuite updates:
--------------------------------
* The signed versions of vdupq_* tests lack a version with an
immediate argument.  This patch adds them, similar to what we already
have for vdupq_n_u*.c tests.

* Code generation for different immediate values is checked with the
new tests this patch introduces.  Note there's no need for s8/u8 tests
because 8-bit immediates always comply wth imm_for_neon_mov_operand.

* We can remove xfail from vcmp*f tests since we now generate:
movw r3, #15462
vcmp.f16 eq, q0, r3
instead of the previous:
vldr.64 d6, .L5
vldr.64 d7, .L5+8
vcmp.f16 eq, q0, q3

Tested on arm-linux-gnueabihf and arm-none-eabi with no regression.

2024-07-02  Jolen Li  <jolen.li@arm.com>
    Christophe Lyon  <christophe.lyon@arm.com>

gcc/
* config/arm/arm-mve-builtins-base.cc (vdupq_impl): New class.
(vdupq): Use new implementation.
* config/arm/arm.cc (arm_rtx_costs_internal): Handle HFmode
for COST_DOUBLE. Update costing for CONST_VECTOR.
* config/arm/arm_mve_builtins.def: Merge vdupq_n_f, vdupq_n_s
and vdupq_n_u into vdupq_n.
* config/arm/mve.md (mve_vdup<mode>): Rename into ...
(@mve_vdup_n<mode>): ... this.
(@mve_<mve_insn>q_n_f<mode>): Delete.
(@mve_<mve_insn>q_n_<supf><mode>): Delete..
(@mve_<mve_insn>q_m_n_<supf><mode>): Update mve_unpredicated_insn
attribute.
(@mve_<mve_insn>q_m_n_f<mode>): Likewise.

gcc/testsuite/
* gcc.target/arm/mve/intrinsics/vdupq_n_u8.c (foo1): Update
expected code.
* gcc.target/arm/mve/intrinsics/vdupq_n_u16.c (foo1): Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_u32.c (foo1): Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_s8.c: Add test with
immediate argument.
* gcc.target/arm/mve/intrinsics/vdupq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_f16.c (foo1): Update
expected code.
* gcc.target/arm/mve/intrinsics/vdupq_n_f32.c (foo1): Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c: Add test with
immediate argument.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_f32-2.c: New test.
* gcc.target/arm/mve/intrinsics/vdupq_n_s16-2.c: New test.
* gcc.target/arm/mve/intrinsics/vdupq_n_s32-2.c: New test.
* gcc.target/arm/mve/intrinsics/vdupq_n_u16-2.c: New test.
* gcc.target/arm/mve/intrinsics/vdupq_n_u32-2.c: New test.
* gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c: Remove xfail.
* gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c: Likewise.

35 files changed:
gcc/config/arm/arm-mve-builtins-base.cc
gcc/config/arm/arm.cc
gcc/config/arm/arm_mve_builtins.def
gcc/config/arm/mve.md
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s8.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u8.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c
gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c

index e0ae593a6c025214e1672f21734eab7d1c251b5a..be0f9c26c834f84bccfa6e5f1b837df53efee089 100644 (file)
@@ -39,6 +39,59 @@ using namespace arm_mve;
 
 namespace {
 
+/* Implements vdup_* intrinsics.  */
+class vdupq_impl : public quiet<function_base>
+{
+public:
+  CONSTEXPR vdupq_impl (int unspec_for_m_n_sint,
+                       int unspec_for_m_n_uint,
+                       int unspec_for_m_n_fp)
+    : m_unspec_for_m_n_sint (unspec_for_m_n_sint),
+      m_unspec_for_m_n_uint (unspec_for_m_n_uint),
+      m_unspec_for_m_n_fp (unspec_for_m_n_fp)
+  {}
+  int m_unspec_for_m_n_sint;
+  int m_unspec_for_m_n_uint;
+  int m_unspec_for_m_n_fp;
+
+  rtx expand (function_expander &e) const override
+  {
+    gcc_assert (e.mode_suffix_id == MODE_n);
+
+    insn_code code;
+    machine_mode mode = e.vector_mode (0);
+
+    switch (e.pred)
+    {
+    case PRED_none:
+      /* No predicate, _n suffix.  */
+      code = code_for_mve_vdupq_n (mode);
+      return e.use_exact_insn (code);
+
+    case PRED_m:
+    case PRED_x:
+      /* "m" or "x" predicate, _n suffix.  */
+      if (e.type_suffix (0).integer_p)
+       if (e.type_suffix (0).unsigned_p)
+         code = code_for_mve_q_m_n (m_unspec_for_m_n_uint,
+                                    m_unspec_for_m_n_uint, mode);
+       else
+         code = code_for_mve_q_m_n (m_unspec_for_m_n_sint,
+                                    m_unspec_for_m_n_sint, mode);
+      else
+       code = code_for_mve_q_m_n_f (m_unspec_for_m_n_fp, mode);
+
+      if (e.pred == PRED_m)
+       return e.use_cond_insn (code, 0);
+      else
+       return e.use_pred_x_insn (code);
+
+    default:
+      gcc_unreachable ();
+    }
+  }
+};
+
 /* Implements vreinterpretq_* intrinsics.  */
 class vreinterpretq_impl : public quiet<function_base>
 {
@@ -339,7 +392,7 @@ FUNCTION (vcmpltq, unspec_based_mve_function_exact_insn_vcmp, (LT, UNKNOWN, LT,
 FUNCTION (vcmpcsq, unspec_based_mve_function_exact_insn_vcmp, (UNKNOWN, GEU, UNKNOWN, UNKNOWN, VCMPCSQ_M_U, UNKNOWN, UNKNOWN, VCMPCSQ_M_N_U, UNKNOWN))
 FUNCTION (vcmphiq, unspec_based_mve_function_exact_insn_vcmp, (UNKNOWN, GTU, UNKNOWN, UNKNOWN, VCMPHIQ_M_U, UNKNOWN, UNKNOWN, VCMPHIQ_M_N_U, UNKNOWN))
 FUNCTION_WITHOUT_M_N (vcreateq, VCREATEQ)
-FUNCTION_ONLY_N (vdupq, VDUPQ)
+FUNCTION (vdupq, vdupq_impl, (VDUPQ_M_N_S, VDUPQ_M_N_U, VDUPQ_M_N_F))
 FUNCTION_WITH_RTX_M (veorq, XOR, VEORQ)
 FUNCTION (vfmaq, unspec_mve_function_exact_insn, (-1, -1, VFMAQ_F, -1, -1, VFMAQ_N_F, -1, -1, VFMAQ_M_F, -1, -1, VFMAQ_M_N_F))
 FUNCTION (vfmasq, unspec_mve_function_exact_insn, (-1, -1, -1, -1, -1, VFMASQ_N_F, -1, -1, -1, -1, -1, VFMASQ_M_N_F))
index 50dd005ba10a48a0e53c14bde1910f7be32c3ac4..0d32b70568b857646abf9dab8211ae689607da58 100644 (file)
@@ -11911,7 +11911,7 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code,
 
     case CONST_DOUBLE:
       if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
-         && (mode == SFmode || !TARGET_VFP_SINGLE))
+         && (mode == SFmode || mode == HFmode || !TARGET_VFP_SINGLE))
        {
          if (vfp3_const_double_rtx (x))
            {
@@ -11936,12 +11936,18 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code,
       return true;
 
     case CONST_VECTOR:
-      /* Fixme.  */
       if (((TARGET_NEON && TARGET_HARD_FLOAT
            && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)))
           || TARGET_HAVE_MVE)
          && simd_immediate_valid_for_move (x, mode, NULL, NULL))
        *cost = COSTS_N_INSNS (1);
+      else if (TARGET_HAVE_MVE)
+       {
+         /* 128-bit vector requires two vldr.64 on MVE.  */
+         *cost = COSTS_N_INSNS (2);
+         if (speed_p)
+           *cost += extra_cost->ldst.loadd * 2;
+       }
       else
        *cost = COSTS_N_INSNS (4);
       return true;
index f141aab816c954c5e9319401484b3b4562ae9823..dd99a90b95219a0c475775dd433cc5413f2f6fce 100644 (file)
@@ -27,7 +27,7 @@ VAR2 (UNOP_NONE_NONE, vrndmq_f, v8hf, v4sf)
 VAR2 (UNOP_NONE_NONE, vrndaq_f, v8hf, v4sf)
 VAR2 (UNOP_NONE_NONE, vrev64q_f, v8hf, v4sf)
 VAR2 (UNOP_NONE_NONE, vnegq_f, v8hf, v4sf)
-VAR2 (UNOP_NONE_NONE, vdupq_n_f, v8hf, v4sf)
+VAR5 (UNOP_NONE_NONE, vdupq_n, v8hf, v4sf, v16qi, v8hi, v4si)
 VAR2 (UNOP_NONE_NONE, vabsq_f, v8hf, v4sf)
 VAR1 (UNOP_NONE_NONE, vrev32q_f, v8hf)
 VAR1 (UNOP_NONE_NONE, vcvttq_f32_f16, v4sf)
@@ -39,7 +39,6 @@ VAR3 (UNOP_SNONE_SNONE, vqnegq_s, v16qi, v8hi, v4si)
 VAR3 (UNOP_SNONE_SNONE, vqabsq_s, v16qi, v8hi, v4si)
 VAR3 (UNOP_SNONE_SNONE, vnegq_s, v16qi, v8hi, v4si)
 VAR3 (UNOP_SNONE_SNONE, vmvnq_s, v16qi, v8hi, v4si)
-VAR3 (UNOP_SNONE_SNONE, vdupq_n_s, v16qi, v8hi, v4si)
 VAR3 (UNOP_SNONE_SNONE, vclzq_s, v16qi, v8hi, v4si)
 VAR3 (UNOP_SNONE_SNONE, vclsq_s, v16qi, v8hi, v4si)
 VAR3 (UNOP_SNONE_SNONE, vaddvq_s, v16qi, v8hi, v4si)
@@ -57,7 +56,6 @@ VAR1 (UNOP_SNONE_SNONE, vrev16q_s, v16qi)
 VAR1 (UNOP_SNONE_SNONE, vaddlvq_s, v4si)
 VAR3 (UNOP_UNONE_UNONE, vrev64q_u, v16qi, v8hi, v4si)
 VAR3 (UNOP_UNONE_UNONE, vmvnq_u, v16qi, v8hi, v4si)
-VAR3 (UNOP_UNONE_UNONE, vdupq_n_u, v16qi, v8hi, v4si)
 VAR3 (UNOP_UNONE_UNONE, vclzq_u, v16qi, v8hi, v4si)
 VAR3 (UNOP_UNONE_UNONE, vaddvq_u, v16qi, v8hi, v4si)
 VAR2 (UNOP_UNONE_UNONE, vrev32q_u, v16qi, v8hi)
index 3f01bc1f4fc758aacbccdf4ea0265a6be6d63b97..7ace8b1c80852486cdf3ba681ba4aa3fc630ed04 100644 (file)
    (set_attr "thumb2_pool_range" "*,*,*,*,1018,*,*,*")
    (set_attr "neg_pool_range" "*,*,*,*,996,*,*,*")])
 
-(define_insn "mve_vdup<mode>"
+;;
+;; [vdupq_n_u, vdupq_n_s, vdupq_n_f]
+;;
+(define_insn "@mve_vdupq_n<mode>"
   [(set (match_operand:MVE_VLD_ST 0 "s_register_operand" "=w")
        (vec_duplicate:MVE_VLD_ST
          (match_operand:<V_elem> 1 "s_register_operand" "r")))]
   "TARGET_HAVE_MVE || TARGET_HAVE_MVE_FLOAT"
   "vdup.<V_sz_elem>\t%q0, %1"
- [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_vdup<mode>"))
+ [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_vdupq_n<mode>"))
   (set_attr "length" "4")
    (set_attr "type" "mve_move")])
 
   (set_attr "type" "mve_move")
 ])
 
-;;
-;; [vdupq_n_f])
-;;
-(define_insn "@mve_<mve_insn>q_n_f<mode>"
-  [
-   (set (match_operand:MVE_0 0 "s_register_operand" "=w")
-       (unspec:MVE_0 [(match_operand:<V_elem> 1 "s_register_operand" "r")]
-        MVE_FP_N_VDUPQ_ONLY))
-  ]
-  "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
-  "<mve_insn>.%#<V_sz_elem>\t%q0, %1"
- [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_f<mode>"))
-  (set_attr "type" "mve_move")
-])
-
 ;;
 ;; [vrev32q_f])
 ;;
   "TARGET_HAVE_MVE"
 )
 
-;;
-;; [vdupq_n_u, vdupq_n_s])
-;;
-(define_insn "@mve_<mve_insn>q_n_<supf><mode>"
-  [
-   (set (match_operand:MVE_2 0 "s_register_operand" "=w")
-       (unspec:MVE_2 [(match_operand:<V_elem> 1 "s_register_operand" "r")]
-        VDUPQ_N))
-  ]
-  "TARGET_HAVE_MVE"
-  "<mve_insn>.%#<V_sz_elem>\t%q0, %1"
- [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_<supf><mode>"))
-  (set_attr "type" "mve_move")
-])
-
 ;;
 ;; [vclzq_u, vclzq_s])
 ;;
   ]
   "TARGET_HAVE_MVE"
   "vpst\;<mve_insn>t.%#<V_sz_elem>\t%q0, %2"
- [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_<supf><mode>"))
+ [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n<mode>"))
   (set_attr "type" "mve_move")
    (set_attr "length""8")])
 
   ]
   "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
   "vpst\;<mve_insn>t.%#<V_sz_elem>\t%q0, %2"
- [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_f<mode>"))
+ [(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n<mode>"))
   (set_attr "type" "mve_move")
    (set_attr "length""8")])
 
index 2f84d751c5311fecc2cddc5febab409e301a58b9..335e511b17bbb04e79b4c1c85d24761f9aba44f1 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float16x8_t a, float16_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f16        eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float16x8_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 6cfe7338fcee5b585fc71fec6f669cfd944f7bf6..e5c16be65e3dc85c53f9f03aa59464e3047237ee 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float32x4_t a, float32_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f32        eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float32x4_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 978bd7d4b52c5d81f2c711f15c7bc6c2f14b74d0..47d54863a85992a16bb72207a2ed00ed60b96066 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float16x8_t a, float16_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f16        ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float16x8_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 66b6d8b00562fb49df7af2cb4c36eda19692d815..1b775eaf8a06a1298750f34c0a9441045e56137b 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float32x4_t a, float32_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f32        ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float32x4_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 9c5f1f2f5c8c543e40476984542abecb6c82e7cd..89d8e2b91096128693699b5fd0eea4f13508c025 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float16x8_t a, float16_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f16        gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
index 2723aa7f98f1e4942e16edb99730ee4b5e58bf6f..a5510e852d5bd91f90e213de8bfd7a30ac9f8dd0 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float32x4_t a, float32_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f32        gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float32x4_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 1d1f4bf0e58313b8cb5bd179a3e5d76592bc2a4a..c94b3119d59f33bdef345bc206b6e50159125154 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float16x8_t a, float16_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f16        le, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float16x8_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index bf77a80806432a1ef93188c6271a418a1d355388..80e2cfa1079117320621bc828d2d7c7d0b308d78 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float32x4_t a, float32_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f32        le, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float32x4_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index f9f091cd9b3811af6b045fcd141fd17c258617a5..c3a106455cbdae771ef1f17264283744bef95de2 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float16x8_t a, float16_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f16        lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float16x8_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index d22ea1aca305cfa3e3081cb330197246bd7395d7..b485f75e769e9b796d52f2023c686d47fa48621c 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float32x4_t a, float32_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f32        lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float32x4_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 83beca964d62c4aecd8350d645cc8b077afd8b20..1156caafda1eb925e4b01fc1f5390304a94f5707 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float16x8_t a, float16_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f16        ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float16x8_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index abe1abfed2aa260f159e570dba4efc434767dd0e..c3ffbd1335f5b5915669c674726b3980175628c8 100644 (file)
@@ -39,7 +39,7 @@ foo1 (float32x4_t a, float32_t b)
 }
 
 /*
-**foo2: { xfail *-*-* }
+**foo2:
 **     ...
 **     vcmp.f32        ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?:       @.*|)
 **     ...
@@ -56,4 +56,4 @@ foo2 (float32x4_t a)
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index bf05c73fc1d78e2a136a15a822318fa42617dbb7..dbbf854068142a2075572864e7ad53ca4feea33e 100644 (file)
@@ -42,8 +42,24 @@ foo1 (int16x8_t inactive, int16_t a, mve_pred16_t p)
   return vdupq_m (inactive, a, p);
 }
 
+/*
+**foo2:
+**     ...
+**     vmsr    p0, (?:ip|fp|r[0-9]+)(?:        @.*|)
+**     ...
+**     vpst(?: @.*|)
+**     ...
+**     vdupt.16        q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     ...
+*/
+int16x8_t
+foo2 (int16x8_t inactive, mve_pred16_t p)
+{
+  return vdupq_m (inactive, 1, p);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 71789bb620e0a2b84a5485113d2739df56bcc392..613b5d30fb3d62fc588121d153a796c2cf0b727f 100644 (file)
@@ -42,8 +42,24 @@ foo1 (int32x4_t inactive, int32_t a, mve_pred16_t p)
   return vdupq_m (inactive, a, p);
 }
 
+/*
+**foo2:
+**     ...
+**     vmsr    p0, (?:ip|fp|r[0-9]+)(?:        @.*|)
+**     ...
+**     vpst(?: @.*|)
+**     ...
+**     vdupt.32        q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     ...
+*/
+int32x4_t
+foo2 (int32x4_t inactive, mve_pred16_t p)
+{
+  return vdupq_m (inactive, 1, p);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 48c4fbd1f821c36b9f32ca21368c08eab88308cf..a1ff48e94e557844beb476a883c9cc4931495d72 100644 (file)
@@ -42,8 +42,24 @@ foo1 (int8x16_t inactive, int8_t a, mve_pred16_t p)
   return vdupq_m (inactive, a, p);
 }
 
+/*
+**foo2:
+**     ...
+**     vmsr    p0, (?:ip|fp|r[0-9]+)(?:        @.*|)
+**     ...
+**     vpst(?: @.*|)
+**     ...
+**     vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     ...
+*/
+int8x16_t
+foo2 (int8x16_t inactive, mve_pred16_t p)
+{
+  return vdupq_m (inactive, 1, p);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 44112190fb8750e84a433e6d38f7c421d9703e06..f9aae2fd1200a6c6982e3e43ea25ad86e2312ebb 100644 (file)
@@ -24,6 +24,7 @@ foo (float16_t a)
 /*
 **foo1:
 **     ...
+**     movw    r[0-9]+, #15462
 **     vdup.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
 **     ...
 */
@@ -37,4 +38,4 @@ foo1 ()
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32-2.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32-2.c
new file mode 100644 (file)
index 0000000..a4b0022
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* Test with a constant that fits in vmov.  */
+/*
+**foo1:
+**     ...
+**     vmov.f32        q[0-9]+, #0.0  .*
+**     ...
+*/
+float32x4_t
+foo1 ()
+{
+  return vdupq_n_f32 (0);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 059e3e42dd04f04c44e0c5add448999abffdaeb1..81c2e29f5e50860f99312a6a504609a12e6a3c59 100644 (file)
@@ -24,7 +24,8 @@ foo (float32_t a)
 /*
 **foo1:
 **     ...
-**     vdup.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     ldr     r[0-9]+, .L.*
+**     vdup.32 q[0-9]+, r[0-9]+
 **     ...
 */
 float32x4_t
@@ -37,4 +38,4 @@ foo1 ()
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16-2.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16-2.c
new file mode 100644 (file)
index 0000000..3fedbb1
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* Test with a constant that does not fit in vmov.  */
+/*
+**foo1:
+**     ...
+**     mov     r[0-9]+, #1000(?:       @.*|)
+**     vdup.16 q[0-9]+, r[0-9]+
+**     ...
+*/
+int16x8_t
+foo1 ()
+{
+  return vdupq_n_s16 (1000);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index d8ba299cb1580569abefe7778187ca0a8e36a1a1..f2746075a3bcb97c8690a352ab477d4da79d0291 100644 (file)
@@ -21,8 +21,20 @@ foo (int16_t a)
   return vdupq_n_s16 (a);
 }
 
+/*
+**foo1:
+**     ...
+**     vmov.i16        q[0-9]+, (#0x1)  (?:@.*|)
+**     ...
+*/
+int16x8_t
+foo1 ()
+{
+  return vdupq_n_s16 (1);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32-2.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32-2.c
new file mode 100644 (file)
index 0000000..3a4d32e
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* Test with a constant that does not fit in vmov.  */
+/*
+**foo1:
+**     ...
+**     mov     r[0-9]+, #1000
+**     vdup.32 q[0-9]+, r[0-9]+
+**     ...
+*/
+int32x4_t
+foo1 ()
+{
+  return vdupq_n_s32 (1000);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index a81c6d1e2201ce2b2c1a1f8dcb35bf2106e3b56f..7f75eca2ad220c25edc191de7f1ab02bdb72dc7b 100644 (file)
@@ -21,8 +21,20 @@ foo (int32_t a)
   return vdupq_n_s32 (a);
 }
 
+/*
+**foo1:
+**     ...
+**     vmov.i32        q[0-9]+, (#0x1)  (?:@.*|)
+**     ...
+*/
+int32x4_t
+foo1 ()
+{
+  return vdupq_n_s32 (1);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index b0bac4fce892e455f53165ca16ee0e9640ce08f9..454ff5abac239436934cd258fa07e118d04ba09d 100644 (file)
@@ -21,8 +21,20 @@ foo (int8_t a)
   return vdupq_n_s8 (a);
 }
 
+/*
+**foo1:
+**     ...
+**     vmov.i8 q[0-9]+, (#0x1)  (?:@.*|)
+**     ...
+*/
+int8x16_t
+foo1 ()
+{
+  return vdupq_n_s8 (1);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16-2.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16-2.c
new file mode 100644 (file)
index 0000000..accd7fa
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* Test with a constant that does not fit in vmov.  */
+/*
+**foo1:
+**     ...
+**     mov     r[0-9]+, #1000(?:       @.*|)
+**     vdup.16 q[0-9]+, r[0-9]+
+**     ...
+*/
+uint16x8_t
+foo1 ()
+{
+  return vdupq_n_u16 (1000);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 55e0a6011100e3026309345d9b1437b1ad10eda4..4accb6480dd6311dca11f86b2ade0c8be94d7634 100644 (file)
@@ -24,7 +24,7 @@ foo (uint16_t a)
 /*
 **foo1:
 **     ...
-**     vdup.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     vmov.i16        q[0-9]+, (#0x1)  (?:@.*|)
 **     ...
 */
 uint16x8_t
@@ -37,4 +37,4 @@ foo1 ()
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32-2.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32-2.c
new file mode 100644 (file)
index 0000000..03ea23c
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* Test with a constant that does not fit in vmov.  */
+/*
+**foo1:
+**     ...
+**     mov     r[0-9]+, #1000
+**     vdup.32 q[0-9]+, r[0-9]+
+**     ...
+*/
+uint32x4_t
+foo1 ()
+{
+  return vdupq_n_u32 (1000);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index bf73bc17fc704ce79c1274b9b45a75415b36f379..d08a94c7a16457ac1eb71a14838bfd18042a8c9f 100644 (file)
@@ -24,7 +24,7 @@ foo (uint32_t a)
 /*
 **foo1:
 **     ...
-**     vdup.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     vmov.i32        q[0-9]+, (#0x1)  (?:@.*|)
 **     ...
 */
 uint32x4_t
@@ -37,4 +37,4 @@ foo1 ()
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 48cbdb2a1daa2112799422fea11f2db361e79812..f1fcd4acaa396d6d09cf23c3601e4edfe86a171a 100644 (file)
@@ -24,7 +24,7 @@ foo (uint8_t a)
 /*
 **foo1:
 **     ...
-**     vdup.8  q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     vmov.i8 q[0-9]+, (#0x1)  (?:@.*|)
 **     ...
 */
 uint8x16_t
@@ -37,4 +37,4 @@ foo1 ()
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index 6756502ab21227b2a5b78a990bf98d6894da2363..9dcfe4e0376c4f911a6349dcb3fbf0a5717d599a 100644 (file)
@@ -25,8 +25,24 @@ foo (int16_t a, mve_pred16_t p)
   return vdupq_x_n_s16 (a, p);
 }
 
+/*
+**foo1:
+**     ...
+**     vmsr    p0, (?:ip|fp|r[0-9]+)(?:        @.*|)
+**     ...
+**     vpst(?: @.*|)
+**     ...
+**     vdupt.16        q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     ...
+*/
+int16x8_t
+foo1 (mve_pred16_t p)
+{
+  return vdupq_x_n_s16 (1, p);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index b04afb3834b6080e50c53bb200f428c45df63695..eacdb2e454f7311e337b223bf3c12938b509d909 100644 (file)
@@ -25,8 +25,24 @@ foo (int32_t a, mve_pred16_t p)
   return vdupq_x_n_s32 (a, p);
 }
 
+/*
+**foo1:
+**     ...
+**     vmsr    p0, (?:ip|fp|r[0-9]+)(?:        @.*|)
+**     ...
+**     vpst(?: @.*|)
+**     ...
+**     vdupt.32        q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     ...
+*/
+int32x4_t
+foo1 (mve_pred16_t p)
+{
+  return vdupq_x_n_s32 (1, p);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
index b23facd5e94b2572e634cb330974eed5ff2c9543..8951f7475f5d4249a20b18ad6e5146940b009501 100644 (file)
@@ -25,8 +25,24 @@ foo (int8_t a, mve_pred16_t p)
   return vdupq_x_n_s8 (a, p);
 }
 
+/*
+**foo1:
+**     ...
+**     vmsr    p0, (?:ip|fp|r[0-9]+)(?:        @.*|)
+**     ...
+**     vpst(?: @.*|)
+**     ...
+**     vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+**     ...
+*/
+int8x16_t
+foo1 (mve_pred16_t p)
+{
+  return vdupq_x_n_s8 (1, p);
+}
+
 #ifdef __cplusplus
 }
 #endif
 
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */