From: Kyrylo Tkachov <[email protected]>

Arm fixed-point vector modes are SIMD32 modes held in core registers.  They
do not have Neon or MVE immediate moves.

arm_legitimate_constant_p_1 asks neon_make_constant about each vector
constant.  neon_make_constant passes fixed-point vectors to the SIMD
immediate classifier, which expects CONST_INT elements.  A fixed-point
vector has CONST_FIXED elements, so a checking compiler fails instead of
using the constant pool.

For a nonuniform V4QQ constant at

  -O2 -mcpu=unset -march=armv6+fp -marm

the checking compiler fails in simd_valid_immediate before the change.  After
the change, the constant uses the existing literal-pool path:

  ldr     r3, .L3
  str     r3, [r0]
  ...
 .L3:
  .word   6307872

Return a fixed-point CONST_VECTOR through that path.  The generic constant
output code already emits fixed-point vector elements.

Tested on arm-linux-gnueabihf with QEMU.
Ok for trunk?
Thanks,
Kyrill

gcc/ChangeLog:

        * config/arm/arm.cc (neon_make_constant): Send fixed-point vector
        constants to the constant pool.

gcc/testsuite/ChangeLog:

        * gcc.target/arm/fixed-point-vector-const-1.c: New test.

Signed-off-by: Kyrylo Tkachov <[email protected]>
---
 gcc/config/arm/arm.cc                                |  4 ++++
 .../gcc.target/arm/fixed-point-vector-const-1.c      | 12 ++++++++++++
 2 files changed, 16 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/arm/fixed-point-vector-const-1.c

diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 0bc66abe238..36cdf19d58f 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -13652,6 +13652,10 @@ neon_make_constant (rtx vals, bool generate)
   else
     gcc_unreachable ();
 
+  /* Load fixed-point vector constants from the constant pool.  */
+  if (ALL_FIXED_POINT_MODE_P (mode))
+    return arm_disable_literal_pool ? NULL_RTX : const_vec;
+
   if (const_vec != NULL
       && simd_immediate_valid_for_move (const_vec, mode, NULL, NULL))
     /* Load using VMOV.  On Cortex-A8 this takes one cycle.  */
diff --git a/gcc/testsuite/gcc.target/arm/fixed-point-vector-const-1.c 
b/gcc/testsuite/gcc.target/arm/fixed-point-vector-const-1.c
new file mode 100644
index 00000000000..098419bbd5a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/fixed-point-vector-const-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target fixed_point } } */
+/* { dg-require-effective-target arm_arch_v6_arm_ok } */
+/* { dg-options "-O2 -std=gnu99" } */
+/* { dg-add-options arm_arch_v6_arm } */
+
+typedef short _Fract v4qq __attribute__ ((vector_size (4)));
+
+void
+f (v4qq *out)
+{
+  *out = (v4qq) { 0.25hr, 0.5hr, 0.75hr, 0.0hr };
+}
-- 
2.50.1 (Apple Git-155)

Reply via email to