Skip to content

Commit 4731ead

Browse files
Jiahao Xuchenglulu326
authored andcommitted
LoongArch: Support immediate_operand for vec_cmp
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 (vec_cmp<mode><mode256_i>): Remove. (vec_cmpu<ILASX:mode><mode256_i>): Remove. * config/loongarch/loongarch.cc (loongarch_expand_lsx_cmp): Ensure vector comparison instructions support CMP_OP1. * config/loongarch/lsx.md (vec_cmp<mode><mode_i>): Remove. (vec_cmpu<ILSX:mode><mode_i>): Remove. * config/loongarch/simd.md (ALLVEC, allmode_i): New mode iterators. (vec_cmp<mode><allmode_i>): New define_expand. (vec_cmpu<mode><allmode_i>): Likewise. gcc/testsuite/ChangeLog: * gcc.target/loongarch/vector/lasx/lasx-vcond-3.c: New test.
1 parent c6f7a29 commit 4731ead

File tree

5 files changed

+133
-50
lines changed

5 files changed

+133
-50
lines changed

gcc/config/loongarch/lasx.md

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,6 @@
162162
UNSPEC_LASX_XVILVL_INTERNAL
163163
])
164164

165-
;; All vector modes with 256 bits.
166-
(define_mode_iterator LASX [V4DF V8SF V4DI V8SI V16HI V32QI])
167-
168165
;; Only used for splitting insert_d and copy_{u,s}.d.
169166
(define_mode_iterator LASX_D [V4DI V4DF])
170167

@@ -1365,28 +1362,6 @@
13651362
[(set_attr "type" "simd_int_arith")
13661363
(set_attr "mode" "<MODE>")])
13671364

1368-
(define_expand "vec_cmp<mode><mode256_i>"
1369-
[(set (match_operand:<VIMODE256> 0 "register_operand")
1370-
(match_operator 1 ""
1371-
[(match_operand:LASX 2 "register_operand")
1372-
(match_operand:LASX 3 "register_operand")]))]
1373-
"ISA_HAS_LASX"
1374-
{
1375-
loongarch_expand_vec_cmp (operands);
1376-
DONE;
1377-
})
1378-
1379-
(define_expand "vec_cmpu<ILASX:mode><mode256_i>"
1380-
[(set (match_operand:<VIMODE256> 0 "register_operand")
1381-
(match_operator 1 ""
1382-
[(match_operand:ILASX 2 "register_operand")
1383-
(match_operand:ILASX 3 "register_operand")]))]
1384-
"ISA_HAS_LASX"
1385-
{
1386-
loongarch_expand_vec_cmp (operands);
1387-
DONE;
1388-
})
1389-
13901365
(define_insn "lasx_xvfclass_<flasxfmt>"
13911366
[(set (match_operand:<VIMODE256> 0 "register_operand" "=f")
13921367
(unspec:<VIMODE256> [(match_operand:FLASX 1 "register_operand" "f")]

gcc/config/loongarch/loongarch.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10399,19 +10399,29 @@ loongarch_expand_lsx_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1)
1039910399
switch (cond)
1040010400
{
1040110401
case NE:
10402+
if (!loongarch_const_vector_same_int_p (op1, cmp_mode, -16, 15))
10403+
op1 = force_reg (cmp_mode, op1);
1040210404
cond = reverse_condition (cond);
1040310405
negate = true;
1040410406
break;
1040510407
case EQ:
1040610408
case LT:
1040710409
case LE:
10410+
if (!loongarch_const_vector_same_int_p (op1, cmp_mode, -16, 15))
10411+
op1 = force_reg (cmp_mode, op1);
10412+
break;
1040810413
case LTU:
1040910414
case LEU:
10415+
if (!loongarch_const_vector_same_int_p (op1, cmp_mode, 0, 31))
10416+
op1 = force_reg (cmp_mode, op1);
1041010417
break;
1041110418
case GE:
1041210419
case GT:
1041310420
case GEU:
1041410421
case GTU:
10422+
/* Only supports reg-reg comparison. */
10423+
if (!register_operand (op1, cmp_mode))
10424+
op1 = force_reg (cmp_mode, op1);
1041510425
std::swap (op0, op1);
1041610426
cond = swap_condition (cond);
1041710427
break;
@@ -10427,6 +10437,8 @@ loongarch_expand_lsx_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1)
1042710437
case E_V2DFmode:
1042810438
case E_V8SFmode:
1042910439
case E_V4DFmode:
10440+
if (!register_operand (op1, cmp_mode))
10441+
op1 = force_reg (cmp_mode, op1);
1043010442
loongarch_emit_binary (cond, dest, op0, op1);
1043110443
break;
1043210444

gcc/config/loongarch/lsx.md

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,6 @@
183183
(V8HI "V2DI")
184184
(V16QI "V4SI")])
185185

186-
;; All vector modes with 128 bits.
187-
(define_mode_iterator LSX [V2DF V4SF V2DI V4SI V8HI V16QI])
188-
189186
;; Only used for vilvh and splitting insert_d and copy_{u,s}.d.
190187
(define_mode_iterator LSX_D [V2DI V2DF])
191188

@@ -508,28 +505,6 @@
508505
DONE;
509506
})
510507

511-
(define_expand "vec_cmp<mode><mode_i>"
512-
[(set (match_operand:<VIMODE> 0 "register_operand")
513-
(match_operator 1 ""
514-
[(match_operand:LSX 2 "register_operand")
515-
(match_operand:LSX 3 "register_operand")]))]
516-
"ISA_HAS_LSX"
517-
{
518-
loongarch_expand_vec_cmp (operands);
519-
DONE;
520-
})
521-
522-
(define_expand "vec_cmpu<ILSX:mode><mode_i>"
523-
[(set (match_operand:<VIMODE> 0 "register_operand")
524-
(match_operator 1 ""
525-
[(match_operand:ILSX 2 "register_operand")
526-
(match_operand:ILSX 3 "register_operand")]))]
527-
"ISA_HAS_LSX"
528-
{
529-
loongarch_expand_vec_cmp (operands);
530-
DONE;
531-
})
532-
533508
(define_expand "vcond_mask_<mode><mode_i>"
534509
[(match_operand:LSX 0 "register_operand")
535510
(match_operand:LSX 1 "reg_or_m1_operand")

gcc/config/loongarch/simd.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,21 @@
2929
;; FP modes supported by LASX
3030
(define_mode_iterator FLASX [V4DF V8SF])
3131

32+
;; All modes supported by LSX
33+
(define_mode_iterator LSX [ILSX FLSX])
34+
35+
;; ALL modes supported by LASX
36+
(define_mode_iterator LASX [ILASX FLASX])
37+
3238
;; All integer modes available
3339
(define_mode_iterator IVEC [(ILSX "ISA_HAS_LSX") (ILASX "ISA_HAS_LASX")])
3440

3541
;; All FP modes available
3642
(define_mode_iterator FVEC [(FLSX "ISA_HAS_LSX") (FLASX "ISA_HAS_LASX")])
3743

44+
;; All vector modes available
45+
(define_mode_iterator ALLVEC [(LSX "ISA_HAS_LSX") (LASX "ISA_HAS_LASX")])
46+
3847
;; Mnemonic prefix, "x" for LASX modes.
3948
(define_mode_attr x [(V2DI "") (V4SI "") (V8HI "") (V16QI "")
4049
(V2DF "") (V4SF "")
@@ -72,6 +81,14 @@
7281
(define_mode_attr vimode [(V2DF "v2di") (V4SF "v4si")
7382
(V4DF "v4di") (V8SF "v8si")])
7483

84+
;; Integer vector modes with the same size, in lower-case.
85+
(define_mode_attr allmode_i [(V2DI "v2di") (V4SI "v4si")
86+
(V8HI "v8hi") (V16QI "v16qi")
87+
(V2DF "v2di") (V4SF "v4si")
88+
(V4DI "v4di") (V8SI "v8si")
89+
(V16HI "v16hi") (V32QI "v32qi")
90+
(V4DF "v4di") (V8SF "v8si")])
91+
7592
;; Suffix for LSX or LASX instructions.
7693
(define_mode_attr simdfmt [(V2DF "d") (V4DF "d")
7794
(V4SF "s") (V8SF "s")
@@ -476,6 +493,29 @@
476493
[(set_attr "type" "simd_logic")
477494
(set_attr "mode" "<MODE>")])
478495

496+
;; vector compare
497+
(define_expand "vec_cmp<mode><allmode_i>"
498+
[(set (match_operand:<VIMODE> 0 "register_operand")
499+
(match_operator 1 ""
500+
[(match_operand:ALLVEC 2 "register_operand")
501+
(match_operand:ALLVEC 3 "nonmemory_operand")]))]
502+
""
503+
{
504+
loongarch_expand_vec_cmp (operands);
505+
DONE;
506+
})
507+
508+
(define_expand "vec_cmpu<mode><allmode_i>"
509+
[(set (match_operand:<VIMODE> 0 "register_operand")
510+
(match_operator 1 ""
511+
[(match_operand:IVEC 2 "register_operand")
512+
(match_operand:IVEC 3 "nonmemory_operand")]))]
513+
""
514+
{
515+
loongarch_expand_vec_cmp (operands);
516+
DONE;
517+
})
518+
479519
; The LoongArch SX Instructions.
480520
(include "lsx.md")
481521

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2 -ftree-vectorize -fno-unroll-loops -fno-vect-cost-model -mlasx" } */
3+
4+
#include <stdint-gcc.h>
5+
6+
#define DEF_VCOND_VAR(DATA_TYPE, CMP_TYPE, COND, SUFFIX, IMM) \
7+
void __attribute__ ((noinline, noclone)) \
8+
vcond_var_##CMP_TYPE##_##SUFFIX (DATA_TYPE *__restrict__ r, \
9+
DATA_TYPE *__restrict__ x, \
10+
DATA_TYPE *__restrict__ y, \
11+
CMP_TYPE *__restrict__ a, \
12+
int n) \
13+
{ \
14+
for (int i = 0; i < n; i++) \
15+
{ \
16+
DATA_TYPE xval = x[i], yval = y[i]; \
17+
CMP_TYPE aval = a[i], bval = IMM; \
18+
r[i] = aval COND bval ? xval : yval; \
19+
} \
20+
}
21+
22+
#define TEST_COND_VAR_SIGNED_ALL(T, COND, SUFFIX) \
23+
T (int8_t, int8_t, COND, SUFFIX, 0) \
24+
T (int16_t, int16_t, COND, SUFFIX, 0) \
25+
T (int32_t, int32_t, COND, SUFFIX, 0) \
26+
T (int64_t, int64_t, COND, SUFFIX, 0) \
27+
T (float, int32_t, COND, SUFFIX##_float, 0) \
28+
T (double, int64_t, COND, SUFFIX##_double, 0)
29+
30+
#define TEST_COND_VAR_UNSIGNED_ALL(T, COND, SUFFIX) \
31+
T (uint8_t, uint8_t, COND, SUFFIX, 2) \
32+
T (uint16_t, uint16_t, COND, SUFFIX, 2) \
33+
T (uint32_t, uint32_t, COND, SUFFIX, 2) \
34+
T (uint64_t, uint64_t, COND, SUFFIX, 2) \
35+
T (float, uint32_t, COND, SUFFIX##_float, 2) \
36+
T (double, uint64_t, COND, SUFFIX##_double, 2)
37+
38+
#define TEST_COND_VAR_ALL(T, COND, SUFFIX) \
39+
TEST_COND_VAR_SIGNED_ALL (T, COND, SUFFIX) \
40+
TEST_COND_VAR_UNSIGNED_ALL (T, COND, SUFFIX)
41+
42+
#define TEST_VAR_ALL(T) \
43+
TEST_COND_VAR_ALL (T, <, _lt) \
44+
TEST_COND_VAR_ALL (T, <=, _le) \
45+
TEST_COND_VAR_ALL (T, ==, _eq) \
46+
TEST_COND_VAR_ALL (T, !=, _ne)
47+
48+
TEST_VAR_ALL (DEF_VCOND_VAR)
49+
50+
/* { dg-final { scan-assembler-times {\txvslti\.b\t} 1 } } */
51+
/* { dg-final { scan-assembler-times {\txvslti\.h\t} 1 } } */
52+
/* { dg-final { scan-assembler-times {\txvslti\.w\t} 2 } } */
53+
/* { dg-final { scan-assembler-times {\txvslti\.d\t} 2 } } */
54+
/* { dg-final { scan-assembler-times {\tvslti\.b\t} 1 } } */
55+
/* { dg-final { scan-assembler-times {\tvslti\.h\t} 1 } } */
56+
/* { dg-final { scan-assembler-times {\tvslti\.w\t} 2 } } */
57+
/* { dg-final { scan-assembler-times {\tvslti\.d\t} 2 } } */
58+
/* { dg-final { scan-assembler-times {\txvslei\.b\t} 1 } } */
59+
/* { dg-final { scan-assembler-times {\txvslei\.h\t} 1 } } */
60+
/* { dg-final { scan-assembler-times {\txvslei\.w\t} 2 } } */
61+
/* { dg-final { scan-assembler-times {\txvslei\.d\t} 2 } } */
62+
/* { dg-final { scan-assembler-times {\tvslei\.b\t} 1 } } */
63+
/* { dg-final { scan-assembler-times {\tvslei\.h\t} 1 } } */
64+
/* { dg-final { scan-assembler-times {\tvslei\.w\t} 2 } } */
65+
/* { dg-final { scan-assembler-times {\tvslei\.d\t} 2 } } */
66+
/* { dg-final { scan-assembler-times {\txvslei\.bu\t} 2 } } */
67+
/* { dg-final { scan-assembler-times {\txvslei\.hu\t} 2 } } */
68+
/* { dg-final { scan-assembler-times {\txvslei\.wu\t} 4 } } */
69+
/* { dg-final { scan-assembler-times {\txvslei\.du\t} 4 } } */
70+
/* { dg-final { scan-assembler-times {\tvslei\.bu\t} 2 } } */
71+
/* { dg-final { scan-assembler-times {\tvslei\.hu\t} 2 } } */
72+
/* { dg-final { scan-assembler-times {\tvslei\.wu\t} 4 } } */
73+
/* { dg-final { scan-assembler-times {\tvslei\.du\t} 4 } } */
74+
/* { dg-final { scan-assembler-times {\txvseqi\.b\t} 4 } } */
75+
/* { dg-final { scan-assembler-times {\txvseqi\.h\t} 4 } } */
76+
/* { dg-final { scan-assembler-times {\txvseqi\.w\t} 8 } } */
77+
/* { dg-final { scan-assembler-times {\txvseqi\.d\t} 8 } } */
78+
/* { dg-final { scan-assembler-times {\tvseqi\.b\t} 4 } } */
79+
/* { dg-final { scan-assembler-times {\tvseqi\.h\t} 4 } } */
80+
/* { dg-final { scan-assembler-times {\tvseqi\.w\t} 8 } } */
81+
/* { dg-final { scan-assembler-times {\tvseqi\.d\t} 8 } } */

0 commit comments

Comments
 (0)