Skip to content

Commit 5f31dbd

Browse files
authored
[RISCV] Add register bank and instruction selection support for FP G_SELECT. (#72726)
Try to pick the FP register bank based on surrounding use/defs. Code is basically copied from AArch64. Need legalizer changes to make this more useful. Right now we're stuck with only being able to FP select types less than or equal to XLen.
1 parent 90b3e67 commit 5f31dbd

File tree

6 files changed

+554
-6
lines changed

6 files changed

+554
-6
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,8 +912,17 @@ bool RISCVInstructionSelector::selectSelect(MachineInstr &MI,
912912
RISCVCC::CondCode CC;
913913
getOperandsForBranch(SelectMI.getCondReg(), MRI, CC, LHS, RHS);
914914

915-
MachineInstr *Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
916-
.addDef(SelectMI.getReg(0))
915+
Register DstReg = SelectMI.getReg(0);
916+
917+
unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
918+
if (RBI.getRegBank(DstReg, MRI, TRI)->getID() == RISCV::FPRBRegBankID) {
919+
unsigned Size = MRI.getType(DstReg).getSizeInBits();
920+
Opc = Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
921+
: RISCV::Select_FPR64_Using_CC_GPR;
922+
}
923+
924+
MachineInstr *Result = MIB.buildInstr(Opc)
925+
.addDef(DstReg)
917926
.addReg(LHS)
918927
.addReg(RHS)
919928
.addImm(CC)

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

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,57 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
323323
OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
324324
break;
325325
}
326-
case TargetOpcode::G_SELECT:
327-
OpdsMapping[0] = GPRValueMapping;
326+
case TargetOpcode::G_SELECT: {
327+
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
328+
329+
// Try to minimize the number of copies. If we have more floating point
330+
// constrained values than not, then we'll put everything on FPR. Otherwise,
331+
// everything has to be on GPR.
332+
unsigned NumFP = 0;
333+
334+
// Check if the uses of the result always produce floating point values.
335+
//
336+
// For example:
337+
//
338+
// %z = G_SELECT %cond %x %y
339+
// fpr = G_FOO %z ...
340+
if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
341+
[&](const MachineInstr &UseMI) {
342+
return onlyUsesFP(UseMI, MRI, TRI);
343+
}))
344+
++NumFP;
345+
346+
// Check if the defs of the source values always produce floating point
347+
// values.
348+
//
349+
// For example:
350+
//
351+
// %x = G_SOMETHING_ALWAYS_FLOAT %a ...
352+
// %z = G_SELECT %cond %x %y
353+
//
354+
// Also check whether or not the sources have already been decided to be
355+
// FPR. Keep track of this.
356+
//
357+
// This doesn't check the condition, since the condition is always an
358+
// integer.
359+
for (unsigned Idx = 2; Idx < 4; ++Idx) {
360+
Register VReg = MI.getOperand(Idx).getReg();
361+
MachineInstr *DefMI = MRI.getVRegDef(VReg);
362+
if (getRegBank(VReg, MRI, TRI) == &RISCV::FPRBRegBank ||
363+
onlyDefinesFP(*DefMI, MRI, TRI))
364+
++NumFP;
365+
}
366+
367+
// Condition operand is always GPR.
328368
OpdsMapping[1] = GPRValueMapping;
329-
OpdsMapping[2] = GPRValueMapping;
330-
OpdsMapping[3] = GPRValueMapping;
369+
370+
const ValueMapping *Mapping = GPRValueMapping;
371+
if (NumFP >= 2)
372+
Mapping = getFPValueMapping(Ty.getSizeInBits());
373+
374+
OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
331375
break;
376+
}
332377
case TargetOpcode::G_FPTOSI:
333378
case TargetOpcode::G_FPTOUI:
334379
case RISCV::G_FCLASS: {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -mattr=+d -run-pass=instruction-select \
3+
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
4+
5+
---
6+
name: fp_select_s32
7+
legalized: true
8+
regBankSelected: true
9+
tracksRegLiveness: true
10+
body: |
11+
bb.0.entry:
12+
liveins: $x10, $f10_f, $f11_f
13+
14+
; CHECK-LABEL: name: fp_select_s32
15+
; CHECK: liveins: $x10, $f10_f, $f11_f
16+
; CHECK-NEXT: {{ $}}
17+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
18+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $f10_f
19+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY $f11_f
20+
; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
21+
; CHECK-NEXT: [[Select_FPR32_Using_CC_GPR:%[0-9]+]]:fpr32 = Select_FPR32_Using_CC_GPR [[ANDI]], $x0, 1, [[COPY1]], [[COPY2]]
22+
; CHECK-NEXT: $f10_f = COPY [[Select_FPR32_Using_CC_GPR]]
23+
; CHECK-NEXT: PseudoRET implicit $f10_f
24+
%0:gprb(s32) = COPY $x10
25+
%1:fprb(s32) = COPY $f10_f
26+
%2:fprb(s32) = COPY $f11_f
27+
%3:gprb(s32) = G_CONSTANT i32 1
28+
%4:gprb(s32) = G_AND %0, %3
29+
%5:fprb(s32) = G_SELECT %4(s32), %1, %2
30+
$f10_f = COPY %5(s32)
31+
PseudoRET implicit $f10_f
32+
33+
...
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv64 -mattr=+d -run-pass=instruction-select \
3+
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
4+
5+
---
6+
name: fp_select_s32
7+
alignment: 1
8+
legalized: true
9+
regBankSelected: true
10+
tracksRegLiveness: true
11+
body: |
12+
bb.0.entry:
13+
liveins: $x10, $f10_d, $f11_d
14+
15+
; CHECK-LABEL: name: fp_select_s32
16+
; CHECK: liveins: $x10, $f10_d, $f11_d
17+
; CHECK-NEXT: {{ $}}
18+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
19+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $f10_f
20+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY $f11_f
21+
; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
22+
; CHECK-NEXT: [[Select_FPR32_Using_CC_GPR:%[0-9]+]]:fpr32 = Select_FPR32_Using_CC_GPR [[ANDI]], $x0, 1, [[COPY1]], [[COPY2]]
23+
; CHECK-NEXT: $f10_f = COPY [[Select_FPR32_Using_CC_GPR]]
24+
; CHECK-NEXT: PseudoRET implicit $f10_f
25+
%0:gprb(s64) = COPY $x10
26+
%1:fprb(s32) = COPY $f10_f
27+
%2:fprb(s32) = COPY $f11_f
28+
%3:gprb(s64) = G_CONSTANT i64 1
29+
%4:gprb(s64) = G_AND %0, %3
30+
%5:fprb(s32) = G_SELECT %4(s64), %1, %2
31+
$f10_f = COPY %5(s32)
32+
PseudoRET implicit $f10_f
33+
34+
...
35+
---
36+
name: fp_select_s64
37+
alignment: 1
38+
legalized: true
39+
regBankSelected: true
40+
tracksRegLiveness: true
41+
body: |
42+
bb.0.entry:
43+
liveins: $x10, $f10_d, $f11_d
44+
45+
; CHECK-LABEL: name: fp_select_s64
46+
; CHECK: liveins: $x10, $f10_d, $f11_d
47+
; CHECK-NEXT: {{ $}}
48+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
49+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $f10_d
50+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY $f11_d
51+
; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
52+
; CHECK-NEXT: [[Select_FPR64_Using_CC_GPR:%[0-9]+]]:fpr64 = Select_FPR64_Using_CC_GPR [[ANDI]], $x0, 1, [[COPY1]], [[COPY2]]
53+
; CHECK-NEXT: $f10_d = COPY [[Select_FPR64_Using_CC_GPR]]
54+
; CHECK-NEXT: PseudoRET implicit $f10_d
55+
%0:gprb(s64) = COPY $x10
56+
%1:fprb(s64) = COPY $f10_d
57+
%2:fprb(s64) = COPY $f11_d
58+
%3:gprb(s64) = G_CONSTANT i64 1
59+
%4:gprb(s64) = G_AND %0, %3
60+
%5:fprb(s64) = G_SELECT %4(s64), %1, %2
61+
$f10_d = COPY %5(s64)
62+
PseudoRET implicit $f10_d
63+
64+
...
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -mattr=+d -run-pass=regbankselect \
3+
# RUN: -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
4+
# RUN: -o - | FileCheck -check-prefix=RV32I %s
5+
6+
---
7+
name: fp_select_s32
8+
legalized: true
9+
tracksRegLiveness: true
10+
body: |
11+
bb.0.entry:
12+
liveins: $x10, $f10_f, $f11_f
13+
14+
; RV32I-LABEL: name: fp_select_s32
15+
; RV32I: liveins: $x10, $f10_f, $f11_f
16+
; RV32I-NEXT: {{ $}}
17+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
18+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
19+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f11_f
20+
; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
21+
; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
22+
; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]]
23+
; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
24+
; RV32I-NEXT: PseudoRET implicit $f10_f
25+
%3:_(s32) = COPY $x10
26+
%4:_(s32) = COPY $f10_f
27+
%5:_(s32) = COPY $f11_f
28+
%12:_(s32) = G_CONSTANT i32 1
29+
%11:_(s32) = G_AND %3, %12
30+
%10:_(s32) = G_SELECT %11(s32), %4, %5
31+
$f10_f = COPY %10(s32)
32+
PseudoRET implicit $f10_f
33+
34+
...
35+
---
36+
name: fp_select_gpr_use_s32
37+
legalized: true
38+
tracksRegLiveness: true
39+
body: |
40+
bb.0.entry:
41+
liveins: $x10, $f10_f, $f11_f
42+
43+
; RV32I-LABEL: name: fp_select_gpr_use_s32
44+
; RV32I: liveins: $x10, $f10_f, $f11_f
45+
; RV32I-NEXT: {{ $}}
46+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
47+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
48+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f11_f
49+
; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
50+
; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
51+
; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]]
52+
; RV32I-NEXT: $x10 = COPY [[SELECT]](s32)
53+
; RV32I-NEXT: PseudoRET implicit $x10
54+
%3:_(s32) = COPY $x10
55+
%4:_(s32) = COPY $f10_f
56+
%5:_(s32) = COPY $f11_f
57+
%12:_(s32) = G_CONSTANT i32 1
58+
%11:_(s32) = G_AND %3, %12
59+
%10:_(s32) = G_SELECT %11(s32), %4, %5
60+
$x10 = COPY %10(s32)
61+
PseudoRET implicit $x10
62+
63+
...
64+
---
65+
name: fp_select_gpr_def_s32
66+
legalized: true
67+
tracksRegLiveness: true
68+
body: |
69+
bb.0.entry:
70+
liveins: $x10, $x11, $f10_f
71+
72+
; RV32I-LABEL: name: fp_select_gpr_def_s32
73+
; RV32I: liveins: $x10, $x11, $f10_f
74+
; RV32I-NEXT: {{ $}}
75+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
76+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
77+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $x11
78+
; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
79+
; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
80+
; RV32I-NEXT: [[COPY3:%[0-9]+]]:fprb(s32) = COPY [[COPY2]](s32)
81+
; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY3]]
82+
; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
83+
; RV32I-NEXT: PseudoRET implicit $f10_f
84+
%3:_(s32) = COPY $x10
85+
%4:_(s32) = COPY $f10_f
86+
%5:_(s32) = COPY $x11
87+
%12:_(s32) = G_CONSTANT i32 1
88+
%11:_(s32) = G_AND %3, %12
89+
%10:_(s32) = G_SELECT %11(s32), %4, %5
90+
$f10_f = COPY %10(s32)
91+
PseudoRET implicit $f10_f
92+
93+
...
94+
---
95+
name: fp_select_only_fpr_use_s32
96+
legalized: true
97+
tracksRegLiveness: true
98+
body: |
99+
bb.0.entry:
100+
liveins: $x10, $x11, $x12
101+
102+
; RV32I-LABEL: name: fp_select_only_fpr_use_s32
103+
; RV32I: liveins: $x10, $x11, $x12
104+
; RV32I-NEXT: {{ $}}
105+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
106+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $x11
107+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $x12
108+
; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
109+
; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
110+
; RV32I-NEXT: [[SELECT:%[0-9]+]]:gprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]]
111+
; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
112+
; RV32I-NEXT: PseudoRET implicit $f10_f
113+
%3:_(s32) = COPY $x10
114+
%4:_(s32) = COPY $x11
115+
%5:_(s32) = COPY $x12
116+
%12:_(s32) = G_CONSTANT i32 1
117+
%11:_(s32) = G_AND %3, %12
118+
%10:_(s32) = G_SELECT %11(s32), %4, %5
119+
$f10_f = COPY %10(s32)
120+
PseudoRET implicit $f10_f
121+
122+
...
123+
---
124+
name: fp_select_only_one_fpr_def_s32
125+
legalized: true
126+
tracksRegLiveness: true
127+
body: |
128+
bb.0.entry:
129+
liveins: $x10, $x11, $f10_f
130+
131+
; RV32I-LABEL: name: fp_select_only_one_fpr_def_s32
132+
; RV32I: liveins: $x10, $x11, $f10_f
133+
; RV32I-NEXT: {{ $}}
134+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
135+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
136+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $x11
137+
; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
138+
; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
139+
; RV32I-NEXT: [[COPY3:%[0-9]+]]:gprb(s32) = COPY [[COPY1]](s32)
140+
; RV32I-NEXT: [[SELECT:%[0-9]+]]:gprb(s32) = G_SELECT [[AND]](s32), [[COPY3]], [[COPY2]]
141+
; RV32I-NEXT: $x10 = COPY [[SELECT]](s32)
142+
; RV32I-NEXT: PseudoRET implicit $x10
143+
%3:_(s32) = COPY $x10
144+
%4:_(s32) = COPY $f10_f
145+
%5:_(s32) = COPY $x11
146+
%12:_(s32) = G_CONSTANT i32 1
147+
%11:_(s32) = G_AND %3, %12
148+
%10:_(s32) = G_SELECT %11(s32), %4, %5
149+
$x10 = COPY %10(s32)
150+
PseudoRET implicit $x10
151+
152+
...

0 commit comments

Comments
 (0)