Skip to content

Commit b8fef7a

Browse files
committed
[RISCV][GlobalISel] Legalize constants, undefined values, extension instructions, and (un)merge instructions for narrow types
Test legalization for (s7, s8, s16, s32, s48, s64, s96) for rv32, (s8, s15, s16, s32, s64, s72, s128, s192) for rv64. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D156383
1 parent 1b74459 commit b8fef7a

File tree

5 files changed

+520
-0
lines changed

5 files changed

+520
-0
lines changed

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

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

32+
// Extensions
33+
auto ExtLegalFunc = [=](const LegalityQuery &Query) {
34+
unsigned DstSize = Query.Types[0].getSizeInBits();
35+
36+
// Make sure that we have something that will fit in a register, and
37+
// make sure it's a power of 2.
38+
if (DstSize < 8 || DstSize > XLen || !isPowerOf2_32(DstSize))
39+
return false;
40+
41+
const LLT SrcTy = Query.Types[1];
42+
43+
// Make sure we fit in a register otherwise. Don't bother checking that
44+
// the source type is below 2 * XLen bits. We shouldn't be allowing anything
45+
// through which is wider than the destination in the first place.
46+
unsigned SrcSize = SrcTy.getSizeInBits();
47+
if (SrcSize < 8 || !isPowerOf2_32(SrcSize))
48+
return false;
49+
50+
return true;
51+
};
52+
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
53+
.legalIf(ExtLegalFunc)
54+
.clampScalar(0, XLenLLT, XLenLLT);
55+
56+
// Merge/Unmerge
57+
for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
58+
unsigned BigTyIdx = Op == G_MERGE_VALUES ? 0 : 1;
59+
unsigned LitTyIdx = Op == G_MERGE_VALUES ? 1 : 0;
60+
getActionDefinitionsBuilder(Op)
61+
.widenScalarToNextPow2(LitTyIdx, XLen)
62+
.widenScalarToNextPow2(BigTyIdx, XLen)
63+
.clampScalar(LitTyIdx, XLenLLT, XLenLLT)
64+
.clampScalar(BigTyIdx, XLenLLT, XLenLLT);
65+
}
66+
67+
getActionDefinitionsBuilder({G_CONSTANT, G_IMPLICIT_DEF})
68+
.legalFor({XLenLLT})
69+
.widenScalarToNextPow2(0)
70+
.clampScalar(0, XLenLLT, XLenLLT);
71+
3272
getLegacyLegalizerInfo().computeTables();
3373
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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: const_i7
6+
body: |
7+
bb.0.entry:
8+
; CHECK-LABEL: name: const_i7
9+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
10+
; CHECK-NEXT: $x10 = COPY [[C]](s32)
11+
; CHECK-NEXT: PseudoRET implicit $x10
12+
%0:_(s7) = G_CONSTANT i7 15
13+
%1:_(s32) = G_ANYEXT %0(s7)
14+
$x10 = COPY %1(s32)
15+
PseudoRET implicit $x10
16+
17+
...
18+
---
19+
name: const_i8
20+
body: |
21+
bb.0.entry:
22+
; CHECK-LABEL: name: const_i8
23+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -127
24+
; CHECK-NEXT: $x10 = COPY [[C]](s32)
25+
; CHECK-NEXT: PseudoRET implicit $x10
26+
%0:_(s8) = G_CONSTANT i8 129
27+
%1:_(s32) = G_ANYEXT %0(s8)
28+
$x10 = COPY %1(s32)
29+
PseudoRET implicit $x10
30+
31+
...
32+
---
33+
name: const_i16
34+
body: |
35+
bb.0.entry:
36+
; CHECK-LABEL: name: const_i16
37+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 32767
38+
; CHECK-NEXT: $x10 = COPY [[C]](s32)
39+
; CHECK-NEXT: PseudoRET implicit $x10
40+
%0:_(s16) = G_CONSTANT i16 -32769
41+
%1:_(s32) = G_ANYEXT %0(s16)
42+
$x10 = COPY %1(s32)
43+
PseudoRET implicit $x10
44+
45+
...
46+
---
47+
name: const_i32
48+
body: |
49+
bb.0.entry:
50+
; CHECK-LABEL: name: const_i32
51+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -2147483647
52+
; CHECK-NEXT: $x10 = COPY [[C]](s32)
53+
; CHECK-NEXT: PseudoRET implicit $x10
54+
%0:_(s32) = G_CONSTANT i32 2147483649
55+
$x10 = COPY %0(s32)
56+
PseudoRET implicit $x10
57+
58+
...
59+
---
60+
name: const_i48
61+
body: |
62+
bb.0.entry:
63+
; CHECK-LABEL: name: const_i48
64+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
65+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
66+
; CHECK-NEXT: $x10 = COPY [[C]](s32)
67+
; CHECK-NEXT: $x11 = COPY [[C1]](s32)
68+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
69+
%0:_(s48) = G_CONSTANT i48 2
70+
%1:_(s64) = G_ANYEXT %0(s48)
71+
%2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1(s64)
72+
$x10 = COPY %2(s32)
73+
$x11 = COPY %3(s32)
74+
PseudoRET implicit $x10, implicit $x11
75+
76+
...
77+
---
78+
name: const_i64
79+
body: |
80+
bb.0.entry:
81+
; CHECK-LABEL: name: const_i64
82+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -2147483647
83+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
84+
; CHECK-NEXT: $x10 = COPY [[C]](s32)
85+
; CHECK-NEXT: $x11 = COPY [[C1]](s32)
86+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
87+
%0:_(s64) = G_CONSTANT i64 2147483649
88+
%1:_(s32), %2:_(s32) = G_UNMERGE_VALUES %0(s64)
89+
$x10 = COPY %1(s32)
90+
$x11 = COPY %2(s32)
91+
PseudoRET implicit $x10, implicit $x11
92+
93+
...
94+
---
95+
name: const_i96
96+
body: |
97+
bb.0.entry:
98+
; CHECK-LABEL: name: const_i96
99+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -121
100+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -51
101+
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
102+
; CHECK-NEXT: $x10 = COPY [[C]](s32)
103+
; CHECK-NEXT: $x11 = COPY [[C1]](s32)
104+
; CHECK-NEXT: $x12 = COPY [[C2]](s32)
105+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
106+
%0:_(s96) = G_CONSTANT i96 -214748364921
107+
%1:_(s32), %2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %0(s96)
108+
$x10 = COPY %1(s32)
109+
$x11 = COPY %2(s32)
110+
$x12 = COPY %3(s32)
111+
PseudoRET implicit $x10, implicit $x11, implicit $x12
112+
113+
...
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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: implicit_def_i7
6+
body: |
7+
bb.0.entry:
8+
; CHECK-LABEL: name: implicit_def_i7
9+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
10+
; CHECK-NEXT: $x10 = COPY [[DEF]](s32)
11+
; CHECK-NEXT: PseudoRET implicit $x10
12+
%0:_(s7) = G_IMPLICIT_DEF
13+
%1:_(s32) = G_ANYEXT %0(s7)
14+
$x10 = COPY %1(s32)
15+
PseudoRET implicit $x10
16+
17+
...
18+
---
19+
name: implicit_def_i8
20+
body: |
21+
bb.0.entry:
22+
; CHECK-LABEL: name: implicit_def_i8
23+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
24+
; CHECK-NEXT: $x10 = COPY [[DEF]](s32)
25+
; CHECK-NEXT: PseudoRET implicit $x10
26+
%0:_(s8) = G_IMPLICIT_DEF
27+
%1:_(s32) = G_ANYEXT %0(s8)
28+
$x10 = COPY %1(s32)
29+
PseudoRET implicit $x10
30+
31+
...
32+
---
33+
name: implicit_def_i16
34+
body: |
35+
bb.0.entry:
36+
; CHECK-LABEL: name: implicit_def_i16
37+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
38+
; CHECK-NEXT: $x10 = COPY [[DEF]](s32)
39+
; CHECK-NEXT: PseudoRET implicit $x10
40+
%0:_(s16) = G_IMPLICIT_DEF
41+
%1:_(s32) = G_ANYEXT %0(s16)
42+
$x10 = COPY %1(s32)
43+
PseudoRET implicit $x10
44+
45+
...
46+
---
47+
name: implicit_def_i32
48+
body: |
49+
bb.0.entry:
50+
; CHECK-LABEL: name: implicit_def_i32
51+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
52+
; CHECK-NEXT: $x10 = COPY [[DEF]](s32)
53+
; CHECK-NEXT: PseudoRET implicit $x10
54+
%0:_(s32) = G_IMPLICIT_DEF
55+
$x10 = COPY %0(s32)
56+
PseudoRET implicit $x10
57+
58+
...
59+
---
60+
name: implicit_def_i48
61+
body: |
62+
bb.0.entry:
63+
; CHECK-LABEL: name: implicit_def_i48
64+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
65+
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
66+
; CHECK-NEXT: $x10 = COPY [[DEF]](s32)
67+
; CHECK-NEXT: $x11 = COPY [[DEF1]](s32)
68+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
69+
%0:_(s48) = G_IMPLICIT_DEF
70+
%1:_(s64) = G_ANYEXT %0(s48)
71+
%2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1(s64)
72+
$x10 = COPY %2(s32)
73+
$x11 = COPY %3(s32)
74+
PseudoRET implicit $x10, implicit $x11
75+
76+
...
77+
---
78+
name: implicit_def_i64
79+
body: |
80+
bb.0.entry:
81+
; CHECK-LABEL: name: implicit_def_i64
82+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
83+
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
84+
; CHECK-NEXT: $x10 = COPY [[DEF]](s32)
85+
; CHECK-NEXT: $x11 = COPY [[DEF1]](s32)
86+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
87+
%0:_(s64) = G_IMPLICIT_DEF
88+
%1:_(s32), %2:_(s32) = G_UNMERGE_VALUES %0(s64)
89+
$x10 = COPY %1(s32)
90+
$x11 = COPY %2(s32)
91+
PseudoRET implicit $x10, implicit $x11
92+
93+
...
94+
---
95+
name: implicit_def_i96
96+
body: |
97+
bb.0.entry:
98+
; CHECK-LABEL: name: implicit_def_i96
99+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
100+
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
101+
; CHECK-NEXT: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
102+
; CHECK-NEXT: $x10 = COPY [[DEF]](s32)
103+
; CHECK-NEXT: $x11 = COPY [[DEF1]](s32)
104+
; CHECK-NEXT: $x12 = COPY [[DEF2]](s32)
105+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
106+
%0:_(s96) = G_IMPLICIT_DEF
107+
%1:_(s32), %2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %0(s96)
108+
$x10 = COPY %1(s32)
109+
$x11 = COPY %2(s32)
110+
$x12 = COPY %3(s32)
111+
PseudoRET implicit $x10, implicit $x11, implicit $x12
112+
113+
...

0 commit comments

Comments
 (0)