This patch fixes a problem in arm_expand_vcond() where the result
would be a vector of 0 or 1 instead of operand 1 or 2.  The
mve-vcmp-f32-2.c testcase is an update from mve-vcmp-f32.c using a
conditional with 2.0f and 3.0f constants to help scan-assembler-times.

2021-06-09  Christophe Lyon  <christophe.l...@linaro.org>

        gcc/
        * config/arm/arm.c (arm_expand_vcond): Fix select operands.

        gcc/testsuite/
        * gcc.target/arm/simd/mve-vcmp-f32-2.c: New test.
---
 gcc/config/arm/arm.c                          | 15 +++++----
 .../gcc.target/arm/simd/mve-vcmp-f32-2.c      | 32 +++++++++++++++++++
 2 files changed, 40 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32-2.c

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 9377aaef342..35e22382650 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -31164,7 +31164,7 @@ arm_expand_vcond (rtx *operands, machine_mode 
cmp_result_mode)
 
   if (TARGET_HAVE_MVE)
     {
-      vcond_mve=true;
+      vcond_mve = true;
       mask = gen_reg_rtx (HImode);
     }
   else
@@ -31181,18 +31181,19 @@ arm_expand_vcond (rtx *operands, machine_mode 
cmp_result_mode)
     {
       machine_mode cmp_mode = GET_MODE (operands[4]);
       rtx vpr_p0 = mask;
-      rtx zero = gen_reg_rtx (cmp_mode);
-      rtx one = gen_reg_rtx (cmp_mode);
-      emit_move_insn (zero, CONST0_RTX (cmp_mode));
-      emit_move_insn (one, CONST1_RTX (cmp_mode));
+
       switch (GET_MODE_CLASS (cmp_mode))
        {
        case MODE_VECTOR_INT:
-         emit_insn (gen_mve_vpselq (VPSELQ_S, cmp_result_mode, operands[0], 
one, zero, vpr_p0));
+         emit_insn (gen_mve_vpselq (VPSELQ_S, cmp_result_mode, operands[0],
+                                    operands[1], operands[2], vpr_p0));
          break;
        case MODE_VECTOR_FLOAT:
          if (TARGET_HAVE_MVE_FLOAT)
-           emit_insn (gen_mve_vpselq_f (cmp_mode, operands[0], one, zero, 
vpr_p0));
+           emit_insn (gen_mve_vpselq_f (cmp_mode, operands[0],
+                                        operands[1], operands[2], vpr_p0));
+         else
+           gcc_unreachable ();
          break;
        default:
          gcc_unreachable ();
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32-2.c 
b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32-2.c
new file mode 100644
index 00000000000..917a95bf141
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32-2.c
@@ -0,0 +1,32 @@
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O3 -funsafe-math-optimizations" } */
+
+#include <stdint.h>
+
+#define NB 4
+
+#define FUNC(OP, NAME)                                                 \
+  void test_ ## NAME ##_f (float * __restrict__ dest, float *a, float *b) { \
+    int i;                                                             \
+    for (i=0; i<NB; i++) {                                             \
+      dest[i] = (a[i] OP b[i]) ? 2.0f : 3.0f;                          \
+    }                                                                  \
+  }
+
+FUNC(==, vcmpeq)
+FUNC(!=, vcmpne)
+FUNC(<, vcmplt)
+FUNC(<=, vcmple)
+FUNC(>, vcmpgt)
+FUNC(>=, vcmpge)
+
+/* { dg-final { scan-assembler-times {\tvcmp.f32\teq, q[0-9]+, q[0-9]+\n} 1 } 
} */
+/* { dg-final { scan-assembler-times {\tvcmp.f32\tne, q[0-9]+, q[0-9]+\n} 1 } 
} */
+/* { dg-final { scan-assembler-times {\tvcmp.f32\tlt, q[0-9]+, q[0-9]+\n} 1 } 
} */
+/* { dg-final { scan-assembler-times {\tvcmp.f32\tle, q[0-9]+, q[0-9]+\n} 1 } 
} */
+/* { dg-final { scan-assembler-times {\tvcmp.f32\tgt, q[0-9]+, q[0-9]+\n} 1 } 
} */
+/* { dg-final { scan-assembler-times {\tvcmp.f32\tge, q[0-9]+, q[0-9]+\n} 1 } 
} */
+/* { dg-final { scan-assembler-times {\t.word\t1073741824\n} 24 } } */ /* 
Constant 2.0f.  */
+/* { dg-final { scan-assembler-times {\t.word\t1077936128\n} 24 } } */ /* 
Constant 3.0f.  */
-- 
2.25.1

Reply via email to