Skip to content

Commit f873fc3

Browse files
[RISCV][GISEL] instruction-select vmclr (#110782)
This is stacked on #110778. This PR adds and tests renderVLOp too, as that is needed from vmclr.
1 parent 78089d5 commit f873fc3

File tree

7 files changed

+506
-0
lines changed

7 files changed

+506
-0
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class RISCVInstructionSelector : public InstructionSelector {
100100
return selectSHXADD_UWOp(Root, ShAmt);
101101
}
102102

103+
ComplexRendererFns renderVLOp(MachineOperand &Root) const;
104+
103105
// Custom renderers for tablegen
104106
void renderNegImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
105107
int OpIdx) const;
@@ -376,6 +378,29 @@ RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
376378
return std::nullopt;
377379
}
378380

381+
InstructionSelector::ComplexRendererFns
382+
RISCVInstructionSelector::renderVLOp(MachineOperand &Root) const {
383+
assert(Root.isReg() && "Expected operand to be a Register");
384+
MachineInstr *RootDef = MRI->getVRegDef(Root.getReg());
385+
386+
if (RootDef->getOpcode() == TargetOpcode::G_CONSTANT) {
387+
auto C = RootDef->getOperand(1).getCImm();
388+
if (C->getValue().isAllOnes())
389+
// If the operand is a G_CONSTANT with value of all ones it is larger than
390+
// VLMAX. We convert it to an immediate with value VLMaxSentinel. This is
391+
// recognized specially by the vsetvli insertion pass.
392+
return {{[=](MachineInstrBuilder &MIB) {
393+
MIB.addImm(RISCV::VLMaxSentinel);
394+
}}};
395+
396+
if (isUInt<5>(C->getZExtValue())) {
397+
uint64_t ZExtC = C->getZExtValue();
398+
return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
399+
}
400+
}
401+
return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.getReg()); }}};
402+
}
403+
379404
InstructionSelector::ComplexRendererFns
380405
RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root) const {
381406
if (!Root.isReg())

llvm/lib/Target/RISCV/RISCVGISel.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ def GIAddrRegImm :
5050
GIComplexOperandMatcher<s32, "selectAddrRegImm">,
5151
GIComplexPatternEquiv<AddrRegImm>;
5252

53+
// FIXME: This is labelled as handling 's32', however the ComplexPattern it
54+
// refers to handles both i32 and i64 based on the HwMode. Currently this LLT
55+
// parameter appears to be ignored so this pattern works for both, however we
56+
// should add a LowLevelTypeByHwMode, and use that to define our XLenLLT instead
57+
// here.
58+
def GIVLOp : GIComplexOperandMatcher<s32, "renderVLOp">,
59+
GIComplexPatternEquiv<VLOp>;
60+
5361
// Convert from i32 immediate to i64 target immediate to make SelectionDAG type
5462
// checking happy so we can use ADDIW which expects an XLen immediate.
5563
def as_i64imm : SDNodeXForm<imm, [{
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -mtriple=riscv32 -mattr=+v,+m -run-pass=instruction-select \
3+
# RUN: -verify-machineinstrs %s -o - | FileCheck %s
4+
5+
---
6+
name: negative_vl
7+
legalized: true
8+
regBankSelected: true
9+
tracksRegLiveness: true
10+
body: |
11+
bb.1:
12+
; CHECK-LABEL: name: negative_vl
13+
; CHECK: [[ADDI:%[0-9]+]]:gprnox0 = ADDI $x0, -2
14+
; CHECK-NEXT: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 [[ADDI]], 0 /* e8 */
15+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
16+
; CHECK-NEXT: PseudoRET implicit $v0
17+
%0:gprb(s32) = G_CONSTANT i32 -2
18+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s32)
19+
$v0 = COPY %1(<vscale x 1 x s1>)
20+
PseudoRET implicit $v0
21+
...
22+
---
23+
name: nonconst_vl
24+
legalized: true
25+
regBankSelected: true
26+
tracksRegLiveness: true
27+
body: |
28+
bb.1:
29+
liveins: $x10
30+
; CHECK-LABEL: name: nonconst_vl
31+
; CHECK: liveins: $x10
32+
; CHECK-NEXT: {{ $}}
33+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10
34+
; CHECK-NEXT: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 [[COPY]], 0 /* e8 */
35+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
36+
; CHECK-NEXT: PseudoRET implicit $v0
37+
%0:gprb(s32) = COPY $x10
38+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s32)
39+
$v0 = COPY %1(<vscale x 1 x s1>)
40+
PseudoRET implicit $v0
41+
...
42+
43+
---
44+
name: nonzero_vl
45+
legalized: true
46+
regBankSelected: true
47+
tracksRegLiveness: true
48+
body: |
49+
bb.1:
50+
; CHECK-LABEL: name: nonzero_vl
51+
; CHECK: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 1, 0 /* e8 */
52+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
53+
; CHECK-NEXT: PseudoRET implicit $v0
54+
%0:gprb(s32) = G_CONSTANT i32 1
55+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s32)
56+
$v0 = COPY %1(<vscale x 1 x s1>)
57+
PseudoRET implicit $v0
58+
...
59+
60+
---
61+
name: zero_vl
62+
legalized: true
63+
regBankSelected: true
64+
tracksRegLiveness: true
65+
body: |
66+
bb.1:
67+
; CHECK-LABEL: name: zero_vl
68+
; CHECK: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 0, 0 /* e8 */
69+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
70+
; CHECK-NEXT: PseudoRET implicit $v0
71+
%0:gprb(s32) = G_CONSTANT i32 0
72+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s32)
73+
$v0 = COPY %1(<vscale x 1 x s1>)
74+
PseudoRET implicit $v0
75+
...
76+
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -mtriple=riscv64 -mattr=+v,+m -run-pass=instruction-select \
3+
# RUN: -verify-machineinstrs %s -o - | FileCheck %s
4+
5+
---
6+
name: negative_vl
7+
legalized: true
8+
regBankSelected: true
9+
tracksRegLiveness: true
10+
body: |
11+
bb.1:
12+
; CHECK-LABEL: name: negative_vl
13+
; CHECK: [[ADDI:%[0-9]+]]:gprnox0 = ADDI $x0, -2
14+
; CHECK-NEXT: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 [[ADDI]], 0 /* e8 */
15+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
16+
; CHECK-NEXT: PseudoRET implicit $v0
17+
%0:gprb(s64) = G_CONSTANT i64 -2
18+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s64)
19+
$v0 = COPY %1(<vscale x 1 x s1>)
20+
PseudoRET implicit $v0
21+
...
22+
---
23+
name: nonconst_vl
24+
legalized: true
25+
regBankSelected: true
26+
tracksRegLiveness: true
27+
body: |
28+
bb.1:
29+
liveins: $x10
30+
; CHECK-LABEL: name: nonconst_vl
31+
; CHECK: liveins: $x10
32+
; CHECK-NEXT: {{ $}}
33+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10
34+
; CHECK-NEXT: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 [[COPY]], 0 /* e8 */
35+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
36+
; CHECK-NEXT: PseudoRET implicit $v0
37+
%0:gprb(s64) = COPY $x10
38+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s64)
39+
$v0 = COPY %1(<vscale x 1 x s1>)
40+
PseudoRET implicit $v0
41+
...
42+
43+
---
44+
name: nonzero_vl
45+
legalized: true
46+
regBankSelected: true
47+
tracksRegLiveness: true
48+
body: |
49+
bb.1:
50+
; CHECK-LABEL: name: nonzero_vl
51+
; CHECK: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 1, 0 /* e8 */
52+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
53+
; CHECK-NEXT: PseudoRET implicit $v0
54+
%0:gprb(s64) = G_CONSTANT i64 1
55+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s64)
56+
$v0 = COPY %1(<vscale x 1 x s1>)
57+
PseudoRET implicit $v0
58+
...
59+
60+
---
61+
name: zero_vl
62+
legalized: true
63+
regBankSelected: true
64+
tracksRegLiveness: true
65+
body: |
66+
bb.1:
67+
; CHECK-LABEL: name: zero_vl
68+
; CHECK: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 0, 0 /* e8 */
69+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
70+
; CHECK-NEXT: PseudoRET implicit $v0
71+
%0:gprb(s64) = G_CONSTANT i64 0
72+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s64)
73+
$v0 = COPY %1(<vscale x 1 x s1>)
74+
PseudoRET implicit $v0
75+
...
76+
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -mattr=+v,+m -run-pass=instruction-select \
3+
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
4+
5+
---
6+
name: splat_zero_nxv1i1
7+
legalized: true
8+
regBankSelected: true
9+
tracksRegLiveness: true
10+
body: |
11+
bb.1:
12+
; CHECK-LABEL: name: splat_zero_nxv1i1
13+
; CHECK: [[PseudoVMCLR_M_B1_:%[0-9]+]]:vr = PseudoVMCLR_M_B1 -1, 0 /* e8 */
14+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B1_]]
15+
; CHECK-NEXT: PseudoRET implicit $v0
16+
%0:gprb(s32) = G_CONSTANT i32 -1
17+
%1:vrb(<vscale x 1 x s1>) = G_VMCLR_VL %0(s32)
18+
$v0 = COPY %1(<vscale x 1 x s1>)
19+
PseudoRET implicit $v0
20+
21+
...
22+
---
23+
name: splat_zero_nxv2i1
24+
legalized: true
25+
regBankSelected: true
26+
tracksRegLiveness: true
27+
body: |
28+
bb.1:
29+
; CHECK-LABEL: name: splat_zero_nxv2i1
30+
; CHECK: [[PseudoVMCLR_M_B2_:%[0-9]+]]:vr = PseudoVMCLR_M_B2 -1, 0 /* e8 */
31+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B2_]]
32+
; CHECK-NEXT: PseudoRET implicit $v0
33+
%0:gprb(s32) = G_CONSTANT i32 -1
34+
%1:vrb(<vscale x 2 x s1>) = G_VMCLR_VL %0(s32)
35+
$v0 = COPY %1(<vscale x 2 x s1>)
36+
PseudoRET implicit $v0
37+
38+
...
39+
---
40+
name: splat_zero_nxv4i1
41+
legalized: true
42+
regBankSelected: true
43+
tracksRegLiveness: true
44+
body: |
45+
bb.1:
46+
; CHECK-LABEL: name: splat_zero_nxv4i1
47+
; CHECK: [[PseudoVMCLR_M_B4_:%[0-9]+]]:vr = PseudoVMCLR_M_B4 -1, 0 /* e8 */
48+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B4_]]
49+
; CHECK-NEXT: PseudoRET implicit $v0
50+
%0:gprb(s32) = G_CONSTANT i32 -1
51+
%1:vrb(<vscale x 4 x s1>) = G_VMCLR_VL %0(s32)
52+
$v0 = COPY %1(<vscale x 4 x s1>)
53+
PseudoRET implicit $v0
54+
55+
...
56+
---
57+
name: splat_zero_nxv8i1
58+
legalized: true
59+
regBankSelected: true
60+
tracksRegLiveness: true
61+
body: |
62+
bb.1:
63+
; CHECK-LABEL: name: splat_zero_nxv8i1
64+
; CHECK: [[PseudoVMCLR_M_B8_:%[0-9]+]]:vr = PseudoVMCLR_M_B8 -1, 0 /* e8 */
65+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B8_]]
66+
; CHECK-NEXT: PseudoRET implicit $v0
67+
%0:gprb(s32) = G_CONSTANT i32 -1
68+
%1:vrb(<vscale x 8 x s1>) = G_VMCLR_VL %0(s32)
69+
$v0 = COPY %1(<vscale x 8 x s1>)
70+
PseudoRET implicit $v0
71+
72+
...
73+
---
74+
name: splat_zero_nxv16i1
75+
legalized: true
76+
regBankSelected: true
77+
tracksRegLiveness: true
78+
body: |
79+
bb.1:
80+
; CHECK-LABEL: name: splat_zero_nxv16i1
81+
; CHECK: [[PseudoVMCLR_M_B16_:%[0-9]+]]:vr = PseudoVMCLR_M_B16 -1, 0 /* e8 */
82+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B16_]]
83+
; CHECK-NEXT: PseudoRET implicit $v0
84+
%0:gprb(s32) = G_CONSTANT i32 -1
85+
%1:vrb(<vscale x 16 x s1>) = G_VMCLR_VL %0(s32)
86+
$v0 = COPY %1(<vscale x 16 x s1>)
87+
PseudoRET implicit $v0
88+
89+
...
90+
---
91+
name: splat_zero_nxv32i1
92+
legalized: true
93+
regBankSelected: true
94+
tracksRegLiveness: true
95+
body: |
96+
bb.1:
97+
; CHECK-LABEL: name: splat_zero_nxv32i1
98+
; CHECK: [[PseudoVMCLR_M_B32_:%[0-9]+]]:vr = PseudoVMCLR_M_B32 -1, 0 /* e8 */
99+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B32_]]
100+
; CHECK-NEXT: PseudoRET implicit $v0
101+
%0:gprb(s32) = G_CONSTANT i32 -1
102+
%1:vrb(<vscale x 32 x s1>) = G_VMCLR_VL %0(s32)
103+
$v0 = COPY %1(<vscale x 32 x s1>)
104+
PseudoRET implicit $v0
105+
106+
...
107+
---
108+
name: splat_zero_nxv64i1
109+
legalized: true
110+
regBankSelected: true
111+
tracksRegLiveness: true
112+
body: |
113+
bb.1:
114+
; CHECK-LABEL: name: splat_zero_nxv64i1
115+
; CHECK: [[PseudoVMCLR_M_B64_:%[0-9]+]]:vr = PseudoVMCLR_M_B64 -1, 0 /* e8 */
116+
; CHECK-NEXT: $v0 = COPY [[PseudoVMCLR_M_B64_]]
117+
; CHECK-NEXT: PseudoRET implicit $v0
118+
%0:gprb(s32) = G_CONSTANT i32 -1
119+
%1:vrb(<vscale x 64 x s1>) = G_VMCLR_VL %0(s32)
120+
$v0 = COPY %1(<vscale x 64 x s1>)
121+
PseudoRET implicit $v0
122+
123+
...
124+

0 commit comments

Comments
 (0)