Skip to content

Commit 4c43c1e

Browse files
[RISCV][GISEL] Add legalizer for G_BSWAP (#70226)
Lower G_BSWAP into simpler instructions that can be selected in instruction selection. A future patch can handle when there is Zbb.
1 parent 7aa65c3 commit 4c43c1e

File tree

3 files changed

+230
-0
lines changed

3 files changed

+230
-0
lines changed

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
7676
.clampScalar(BigTyIdx, sXLen, sXLen);
7777
}
7878

79+
getActionDefinitionsBuilder(G_BSWAP).maxScalar(0, sXLen).lower();
80+
7981
getActionDefinitionsBuilder({G_CONSTANT, G_IMPLICIT_DEF})
8082
.legalFor({s32, sXLen, p0})
8183
.widenScalarToNextPow2(0)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
2+
# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - | FileCheck %s
3+
4+
---
5+
name: bswap_i16
6+
body: |
7+
bb.0:
8+
liveins: $x10
9+
; CHECK-LABEL: name: bswap_i16
10+
; CHECK: liveins: $x10
11+
; CHECK-NEXT: {{ $}}
12+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
13+
; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY]], 16
14+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
15+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ASSERT_ZEXT]], [[C]](s32)
16+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
17+
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
18+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ASSERT_ZEXT]], [[C2]]
19+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C1]](s32)
20+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[LSHR]], [[SHL]]
21+
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
22+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[OR]], [[C3]]
23+
; CHECK-NEXT: $x10 = COPY [[AND1]](s32)
24+
; CHECK-NEXT: PseudoRET implicit $x10
25+
%0:_(s32) = COPY $x10
26+
%1:_(s32) = G_ASSERT_ZEXT %0, 16
27+
%2:_(s16) = G_TRUNC %1(s32)
28+
%3:_(s16) = G_BSWAP %2
29+
%4:_(s32) = G_ZEXT %3(s16)
30+
$x10 = COPY %4(s32)
31+
PseudoRET implicit $x10
32+
...
33+
---
34+
name: bswap_i32
35+
body: |
36+
bb.0:
37+
liveins: $x10
38+
; CHECK-LABEL: name: bswap_i32
39+
; CHECK: liveins: $x10
40+
; CHECK-NEXT: {{ $}}
41+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
42+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
43+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
44+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C]](s32)
45+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[LSHR]], [[SHL]]
46+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
47+
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
48+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C1]]
49+
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[AND]], [[C2]](s32)
50+
; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s32) = G_OR [[OR]], [[SHL1]]
51+
; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C2]](s32)
52+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[LSHR1]], [[C1]]
53+
; CHECK-NEXT: [[OR2:%[0-9]+]]:_(s32) = G_OR [[OR1]], [[AND1]]
54+
; CHECK-NEXT: $x10 = COPY [[OR2]](s32)
55+
; CHECK-NEXT: PseudoRET implicit $x10
56+
%0:_(s32) = COPY $x10
57+
%1:_(s32) = G_BSWAP %0
58+
$x10 = COPY %1(s32)
59+
PseudoRET implicit $x10
60+
...
61+
---
62+
name: bswap_i64
63+
body: |
64+
bb.0:
65+
liveins: $x10, $x11
66+
; CHECK-LABEL: name: bswap_i64
67+
; CHECK: liveins: $x10, $x11
68+
; CHECK-NEXT: {{ $}}
69+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
70+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
71+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
72+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
73+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY1]], [[C]](s32)
74+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[LSHR]], [[SHL]]
75+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
76+
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
77+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
78+
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[AND]], [[C2]](s32)
79+
; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s32) = G_OR [[OR]], [[SHL1]]
80+
; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[COPY1]], [[C2]](s32)
81+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[LSHR1]], [[C1]]
82+
; CHECK-NEXT: [[OR2:%[0-9]+]]:_(s32) = G_OR [[OR1]], [[AND1]]
83+
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
84+
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C3]](s32)
85+
; CHECK-NEXT: [[LSHR2:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C3]](s32)
86+
; CHECK-NEXT: [[OR3:%[0-9]+]]:_(s32) = G_OR [[LSHR2]], [[SHL2]]
87+
; CHECK-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
88+
; CHECK-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
89+
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C4]]
90+
; CHECK-NEXT: [[SHL3:%[0-9]+]]:_(s32) = G_SHL [[AND2]], [[C5]](s32)
91+
; CHECK-NEXT: [[OR4:%[0-9]+]]:_(s32) = G_OR [[OR3]], [[SHL3]]
92+
; CHECK-NEXT: [[LSHR3:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C5]](s32)
93+
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[LSHR3]], [[C4]]
94+
; CHECK-NEXT: [[OR5:%[0-9]+]]:_(s32) = G_OR [[OR4]], [[AND3]]
95+
; CHECK-NEXT: $x10 = COPY [[OR2]](s32)
96+
; CHECK-NEXT: $x11 = COPY [[OR5]](s32)
97+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
98+
%0:_(s32) = COPY $x10
99+
%1:_(s32) = COPY $x11
100+
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
101+
%3:_(s64) = G_BSWAP %2
102+
%4:_(s32), %5:_(s32) = G_UNMERGE_VALUES %3(s64)
103+
$x10 = COPY %4(s32)
104+
$x11 = COPY %5(s32)
105+
PseudoRET implicit $x10, implicit $x11
106+
...
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - | FileCheck %s
3+
4+
---
5+
name: bswap_i16
6+
body: |
7+
bb.0:
8+
liveins: $x10
9+
; CHECK-LABEL: name: bswap_i16
10+
; CHECK: liveins: $x10
11+
; CHECK-NEXT: {{ $}}
12+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
13+
; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s64) = G_ASSERT_ZEXT [[COPY]], 16
14+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
15+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ASSERT_ZEXT]](s64)
16+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
17+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
18+
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
19+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ASSERT_ZEXT]], [[C2]]
20+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[AND]](s64)
21+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[TRUNC1]], [[C1]](s32)
22+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[LSHR]](s32)
23+
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[SHL]](s32)
24+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[ANYEXT]], [[ANYEXT1]]
25+
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
26+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[OR]], [[C3]]
27+
; CHECK-NEXT: $x10 = COPY [[AND1]](s64)
28+
; CHECK-NEXT: PseudoRET implicit $x10
29+
%0:_(s64) = COPY $x10
30+
%1:_(s64) = G_ASSERT_ZEXT %0, 16
31+
%2:_(s16) = G_TRUNC %1(s64)
32+
%3:_(s16) = G_BSWAP %2
33+
%4:_(s64) = G_ZEXT %3(s16)
34+
$x10 = COPY %4(s64)
35+
PseudoRET implicit $x10
36+
...
37+
---
38+
name: bswap_i32
39+
body: |
40+
bb.0:
41+
liveins: $x10
42+
; CHECK-LABEL: name: bswap_i32
43+
; CHECK: liveins: $x10
44+
; CHECK-NEXT: {{ $}}
45+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
46+
; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s64) = G_ASSERT_ZEXT [[COPY]], 32
47+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ASSERT_ZEXT]](s64)
48+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
49+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
50+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[TRUNC]], [[C]](s32)
51+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[LSHR]](s32)
52+
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[SHL]](s32)
53+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[ANYEXT]], [[ANYEXT1]]
54+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
55+
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 65280
56+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ASSERT_ZEXT]], [[C2]]
57+
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[AND]](s64)
58+
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[TRUNC1]], [[C1]](s32)
59+
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s64) = G_ANYEXT [[SHL1]](s32)
60+
; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s64) = G_OR [[OR]], [[ANYEXT2]]
61+
; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[TRUNC]], [[C1]](s32)
62+
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s64) = G_ANYEXT [[LSHR1]](s32)
63+
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 65280
64+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[ANYEXT3]], [[C3]]
65+
; CHECK-NEXT: [[OR2:%[0-9]+]]:_(s64) = G_OR [[OR1]], [[AND1]]
66+
; CHECK-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
67+
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND [[OR2]], [[C4]]
68+
; CHECK-NEXT: $x10 = COPY [[AND2]](s64)
69+
; CHECK-NEXT: PseudoRET implicit $x10
70+
%0:_(s64) = COPY $x10
71+
%1:_(s64) = G_ASSERT_ZEXT %0, 32
72+
%2:_(s32) = G_TRUNC %1(s64)
73+
%3:_(s32) = G_BSWAP %2
74+
%4:_(s64) = G_ZEXT %3(s32)
75+
$x10 = COPY %4(s64)
76+
PseudoRET implicit $x10
77+
...
78+
---
79+
name: bswap_i64
80+
body: |
81+
bb.0:
82+
liveins: $x10
83+
; CHECK-LABEL: name: bswap_i64
84+
; CHECK: liveins: $x10
85+
; CHECK-NEXT: {{ $}}
86+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
87+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
88+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
89+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[COPY]], [[C]](s64)
90+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[LSHR]], [[SHL]]
91+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 65280
92+
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 40
93+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C1]]
94+
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[AND]], [[C2]](s64)
95+
; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s64) = G_OR [[OR]], [[SHL1]]
96+
; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s64) = G_LSHR [[COPY]], [[C2]](s64)
97+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[LSHR1]], [[C1]]
98+
; CHECK-NEXT: [[OR2:%[0-9]+]]:_(s64) = G_OR [[OR1]], [[AND1]]
99+
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 16711680
100+
; CHECK-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
101+
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C3]]
102+
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s64) = G_SHL [[AND2]], [[C4]](s64)
103+
; CHECK-NEXT: [[OR3:%[0-9]+]]:_(s64) = G_OR [[OR2]], [[SHL2]]
104+
; CHECK-NEXT: [[LSHR2:%[0-9]+]]:_(s64) = G_LSHR [[COPY]], [[C4]](s64)
105+
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s64) = G_AND [[LSHR2]], [[C3]]
106+
; CHECK-NEXT: [[OR4:%[0-9]+]]:_(s64) = G_OR [[OR3]], [[AND3]]
107+
; CHECK-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16777216
108+
; CHECK-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
109+
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C5]]
110+
; CHECK-NEXT: [[SHL3:%[0-9]+]]:_(s64) = G_SHL [[AND4]], [[C6]](s64)
111+
; CHECK-NEXT: [[OR5:%[0-9]+]]:_(s64) = G_OR [[OR4]], [[SHL3]]
112+
; CHECK-NEXT: [[LSHR3:%[0-9]+]]:_(s64) = G_LSHR [[COPY]], [[C6]](s64)
113+
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s64) = G_AND [[LSHR3]], [[C5]]
114+
; CHECK-NEXT: [[OR6:%[0-9]+]]:_(s64) = G_OR [[OR5]], [[AND5]]
115+
; CHECK-NEXT: $x10 = COPY [[OR6]](s64)
116+
; CHECK-NEXT: PseudoRET implicit $x10
117+
%0:_(s64) = COPY $x10
118+
%1:_(s64) = G_BSWAP %0
119+
$x10 = COPY %1(s64)
120+
PseudoRET implicit $x10
121+
...
122+

0 commit comments

Comments
 (0)