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