Skip to content

Commit ca66df3

Browse files
committed
[LoongArch] Add more and/or/xor patterns for vector types
1 parent 56bbf81 commit ca66df3

File tree

8 files changed

+774
-18
lines changed

8 files changed

+774
-18
lines changed

llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,10 +1184,6 @@ multiclass PatShiftXrUimm<SDPatternOperator OpNode, string Inst> {
11841184
(!cast<LAInst>(Inst#"_D") LASX256:$xj, uimm6:$imm)>;
11851185
}
11861186

1187-
class PatXrXrB<SDPatternOperator OpNode, LAInst Inst>
1188-
: Pat<(OpNode (v32i8 LASX256:$xj), (v32i8 LASX256:$xk)),
1189-
(Inst LASX256:$xj, LASX256:$xk)>;
1190-
11911187
let Predicates = [HasExtLASX] in {
11921188

11931189
// XVADD_{B/H/W/D}
@@ -1235,13 +1231,20 @@ defm : PatXrXr<srem, "XVMOD">;
12351231
defm : PatXrXrU<urem, "XVMOD">;
12361232

12371233
// XVAND_V
1238-
def : PatXrXrB<and, XVAND_V>;
1239-
// XVNOR_V
1240-
def : PatXrXrB<or, XVOR_V>;
1234+
foreach vt = [v32i8, v16i16, v8i32, v4i64] in
1235+
def : Pat<(and (vt LASX256:$xj), (vt LASX256:$xk)),
1236+
(XVAND_V LASX256:$xj, LASX256:$xk)>;
1237+
// XVOR_V
1238+
foreach vt = [v32i8, v16i16, v8i32, v4i64] in
1239+
def : Pat<(or (vt LASX256:$xj), (vt LASX256:$xk)),
1240+
(XVOR_V LASX256:$xj, LASX256:$xk)>;
12411241
// XVXOR_V
1242-
def : PatXrXrB<xor, XVXOR_V>;
1242+
foreach vt = [v32i8, v16i16, v8i32, v4i64] in
1243+
def : Pat<(xor (vt LASX256:$xj), (vt LASX256:$xk)),
1244+
(XVXOR_V LASX256:$xj, LASX256:$xk)>;
12431245
// XVNOR_V
1244-
def : Pat<(vnot (or (v32i8 LASX256:$xj), (v32i8 LASX256:$xk))),
1246+
foreach vt = [v32i8, v16i16, v8i32, v4i64] in
1247+
def : Pat<(vnot (or (vt LASX256:$xj), (vt LASX256:$xk))),
12451248
(XVNOR_V LASX256:$xj, LASX256:$xk)>;
12461249

12471250
// XVANDI_B

llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,10 +1261,6 @@ multiclass PatShiftVrUimm<SDPatternOperator OpNode, string Inst> {
12611261
(!cast<LAInst>(Inst#"_D") LSX128:$vj, uimm6:$imm)>;
12621262
}
12631263

1264-
class PatVrVrB<SDPatternOperator OpNode, LAInst Inst>
1265-
: Pat<(OpNode (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)),
1266-
(Inst LSX128:$vj, LSX128:$vk)>;
1267-
12681264
let Predicates = [HasExtLSX] in {
12691265

12701266
// VADD_{B/H/W/D}
@@ -1312,13 +1308,20 @@ defm : PatVrVr<srem, "VMOD">;
13121308
defm : PatVrVrU<urem, "VMOD">;
13131309

13141310
// VAND_V
1315-
def : PatVrVrB<and, VAND_V>;
1316-
// VNOR_V
1317-
def : PatVrVrB<or, VOR_V>;
1311+
foreach vt = [v16i8, v8i16, v4i32, v2i64] in
1312+
def : Pat<(and (vt LSX128:$vj), (vt LSX128:$vk)),
1313+
(VAND_V LSX128:$vj, LSX128:$vk)>;
1314+
// VOR_V
1315+
foreach vt = [v16i8, v8i16, v4i32, v2i64] in
1316+
def : Pat<(or (vt LSX128:$vj), (vt LSX128:$vk)),
1317+
(VOR_V LSX128:$vj, LSX128:$vk)>;
13181318
// VXOR_V
1319-
def : PatVrVrB<xor, VXOR_V>;
1319+
foreach vt = [v16i8, v8i16, v4i32, v2i64] in
1320+
def : Pat<(xor (vt LSX128:$vj), (vt LSX128:$vk)),
1321+
(VXOR_V LSX128:$vj, LSX128:$vk)>;
13201322
// VNOR_V
1321-
def : Pat<(vnot (or (v16i8 LSX128:$vj), (v16i8 LSX128:$vk))),
1323+
foreach vt = [v16i8, v8i16, v4i32, v2i64] in
1324+
def : Pat<(vnot (or (vt LSX128:$vj), (vt LSX128:$vk))),
13221325
(VNOR_V LSX128:$vj, LSX128:$vk)>;
13231326

13241327
// VANDI_B
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2+
; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
3+
4+
define void @and_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind {
5+
; CHECK-LABEL: and_v32i8:
6+
; CHECK: # %bb.0: # %entry
7+
; CHECK-NEXT: xvld $xr0, $a2, 0
8+
; CHECK-NEXT: xvld $xr1, $a1, 0
9+
; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
10+
; CHECK-NEXT: xvst $xr0, $a0, 0
11+
; CHECK-NEXT: ret
12+
entry:
13+
%v0 = load <32 x i8>, ptr %a0
14+
%v1 = load <32 x i8>, ptr %a1
15+
%v2 = and <32 x i8> %v0, %v1
16+
store <32 x i8> %v2, ptr %res
17+
ret void
18+
}
19+
20+
define void @and_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind {
21+
; CHECK-LABEL: and_v16i16:
22+
; CHECK: # %bb.0: # %entry
23+
; CHECK-NEXT: xvld $xr0, $a2, 0
24+
; CHECK-NEXT: xvld $xr1, $a1, 0
25+
; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
26+
; CHECK-NEXT: xvst $xr0, $a0, 0
27+
; CHECK-NEXT: ret
28+
entry:
29+
%v0 = load <16 x i16>, ptr %a0
30+
%v1 = load <16 x i16>, ptr %a1
31+
%v2 = and <16 x i16> %v0, %v1
32+
store <16 x i16> %v2, ptr %res
33+
ret void
34+
}
35+
36+
define void @and_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind {
37+
; CHECK-LABEL: and_v8i32:
38+
; CHECK: # %bb.0: # %entry
39+
; CHECK-NEXT: xvld $xr0, $a2, 0
40+
; CHECK-NEXT: xvld $xr1, $a1, 0
41+
; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
42+
; CHECK-NEXT: xvst $xr0, $a0, 0
43+
; CHECK-NEXT: ret
44+
entry:
45+
%v0 = load <8 x i32>, ptr %a0
46+
%v1 = load <8 x i32>, ptr %a1
47+
%v2 = and <8 x i32> %v0, %v1
48+
store <8 x i32> %v2, ptr %res
49+
ret void
50+
}
51+
52+
define void @and_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind {
53+
; CHECK-LABEL: and_v4i64:
54+
; CHECK: # %bb.0: # %entry
55+
; CHECK-NEXT: xvld $xr0, $a2, 0
56+
; CHECK-NEXT: xvld $xr1, $a1, 0
57+
; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
58+
; CHECK-NEXT: xvst $xr0, $a0, 0
59+
; CHECK-NEXT: ret
60+
entry:
61+
%v0 = load <4 x i64>, ptr %a0
62+
%v1 = load <4 x i64>, ptr %a1
63+
%v2 = and <4 x i64> %v0, %v1
64+
store <4 x i64> %v2, ptr %res
65+
ret void
66+
}
67+
68+
define void @and_u_v32i8(ptr %res, ptr %a0) nounwind {
69+
; CHECK-LABEL: and_u_v32i8:
70+
; CHECK: # %bb.0: # %entry
71+
; CHECK-NEXT: xvld $xr0, $a1, 0
72+
; CHECK-NEXT: xvandi.b $xr0, $xr0, 31
73+
; CHECK-NEXT: xvst $xr0, $a0, 0
74+
; CHECK-NEXT: ret
75+
entry:
76+
%v0 = load <32 x i8>, ptr %a0
77+
%v1 = and <32 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
78+
store <32 x i8> %v1, ptr %res
79+
ret void
80+
}
81+
82+
define void @and_u_v16i16(ptr %res, ptr %a0) nounwind {
83+
; CHECK-LABEL: and_u_v16i16:
84+
; CHECK: # %bb.0: # %entry
85+
; CHECK-NEXT: xvld $xr0, $a1, 0
86+
; CHECK-NEXT: xvrepli.h $xr1, 31
87+
; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1
88+
; CHECK-NEXT: xvst $xr0, $a0, 0
89+
; CHECK-NEXT: ret
90+
entry:
91+
%v0 = load <16 x i16>, ptr %a0
92+
%v1 = and <16 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
93+
store <16 x i16> %v1, ptr %res
94+
ret void
95+
}
96+
97+
define void @and_u_v8i32(ptr %res, ptr %a0) nounwind {
98+
; CHECK-LABEL: and_u_v8i32:
99+
; CHECK: # %bb.0: # %entry
100+
; CHECK-NEXT: xvld $xr0, $a1, 0
101+
; CHECK-NEXT: xvrepli.w $xr1, 31
102+
; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1
103+
; CHECK-NEXT: xvst $xr0, $a0, 0
104+
; CHECK-NEXT: ret
105+
entry:
106+
%v0 = load <8 x i32>, ptr %a0
107+
%v1 = and <8 x i32> %v0, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
108+
store <8 x i32> %v1, ptr %res
109+
ret void
110+
}
111+
112+
define void @and_u_v4i64(ptr %res, ptr %a0) nounwind {
113+
; CHECK-LABEL: and_u_v4i64:
114+
; CHECK: # %bb.0: # %entry
115+
; CHECK-NEXT: xvld $xr0, $a1, 0
116+
; CHECK-NEXT: xvrepli.d $xr1, 31
117+
; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1
118+
; CHECK-NEXT: xvst $xr0, $a0, 0
119+
; CHECK-NEXT: ret
120+
entry:
121+
%v0 = load <4 x i64>, ptr %a0
122+
%v1 = and <4 x i64> %v0, <i64 31, i64 31, i64 31, i64 31>
123+
store <4 x i64> %v1, ptr %res
124+
ret void
125+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2+
; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
3+
4+
define void @or_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind {
5+
; CHECK-LABEL: or_v32i8:
6+
; CHECK: # %bb.0: # %entry
7+
; CHECK-NEXT: xvld $xr0, $a2, 0
8+
; CHECK-NEXT: xvld $xr1, $a1, 0
9+
; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
10+
; CHECK-NEXT: xvst $xr0, $a0, 0
11+
; CHECK-NEXT: ret
12+
entry:
13+
%v0 = load <32 x i8>, ptr %a0
14+
%v1 = load <32 x i8>, ptr %a1
15+
%v2 = or <32 x i8> %v0, %v1
16+
store <32 x i8> %v2, ptr %res
17+
ret void
18+
}
19+
20+
define void @or_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind {
21+
; CHECK-LABEL: or_v16i16:
22+
; CHECK: # %bb.0: # %entry
23+
; CHECK-NEXT: xvld $xr0, $a2, 0
24+
; CHECK-NEXT: xvld $xr1, $a1, 0
25+
; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
26+
; CHECK-NEXT: xvst $xr0, $a0, 0
27+
; CHECK-NEXT: ret
28+
entry:
29+
%v0 = load <16 x i16>, ptr %a0
30+
%v1 = load <16 x i16>, ptr %a1
31+
%v2 = or <16 x i16> %v0, %v1
32+
store <16 x i16> %v2, ptr %res
33+
ret void
34+
}
35+
36+
define void @or_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind {
37+
; CHECK-LABEL: or_v8i32:
38+
; CHECK: # %bb.0: # %entry
39+
; CHECK-NEXT: xvld $xr0, $a2, 0
40+
; CHECK-NEXT: xvld $xr1, $a1, 0
41+
; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
42+
; CHECK-NEXT: xvst $xr0, $a0, 0
43+
; CHECK-NEXT: ret
44+
entry:
45+
%v0 = load <8 x i32>, ptr %a0
46+
%v1 = load <8 x i32>, ptr %a1
47+
%v2 = or <8 x i32> %v0, %v1
48+
store <8 x i32> %v2, ptr %res
49+
ret void
50+
}
51+
52+
define void @or_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind {
53+
; CHECK-LABEL: or_v4i64:
54+
; CHECK: # %bb.0: # %entry
55+
; CHECK-NEXT: xvld $xr0, $a2, 0
56+
; CHECK-NEXT: xvld $xr1, $a1, 0
57+
; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
58+
; CHECK-NEXT: xvst $xr0, $a0, 0
59+
; CHECK-NEXT: ret
60+
entry:
61+
%v0 = load <4 x i64>, ptr %a0
62+
%v1 = load <4 x i64>, ptr %a1
63+
%v2 = or <4 x i64> %v0, %v1
64+
store <4 x i64> %v2, ptr %res
65+
ret void
66+
}
67+
68+
define void @or_u_v32i8(ptr %res, ptr %a0) nounwind {
69+
; CHECK-LABEL: or_u_v32i8:
70+
; CHECK: # %bb.0: # %entry
71+
; CHECK-NEXT: xvld $xr0, $a1, 0
72+
; CHECK-NEXT: xvori.b $xr0, $xr0, 31
73+
; CHECK-NEXT: xvst $xr0, $a0, 0
74+
; CHECK-NEXT: ret
75+
entry:
76+
%v0 = load <32 x i8>, ptr %a0
77+
%v1 = or <32 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
78+
store <32 x i8> %v1, ptr %res
79+
ret void
80+
}
81+
82+
define void @or_u_v16i16(ptr %res, ptr %a0) nounwind {
83+
; CHECK-LABEL: or_u_v16i16:
84+
; CHECK: # %bb.0: # %entry
85+
; CHECK-NEXT: xvld $xr0, $a1, 0
86+
; CHECK-NEXT: xvrepli.h $xr1, 31
87+
; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1
88+
; CHECK-NEXT: xvst $xr0, $a0, 0
89+
; CHECK-NEXT: ret
90+
entry:
91+
%v0 = load <16 x i16>, ptr %a0
92+
%v1 = or <16 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
93+
store <16 x i16> %v1, ptr %res
94+
ret void
95+
}
96+
97+
define void @or_u_v8i32(ptr %res, ptr %a0) nounwind {
98+
; CHECK-LABEL: or_u_v8i32:
99+
; CHECK: # %bb.0: # %entry
100+
; CHECK-NEXT: xvld $xr0, $a1, 0
101+
; CHECK-NEXT: xvrepli.w $xr1, 31
102+
; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1
103+
; CHECK-NEXT: xvst $xr0, $a0, 0
104+
; CHECK-NEXT: ret
105+
entry:
106+
%v0 = load <8 x i32>, ptr %a0
107+
%v1 = or <8 x i32> %v0, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
108+
store <8 x i32> %v1, ptr %res
109+
ret void
110+
}
111+
112+
define void @or_u_v4i64(ptr %res, ptr %a0) nounwind {
113+
; CHECK-LABEL: or_u_v4i64:
114+
; CHECK: # %bb.0: # %entry
115+
; CHECK-NEXT: xvld $xr0, $a1, 0
116+
; CHECK-NEXT: xvrepli.d $xr1, 31
117+
; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1
118+
; CHECK-NEXT: xvst $xr0, $a0, 0
119+
; CHECK-NEXT: ret
120+
entry:
121+
%v0 = load <4 x i64>, ptr %a0
122+
%v1 = or <4 x i64> %v0, <i64 31, i64 31, i64 31, i64 31>
123+
store <4 x i64> %v1, ptr %res
124+
ret void
125+
}

0 commit comments

Comments
 (0)