Skip to content

Commit 98eb28b

Browse files
committed
[RISCV][GISel] Implement instruction selection for G_PHI and G_BRCOND.
This uses a naive lowering for G_BRCOND to a BNE instruction comparing the register to X0.
1 parent 0944eea commit 98eb28b

File tree

3 files changed

+214
-4
lines changed

3 files changed

+214
-4
lines changed

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

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ class RISCVInstructionSelector : public InstructionSelector {
4242

4343
private:
4444
const TargetRegisterClass *
45-
getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
46-
bool GetAllRegSet = false) const;
45+
getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) const;
4746

4847
bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
4948
bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const;
@@ -136,7 +135,34 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
136135
MachineRegisterInfo &MRI = MF.getRegInfo();
137136
MachineIRBuilder MIB(MI);
138137

139-
if (!isPreISelGenericOpcode(Opc)) {
138+
if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
139+
if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
140+
const Register DefReg = MI.getOperand(0).getReg();
141+
const LLT DefTy = MRI.getType(DefReg);
142+
143+
const RegClassOrRegBank &RegClassOrBank =
144+
MRI.getRegClassOrRegBank(DefReg);
145+
146+
const TargetRegisterClass *DefRC =
147+
RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
148+
if (!DefRC) {
149+
if (!DefTy.isValid()) {
150+
LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
151+
return false;
152+
}
153+
154+
const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
155+
DefRC = getRegClassForTypeOnBank(DefTy, RB);
156+
if (!DefRC) {
157+
LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
158+
return false;
159+
}
160+
}
161+
162+
MI.setDesc(TII.get(TargetOpcode::PHI));
163+
return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
164+
}
165+
140166
// Certain non-generic instructions also need some special handling.
141167
if (MI.isCopy())
142168
return selectCopy(MI, MRI);
@@ -205,6 +231,14 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
205231
if (!selectConstant(MI, MIB, MRI))
206232
return false;
207233
break;
234+
case TargetOpcode::G_BRCOND: {
235+
// TODO: Fold with G_ICMP.
236+
auto Bcc =
237+
MIB.buildInstr(RISCV::BNE, {}, {MI.getOperand(0), Register(RISCV::X0)})
238+
.addMBB(MI.getOperand(1).getMBB());
239+
MI.eraseFromParent();
240+
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
241+
}
208242
default:
209243
return false;
210244
}
@@ -224,7 +258,7 @@ void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
224258
}
225259

226260
const TargetRegisterClass *RISCVInstructionSelector::getRegClassForTypeOnBank(
227-
LLT Ty, const RegisterBank &RB, bool GetAllRegSet) const {
261+
LLT Ty, const RegisterBank &RB) const {
228262
if (RB.getID() == RISCV::GPRRegBankID) {
229263
if (Ty.getSizeInBits() <= 32 || (STI.is64Bit() && Ty.getSizeInBits() == 64))
230264
return &RISCV::GPRRegClass;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -march=riscv32 -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \
3+
# RUN: | FileCheck -check-prefix=RV32I %s
4+
5+
---
6+
name: phi_i32
7+
legalized: true
8+
regBankSelected: true
9+
tracksRegLiveness: true
10+
body: |
11+
; RV32I-LABEL: name: phi_i32
12+
; RV32I: bb.0:
13+
; RV32I-NEXT: liveins: $x10, $x11, $x12
14+
; RV32I-NEXT: {{ $}}
15+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
16+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
17+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
18+
; RV32I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
19+
; RV32I-NEXT: BNE [[ANDI]], $x0, %bb.2
20+
; RV32I-NEXT: PseudoBR %bb.1
21+
; RV32I-NEXT: {{ $}}
22+
; RV32I-NEXT: bb.1:
23+
; RV32I-NEXT: {{ $}}
24+
; RV32I-NEXT: bb.2:
25+
; RV32I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.1, [[COPY1]], %bb.0
26+
; RV32I-NEXT: $x10 = COPY [[PHI]]
27+
; RV32I-NEXT: PseudoRET implicit $x10
28+
bb.0:
29+
liveins: $x10, $x11, $x12
30+
31+
%0:gprb(s32) = COPY $x10
32+
%1:gprb(s32) = COPY $x11
33+
%2:gprb(s32) = COPY $x12
34+
%3:gprb(s32) = G_CONSTANT i32 1
35+
%4:gprb(s32) = G_AND %0, %3
36+
G_BRCOND %4(s32), %bb.2
37+
G_BR %bb.1
38+
39+
bb.1:
40+
41+
bb.2:
42+
%5:gprb(s32) = G_PHI %2(s32), %bb.1, %1(s32), %bb.0
43+
$x10 = COPY %5(s32)
44+
PseudoRET implicit $x10
45+
46+
...
47+
---
48+
name: phi_ptr
49+
legalized: true
50+
regBankSelected: true
51+
tracksRegLiveness: true
52+
body: |
53+
; RV32I-LABEL: name: phi_ptr
54+
; RV32I: bb.0.entry:
55+
; RV32I-NEXT: liveins: $x10, $x11, $x12
56+
; RV32I-NEXT: {{ $}}
57+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
58+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
59+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
60+
; RV32I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
61+
; RV32I-NEXT: BNE [[ANDI]], $x0, %bb.2
62+
; RV32I-NEXT: PseudoBR %bb.1
63+
; RV32I-NEXT: {{ $}}
64+
; RV32I-NEXT: bb.1:
65+
; RV32I-NEXT: {{ $}}
66+
; RV32I-NEXT: bb.2:
67+
; RV32I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.1, [[COPY1]], %bb.0
68+
; RV32I-NEXT: $x10 = COPY [[PHI]]
69+
; RV32I-NEXT: PseudoRET implicit $x10
70+
bb.0.entry:
71+
liveins: $x10, $x11, $x12
72+
73+
%0:gprb(s32) = COPY $x10
74+
%1:gprb(p0) = COPY $x11
75+
%2:gprb(p0) = COPY $x12
76+
%3:gprb(s32) = G_CONSTANT i32 1
77+
%4:gprb(s32) = G_AND %0, %3
78+
G_BRCOND %4(s32), %bb.2
79+
G_BR %bb.1
80+
81+
bb.1:
82+
83+
bb.2:
84+
%5:gprb(p0) = G_PHI %2(p0), %bb.1, %1(p0), %bb.0
85+
$x10 = COPY %5(p0)
86+
PseudoRET implicit $x10
87+
88+
...
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -march=riscv64 -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \
3+
# RUN: | FileCheck -check-prefix=RV64I %s
4+
5+
---
6+
name: phi_i64
7+
legalized: true
8+
regBankSelected: true
9+
tracksRegLiveness: true
10+
body: |
11+
; RV64I-LABEL: name: phi_i64
12+
; RV64I: bb.0:
13+
; RV64I-NEXT: liveins: $x10, $x11, $x12
14+
; RV64I-NEXT: {{ $}}
15+
; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
16+
; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
17+
; RV64I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
18+
; RV64I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
19+
; RV64I-NEXT: BNE [[ANDI]], $x0, %bb.2
20+
; RV64I-NEXT: PseudoBR %bb.1
21+
; RV64I-NEXT: {{ $}}
22+
; RV64I-NEXT: bb.1:
23+
; RV64I-NEXT: {{ $}}
24+
; RV64I-NEXT: bb.2:
25+
; RV64I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.1, [[COPY1]], %bb.0
26+
; RV64I-NEXT: $x10 = COPY [[PHI]]
27+
; RV64I-NEXT: PseudoRET implicit $x10
28+
bb.0:
29+
liveins: $x10, $x11, $x12
30+
31+
%0:gprb(s64) = COPY $x10
32+
%1:gprb(s64) = COPY $x11
33+
%2:gprb(s64) = COPY $x12
34+
%3:gprb(s64) = G_CONSTANT i64 1
35+
%4:gprb(s64) = G_AND %0, %3
36+
G_BRCOND %4(s64), %bb.2
37+
G_BR %bb.1
38+
39+
bb.1:
40+
41+
bb.2:
42+
%5:gprb(s64) = G_PHI %2(s64), %bb.1, %1(s64), %bb.0
43+
$x10 = COPY %5(s64)
44+
PseudoRET implicit $x10
45+
46+
...
47+
---
48+
name: phi_ptr
49+
legalized: true
50+
regBankSelected: true
51+
tracksRegLiveness: true
52+
body: |
53+
; RV64I-LABEL: name: phi_ptr
54+
; RV64I: bb.0:
55+
; RV64I-NEXT: liveins: $x10, $x11, $x12
56+
; RV64I-NEXT: {{ $}}
57+
; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
58+
; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
59+
; RV64I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
60+
; RV64I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
61+
; RV64I-NEXT: BNE [[ANDI]], $x0, %bb.2
62+
; RV64I-NEXT: PseudoBR %bb.1
63+
; RV64I-NEXT: {{ $}}
64+
; RV64I-NEXT: bb.1:
65+
; RV64I-NEXT: {{ $}}
66+
; RV64I-NEXT: bb.2:
67+
; RV64I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.1, [[COPY1]], %bb.0
68+
; RV64I-NEXT: $x10 = COPY [[PHI]]
69+
; RV64I-NEXT: PseudoRET implicit $x10
70+
bb.0:
71+
liveins: $x10, $x11, $x12
72+
73+
%0:gprb(s64) = COPY $x10
74+
%1:gprb(p0) = COPY $x11
75+
%2:gprb(p0) = COPY $x12
76+
%3:gprb(s64) = G_CONSTANT i64 1
77+
%4:gprb(s64) = G_AND %0, %3
78+
G_BRCOND %4(s64), %bb.2
79+
G_BR %bb.1
80+
81+
bb.1:
82+
83+
bb.2:
84+
%5:gprb(p0) = G_PHI %2(p0), %bb.1, %1(p0), %bb.0
85+
$x10 = COPY %5(p0)
86+
PseudoRET implicit $x10
87+
88+
...

0 commit comments

Comments
 (0)