arm: MVE: Fix vec extracts to memory
authorAndre Simoes Dias Vieira <andre.simoesdiasvieira@arm.com>
Tue, 7 Apr 2020 14:29:31 +0000 (15:29 +0100)
committerAndre Vieira <andre.simoesdiasvieira@arm.com>
Tue, 7 Apr 2020 14:44:52 +0000 (15:44 +0100)
This patch fixes vec extracts to memory that can arise from code as seen in the
testcase added. The patch fixes this by allowing mem operands in the set of
mve_vec_extract patterns, which given the only '=r' constraint will lead to the
scalar value being written to a register and then stored in memory using scalar
store pattern.

gcc/ChangeLog:
2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>

* config/arm/mve.md (mve_vec_extract*): Allow memory operands in set.

gcc/testsuite/ChangeLog:
2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>

* gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c: New
test.

gcc/ChangeLog
gcc/config/arm/mve.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c [new file with mode: 0644]

index b9ee1817e006705717ade42cd36f761225d39fb7..b71e45aa9d495bdc0eb63cf00362a4eddc1cad63 100644 (file)
@@ -1,3 +1,7 @@
+2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+       * config/arm/mve.md (mve_vec_extract*): Allow memory operands in set.
+
 2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
        * config/arm/arm.c (arm_mve_immediate_check): Removed.
index 3c75f9ebc70d5765a59934b944955c757b6b2195..c49c14c4240838ce086f424f58726e2e94cf190e 100644 (file)
 ;; [vgetq_lane_u, vgetq_lane_s, vgetq_lane_f])
 ;;
 (define_insn "mve_vec_extract<mode><V_elem_l>"
- [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
+ [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=r")
    (vec_select:<V_elem>
     (match_operand:MVE_VLD_ST 1 "s_register_operand" "w")
     (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
  [(set_attr "type" "mve_move")])
 
 (define_insn "mve_vec_extractv2didi"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r")
    (vec_select:DI
     (match_operand:V2DI 1 "s_register_operand" "w")
     (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
   if (elt == 0)
    return "vmov\t%Q0, %R0, %e1";
   else
-   return "vmov\t%J0, %K0, %f1";
+   return "vmov\t%Q0, %R0, %f1";
 }
  [(set_attr "type" "mve_move")])
 
index 6b44c3484477fec0749ff64ecd2e2fb64617fa65..fe79c5c34f5b5a9db63433cafb6095f6d134d25a 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+       * gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c: New
+       test.
+
 2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
        * gcc.target/arm/mve/intrinsics/mve_immediates_1_n.c: New test.
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c
new file mode 100644 (file)
index 0000000..12f2f2d
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O3" } */
+
+#include "arm_mve.h"
+
+uint8x16_t *vu8;
+int8x16_t *vs8;
+uint16x8_t *vu16;
+int16x8_t *vs16;
+uint32x4_t *vu32;
+int32x4_t *vs32;
+uint64x2_t *vu64;
+int64x2_t *vs64;
+float16x8_t *vf16;
+float32x4_t *vf32;
+uint8_t u8;
+uint16_t u16;
+uint32_t u32;
+uint64_t u64;
+int8_t s8;
+int16_t s16;
+int32_t s32;
+int64_t s64;
+float16_t f16;
+float32_t f32;
+
+void foo (void)
+{
+  u8 = vgetq_lane (*vu8, 1);
+  u16 = vgetq_lane (*vu16, 1);
+  u32 = vgetq_lane (*vu32, 1);
+  u64 = vgetq_lane (*vu64, 1);
+  s8 = vgetq_lane (*vs8, 1);
+  s16 = vgetq_lane (*vs16, 1);
+  s32 = vgetq_lane (*vs32, 1);
+  s64 = vgetq_lane (*vs64, 1);
+  f16 = vgetq_lane (*vf16, 1);
+  f32 = vgetq_lane (*vf32, 1);
+}