We can't vectorize the code into instructions like vslti.w that compare
with immediate_operand, because we miss immediate_operand support for
integer comparisons.

gcc/ChangeLog:

        * config/loongarch/lasx.md: Support immediate_operand.
        * config/loongarch/loongarch.cc (loongarch_expand_lsx_cmp):
        Ensure vector comparison instructions support CMP_OP1.
        * config/loongarch/lsx.md: Support immediate_operand.

gcc/testsuite/ChangeLog:

        * gcc.target/loongarch/vector/lasx/lasx-vcond-3.c: New test.
---
 gcc/config/loongarch/lasx.md                  |  4 +-
 gcc/config/loongarch/loongarch.cc             |  5 ++
 gcc/config/loongarch/lsx.md                   |  4 +-
 .../loongarch/vector/lasx/lasx-vcond-3.c      | 81 +++++++++++++++++++
 4 files changed, 90 insertions(+), 4 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-3.c

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 90778dd8ff9..2f485de8a65 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -1369,7 +1369,7 @@
   [(set (match_operand:<VIMODE256> 0 "register_operand")
        (match_operator 1 ""
          [(match_operand:LASX 2 "register_operand")
-          (match_operand:LASX 3 "register_operand")]))]
+          (match_operand:LASX 3 "reg_or_vector_same_simm5_operand")]))]
   "ISA_HAS_LASX"
 {
   loongarch_expand_vec_cmp (operands);
@@ -1380,7 +1380,7 @@
   [(set (match_operand:<VIMODE256> 0 "register_operand")
        (match_operator 1 ""
          [(match_operand:ILASX 2 "register_operand")
-          (match_operand:ILASX 3 "register_operand")]))]
+          (match_operand:ILASX 3 "reg_or_vector_same_uimm5_operand")]))]
   "ISA_HAS_LASX"
 {
   loongarch_expand_vec_cmp (operands);
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 125ecc26c9c..58129295b89 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -10412,6 +10412,9 @@ loongarch_expand_lsx_cmp (rtx dest, enum rtx_code cond, 
rtx op0, rtx op1)
        case GT:
        case GEU:
        case GTU:
+         /* Only supports reg-reg comparison.  */
+         if (!register_operand (op1, cmp_mode))
+           op1 = force_reg (cmp_mode, op1);
          std::swap (op0, op1);
          cond = swap_condition (cond);
          break;
@@ -10427,6 +10430,8 @@ loongarch_expand_lsx_cmp (rtx dest, enum rtx_code cond, 
rtx op0, rtx op1)
     case E_V2DFmode:
     case E_V8SFmode:
     case E_V4DFmode:
+      if (!register_operand (op1, cmp_mode))
+       op1 = force_reg (cmp_mode, op1);
       loongarch_emit_binary (cond, dest, op0, op1);
       break;
 
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 2466d8c87be..e51bd18d511 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -512,7 +512,7 @@
   [(set (match_operand:<VIMODE> 0 "register_operand")
        (match_operator 1 ""
          [(match_operand:LSX 2 "register_operand")
-          (match_operand:LSX 3 "register_operand")]))]
+          (match_operand:LSX 3 "reg_or_vector_same_simm5_operand")]))]
   "ISA_HAS_LSX"
 {
   loongarch_expand_vec_cmp (operands);
@@ -523,7 +523,7 @@
   [(set (match_operand:<VIMODE> 0 "register_operand")
        (match_operator 1 ""
          [(match_operand:ILSX 2 "register_operand")
-          (match_operand:ILSX 3 "register_operand")]))]
+          (match_operand:ILSX 3 "reg_or_vector_same_uimm5_operand")]))]
   "ISA_HAS_LSX"
 {
   loongarch_expand_vec_cmp (operands);
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-3.c 
b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-3.c
new file mode 100644
index 00000000000..0c3d9de2580
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vcond-3.c
@@ -0,0 +1,81 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-unroll-loops -fno-vect-cost-model 
-mlasx" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_VCOND_VAR(DATA_TYPE, CMP_TYPE, COND, SUFFIX, IMM)  \
+  void __attribute__ ((noinline, noclone))                     \
+  vcond_var_##CMP_TYPE##_##SUFFIX (DATA_TYPE *__restrict__ r,  \
+                                  DATA_TYPE *__restrict__ x,   \
+                                  DATA_TYPE *__restrict__ y,   \
+                                  CMP_TYPE *__restrict__ a,    \
+                                  int n)                       \
+  {                                                            \
+    for (int i = 0; i < n; i++)                                        \
+      {                                                                \
+       DATA_TYPE xval = x[i], yval = y[i];                     \
+       CMP_TYPE aval = a[i], bval = IMM;                       \
+       r[i] = aval COND bval ? xval : yval;                    \
+      }                                                                \
+  }
+
+#define TEST_COND_VAR_SIGNED_ALL(T, COND, SUFFIX)      \
+  T (int8_t, int8_t, COND, SUFFIX, 0)                  \
+  T (int16_t, int16_t, COND, SUFFIX, 0)                        \
+  T (int32_t, int32_t, COND, SUFFIX, 0)                        \
+  T (int64_t, int64_t, COND, SUFFIX, 0)                        \
+  T (float, int32_t, COND, SUFFIX##_float, 0)          \
+  T (double, int64_t, COND, SUFFIX##_double, 0)
+
+#define TEST_COND_VAR_UNSIGNED_ALL(T, COND, SUFFIX)    \
+  T (uint8_t, uint8_t, COND, SUFFIX, 2)                        \
+  T (uint16_t, uint16_t, COND, SUFFIX, 2)              \
+  T (uint32_t, uint32_t, COND, SUFFIX, 2)              \
+  T (uint64_t, uint64_t, COND, SUFFIX, 2)              \
+  T (float, uint32_t, COND, SUFFIX##_float, 2)         \
+  T (double, uint64_t, COND, SUFFIX##_double, 2)
+
+#define TEST_COND_VAR_ALL(T, COND, SUFFIX)     \
+  TEST_COND_VAR_SIGNED_ALL (T, COND, SUFFIX)   \
+  TEST_COND_VAR_UNSIGNED_ALL (T, COND, SUFFIX)
+
+#define TEST_VAR_ALL(T)                                \
+  TEST_COND_VAR_ALL (T, <, _lt)                        \
+  TEST_COND_VAR_ALL (T, <=, _le)               \
+  TEST_COND_VAR_ALL (T, ==, _eq)               \
+  TEST_COND_VAR_ALL (T, !=, _ne)
+
+TEST_VAR_ALL (DEF_VCOND_VAR)
+
+/* { dg-final { scan-assembler-times {\txvslti\.b\t} 1 } } */
+/* { dg-final { scan-assembler-times {\txvslti\.h\t} 1 } } */
+/* { dg-final { scan-assembler-times {\txvslti\.w\t} 2 } } */
+/* { dg-final { scan-assembler-times {\txvslti\.d\t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvslti\.b\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tvslti\.h\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tvslti\.w\t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvslti\.d\t} 2 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.b\t} 1 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.h\t} 1 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.w\t} 2 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.d\t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.b\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.h\t} 1 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.w\t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.d\t} 2 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.bu\t} 2 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.hu\t} 2 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.wu\t} 4 } } */
+/* { dg-final { scan-assembler-times {\txvslei\.du\t} 4 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.bu\t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.hu\t} 2 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.wu\t} 4 } } */
+/* { dg-final { scan-assembler-times {\tvslei\.du\t} 4 } } */
+/* { dg-final { scan-assembler-times {\txvseqi\.b\t} 4 } } */
+/* { dg-final { scan-assembler-times {\txvseqi\.h\t} 4 } } */
+/* { dg-final { scan-assembler-times {\txvseqi\.w\t} 8 } } */
+/* { dg-final { scan-assembler-times {\txvseqi\.d\t} 8 } } */
+/* { dg-final { scan-assembler-times {\tvseqi\.b\t} 4 } } */
+/* { dg-final { scan-assembler-times {\tvseqi\.h\t} 4 } } */
+/* { dg-final { scan-assembler-times {\tvseqi\.w\t} 8 } } */
+/* { dg-final { scan-assembler-times {\tvseqi\.d\t} 8 } } */
-- 
2.20.1

Reply via email to