Skip to content

Commit 649e1d1

Browse files
committed
[RISCV][GlobalISel] Legalize bitshift instructions for narrow types
Legalize G_SHL, G_ASHR and G_LSHR for types narrower and upto (and including) XLen: (i7, i8, i16 and i32) for rv32 and (i8, i15, i16, i32 and i64) for rv64. This requires adding some rules to handle G_ANYEXT, G_ZEXT and G_SEXT. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D155772
1 parent f0a3954 commit 649e1d1

File tree

7 files changed

+611
-0
lines changed

7 files changed

+611
-0
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
2929
.legalFor({XLenLLT})
3030
.clampScalar(0, XLenLLT, XLenLLT);
3131

32+
getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
33+
.legalFor({{XLenLLT, XLenLLT}})
34+
.widenScalarToNextPow2(0)
35+
.clampScalar(1, XLenLLT, XLenLLT)
36+
.clampScalar(0, XLenLLT, XLenLLT);
37+
3238
// Extensions
3339
auto ExtLegalFunc = [=](const LegalityQuery &Query) {
3440
unsigned DstSize = Query.Types[0].getSizeInBits();
@@ -53,6 +59,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
5359
.legalIf(ExtLegalFunc)
5460
.clampScalar(0, XLenLLT, XLenLLT);
5561

62+
getActionDefinitionsBuilder(G_SEXT_INREG).legalFor({XLenLLT}).lower();
63+
5664
// Merge/Unmerge
5765
for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
5866
unsigned BigTyIdx = Op == G_MERGE_VALUES ? 0 : 1;
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
3+
# RUN: | FileCheck %s
4+
---
5+
name: ashr_i7
6+
body: |
7+
bb.0.entry:
8+
; CHECK-LABEL: name: ashr_i7
9+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
10+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
11+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
12+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
13+
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 7
14+
; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SEXT_INREG]], [[AND]](s32)
15+
; CHECK-NEXT: $x10 = COPY [[ASHR]](s32)
16+
; CHECK-NEXT: PseudoRET implicit $x10
17+
%0:_(s32) = COPY $x10
18+
%1:_(s32) = COPY $x11
19+
%2:_(s7) = G_TRUNC %0(s32)
20+
%3:_(s7) = G_TRUNC %1(s32)
21+
%4:_(s7) = G_ASHR %2, %3
22+
%5:_(s32) = G_ANYEXT %4(s7)
23+
$x10 = COPY %5(s32)
24+
PseudoRET implicit $x10
25+
26+
...
27+
---
28+
name: ashr_i8
29+
body: |
30+
bb.0.entry:
31+
; CHECK-LABEL: name: ashr_i8
32+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
33+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
34+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
35+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
36+
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 8
37+
; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SEXT_INREG]], [[AND]](s32)
38+
; CHECK-NEXT: $x10 = COPY [[ASHR]](s32)
39+
; CHECK-NEXT: PseudoRET implicit $x10
40+
%0:_(s32) = COPY $x10
41+
%1:_(s32) = COPY $x11
42+
%2:_(s8) = G_TRUNC %0(s32)
43+
%3:_(s8) = G_TRUNC %1(s32)
44+
%4:_(s8) = G_ASHR %2, %3
45+
%5:_(s32) = G_ANYEXT %4(s8)
46+
$x10 = COPY %5(s32)
47+
PseudoRET implicit $x10
48+
49+
...
50+
---
51+
name: ashr_i16
52+
body: |
53+
bb.0.entry:
54+
; CHECK-LABEL: name: ashr_i16
55+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
56+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
57+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
58+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
59+
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 16
60+
; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SEXT_INREG]], [[AND]](s32)
61+
; CHECK-NEXT: $x10 = COPY [[ASHR]](s32)
62+
; CHECK-NEXT: PseudoRET implicit $x10
63+
%0:_(s32) = COPY $x10
64+
%1:_(s32) = COPY $x11
65+
%2:_(s16) = G_TRUNC %0(s32)
66+
%3:_(s16) = G_TRUNC %1(s32)
67+
%4:_(s16) = G_ASHR %2, %3
68+
%5:_(s32) = G_ANYEXT %4(s16)
69+
$x10 = COPY %5(s32)
70+
PseudoRET implicit $x10
71+
72+
...
73+
---
74+
name: ashr_i32
75+
body: |
76+
bb.0.entry:
77+
; CHECK-LABEL: name: ashr_i32
78+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
79+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
80+
; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[COPY]], [[COPY1]](s32)
81+
; CHECK-NEXT: $x10 = COPY [[ASHR]](s32)
82+
; CHECK-NEXT: PseudoRET implicit $x10
83+
%0:_(s32) = COPY $x10
84+
%1:_(s32) = COPY $x11
85+
%2:_(s32) = G_ASHR %0, %1
86+
$x10 = COPY %2(s32)
87+
PseudoRET implicit $x10
88+
89+
...
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
3+
# RUN: | FileCheck %s
4+
---
5+
name: lshr_i1
6+
body: |
7+
bb.0.entry:
8+
; CHECK-LABEL: name: lshr_i1
9+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
10+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
11+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
12+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
13+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
14+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C1]]
15+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND1]], [[AND]](s32)
16+
; CHECK-NEXT: $x10 = COPY [[LSHR]](s32)
17+
; CHECK-NEXT: PseudoRET implicit $x10
18+
%0:_(s32) = COPY $x10
19+
%1:_(s32) = COPY $x11
20+
%2:_(s1) = G_TRUNC %0(s32)
21+
%3:_(s1) = G_TRUNC %1(s32)
22+
%4:_(s1) = G_LSHR %2, %3
23+
%5:_(s32) = G_ANYEXT %4(s1)
24+
$x10 = COPY %5(s32)
25+
PseudoRET implicit $x10
26+
27+
...
28+
---
29+
name: lshr_i8
30+
body: |
31+
bb.0.entry:
32+
; CHECK-LABEL: name: lshr_i8
33+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
34+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
35+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
36+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
37+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
38+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C1]]
39+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND1]], [[AND]](s32)
40+
; CHECK-NEXT: $x10 = COPY [[LSHR]](s32)
41+
; CHECK-NEXT: PseudoRET implicit $x10
42+
%0:_(s32) = COPY $x10
43+
%1:_(s32) = COPY $x11
44+
%2:_(s8) = G_TRUNC %0(s32)
45+
%3:_(s8) = G_TRUNC %1(s32)
46+
%4:_(s8) = G_LSHR %2, %3
47+
%5:_(s32) = G_ANYEXT %4(s8)
48+
$x10 = COPY %5(s32)
49+
PseudoRET implicit $x10
50+
51+
...
52+
---
53+
name: lshr_i16
54+
body: |
55+
bb.0.entry:
56+
; CHECK-LABEL: name: lshr_i16
57+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
58+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
59+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
60+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
61+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
62+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C1]]
63+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND1]], [[AND]](s32)
64+
; CHECK-NEXT: $x10 = COPY [[LSHR]](s32)
65+
; CHECK-NEXT: PseudoRET implicit $x10
66+
%0:_(s32) = COPY $x10
67+
%1:_(s32) = COPY $x11
68+
%2:_(s16) = G_TRUNC %0(s32)
69+
%3:_(s16) = G_TRUNC %1(s32)
70+
%4:_(s16) = G_LSHR %2, %3
71+
%5:_(s32) = G_ANYEXT %4(s16)
72+
$x10 = COPY %5(s32)
73+
PseudoRET implicit $x10
74+
75+
...
76+
---
77+
name: lshr_i32
78+
body: |
79+
bb.0.entry:
80+
; CHECK-LABEL: name: lshr_i32
81+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
82+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
83+
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[COPY1]](s32)
84+
; CHECK-NEXT: $x10 = COPY [[LSHR]](s32)
85+
; CHECK-NEXT: PseudoRET implicit $x10
86+
%0:_(s32) = COPY $x10
87+
%1:_(s32) = COPY $x11
88+
%2:_(s32) = G_LSHR %0, %1
89+
$x10 = COPY %2(s32)
90+
PseudoRET implicit $x10
91+
92+
...
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
3+
# RUN: | FileCheck %s
4+
---
5+
name: shl_i1
6+
body: |
7+
bb.0.entry:
8+
; CHECK-LABEL: name: shl_i1
9+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
10+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
11+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
12+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
13+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[AND]](s32)
14+
; CHECK-NEXT: $x10 = COPY [[SHL]](s32)
15+
; CHECK-NEXT: PseudoRET implicit $x10
16+
%0:_(s32) = COPY $x10
17+
%1:_(s32) = COPY $x11
18+
%2:_(s1) = G_TRUNC %0(s32)
19+
%3:_(s1) = G_TRUNC %1(s32)
20+
%4:_(s1) = G_SHL %2, %3
21+
%5:_(s32) = G_ANYEXT %4(s1)
22+
$x10 = COPY %5(s32)
23+
PseudoRET implicit $x10
24+
25+
...
26+
---
27+
name: shl_i8
28+
body: |
29+
bb.0.entry:
30+
; CHECK-LABEL: name: shl_i8
31+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
32+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
33+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
34+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
35+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[AND]](s32)
36+
; CHECK-NEXT: $x10 = COPY [[SHL]](s32)
37+
; CHECK-NEXT: PseudoRET implicit $x10
38+
%0:_(s32) = COPY $x10
39+
%1:_(s32) = COPY $x11
40+
%2:_(s8) = G_TRUNC %0(s32)
41+
%3:_(s8) = G_TRUNC %1(s32)
42+
%4:_(s8) = G_SHL %2, %3
43+
%5:_(s32) = G_ANYEXT %4(s8)
44+
$x10 = COPY %5(s32)
45+
PseudoRET implicit $x10
46+
47+
...
48+
---
49+
name: shl_i16
50+
body: |
51+
bb.0.entry:
52+
; CHECK-LABEL: name: shl_i16
53+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
54+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
55+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
56+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
57+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[AND]](s32)
58+
; CHECK-NEXT: $x10 = COPY [[SHL]](s32)
59+
; CHECK-NEXT: PseudoRET implicit $x10
60+
%0:_(s32) = COPY $x10
61+
%1:_(s32) = COPY $x11
62+
%2:_(s16) = G_TRUNC %0(s32)
63+
%3:_(s16) = G_TRUNC %1(s32)
64+
%4:_(s16) = G_SHL %2, %3
65+
%5:_(s32) = G_ANYEXT %4(s16)
66+
$x10 = COPY %5(s32)
67+
PseudoRET implicit $x10
68+
69+
...
70+
---
71+
name: shl_i32
72+
body: |
73+
bb.0.entry:
74+
; CHECK-LABEL: name: shl_i32
75+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
76+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
77+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[COPY1]](s32)
78+
; CHECK-NEXT: $x10 = COPY [[SHL]](s32)
79+
; CHECK-NEXT: PseudoRET implicit $x10
80+
%0:_(s32) = COPY $x10
81+
%1:_(s32) = COPY $x11
82+
%2:_(s32) = G_SHL %0, %1
83+
$x10 = COPY %2(s32)
84+
PseudoRET implicit $x10
85+
86+
...

0 commit comments

Comments
 (0)