Skip to content

Commit d605d9d

Browse files
authored
[RISCV][GISel] Support G_ROTL/G_ROTR with Zbb. (#72825)
1 parent e1e34cc commit d605d9d

File tree

8 files changed

+515
-100
lines changed

8 files changed

+515
-100
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,6 +2406,16 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
24062406
Observer.changedInstr(MI);
24072407
return Legalized;
24082408

2409+
case TargetOpcode::G_ROTR:
2410+
case TargetOpcode::G_ROTL:
2411+
if (TypeIdx != 1)
2412+
return UnableToLegalize;
2413+
2414+
Observer.changingInstr(MI);
2415+
widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
2416+
Observer.changedInstr(MI);
2417+
return Legalized;
2418+
24092419
case TargetOpcode::G_SDIV:
24102420
case TargetOpcode::G_SREM:
24112421
case TargetOpcode::G_SMIN:

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ class RISCVInstructionSelector : public InstructionSelector {
104104
// Custom renderers for tablegen
105105
void renderNegImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
106106
int OpIdx) const;
107+
void renderImmSubFromXLen(MachineInstrBuilder &MIB, const MachineInstr &MI,
108+
int OpIdx) const;
109+
void renderImmSubFrom32(MachineInstrBuilder &MIB, const MachineInstr &MI,
110+
int OpIdx) const;
107111
void renderImmPlus1(MachineInstrBuilder &MIB, const MachineInstr &MI,
108112
int OpIdx) const;
109113
void renderImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
@@ -721,6 +725,24 @@ void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
721725
MIB.addImm(-CstVal);
722726
}
723727

728+
void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
729+
const MachineInstr &MI,
730+
int OpIdx) const {
731+
assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
732+
"Expected G_CONSTANT");
733+
uint64_t CstVal = MI.getOperand(1).getCImm()->getZExtValue();
734+
MIB.addImm(STI.getXLen() - CstVal);
735+
}
736+
737+
void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
738+
const MachineInstr &MI,
739+
int OpIdx) const {
740+
assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
741+
"Expected G_CONSTANT");
742+
uint64_t CstVal = MI.getOperand(1).getCImm()->getZExtValue();
743+
MIB.addImm(32 - CstVal);
744+
}
745+
724746
void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
725747
const MachineInstr &MI,
726748
int OpIdx) const {

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
using namespace llvm;
2525
using namespace LegalityPredicates;
26+
using namespace LegalizeMutations;
2627

2728
// Is this type supported by scalar FP arithmetic operations given the current
2829
// subtarget.
@@ -99,7 +100,15 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
99100

100101
getActionDefinitionsBuilder({G_FSHL, G_FSHR}).lower();
101102

102-
getActionDefinitionsBuilder({G_ROTL, G_ROTR}).lower();
103+
auto &RotateActions = getActionDefinitionsBuilder({G_ROTL, G_ROTR});
104+
if (ST.hasStdExtZbb()) {
105+
RotateActions.legalFor({{s32, sXLen}, {sXLen, sXLen}});
106+
// Widen s32 rotate amount to s64 so SDAG patterns will match.
107+
if (ST.is64Bit())
108+
RotateActions.widenScalarIf(all(typeIs(0, s32), typeIs(1, s32)),
109+
changeTo(1, sXLen));
110+
}
111+
RotateActions.lower();
103112

104113
getActionDefinitionsBuilder(G_BITREVERSE).maxScalar(0, sXLen).lower();
105114

llvm/lib/Target/RISCV/RISCVGISel.td

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ def ImmPlus1 : SDNodeXForm<imm, [{
3737
def GINegImm : GICustomOperandRenderer<"renderNegImm">,
3838
GISDNodeXFormEquiv<NegImm>;
3939

40+
def GIImmSubFromXLen : GICustomOperandRenderer<"renderImmSubFromXLen">,
41+
GISDNodeXFormEquiv<ImmSubFromXLen>;
42+
def GIImmSubFrom32 : GICustomOperandRenderer<"renderImmSubFrom32">,
43+
GISDNodeXFormEquiv<ImmSubFrom32>;
44+
4045
def GIImmPlus1 :
4146
GICustomOperandRenderer<"renderImmPlus1">,
4247
GISDNodeXFormEquiv<ImmPlus1>;
@@ -56,9 +61,12 @@ def gi_trailing_zero : GICustomOperandRenderer<"renderTrailingZeros">,
5661
// parameter appears to be ignored so this pattern works for both, however we
5762
// should add a LowLevelTypeByHwMode, and use that to define our XLenLLT instead
5863
// here.
59-
def ShiftMaskGI :
64+
def GIShiftMaskXLen :
6065
GIComplexOperandMatcher<s32, "selectShiftMask">,
6166
GIComplexPatternEquiv<shiftMaskXLen>;
67+
def GIShiftMask32 :
68+
GIComplexOperandMatcher<s32, "selectShiftMask">,
69+
GIComplexPatternEquiv<shiftMask32>;
6270

6371
def gi_sh1add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<1>">,
6472
GIComplexPatternEquiv<sh1add_op>;
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -mattr=+zbb -run-pass=instruction-select \
3+
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
4+
5+
---
6+
name: rotl_i32
7+
legalized: true
8+
regBankSelected: true
9+
body: |
10+
bb.0:
11+
liveins: $x10, $x11
12+
13+
; CHECK-LABEL: name: rotl_i32
14+
; CHECK: liveins: $x10, $x11
15+
; CHECK-NEXT: {{ $}}
16+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
17+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
18+
; CHECK-NEXT: [[ROL:%[0-9]+]]:gpr = ROL [[COPY]], [[COPY1]]
19+
; CHECK-NEXT: $x10 = COPY [[ROL]]
20+
; CHECK-NEXT: PseudoRET implicit $x10
21+
%0:gprb(s32) = COPY $x10
22+
%1:gprb(s32) = COPY $x11
23+
%2:gprb(s32) = G_ROTL %0, %1(s32)
24+
$x10 = COPY %2(s32)
25+
PseudoRET implicit $x10
26+
27+
...
28+
---
29+
name: rotr_i32
30+
legalized: true
31+
regBankSelected: true
32+
body: |
33+
bb.0:
34+
liveins: $x10, $x11
35+
36+
; CHECK-LABEL: name: rotr_i32
37+
; CHECK: liveins: $x10, $x11
38+
; CHECK-NEXT: {{ $}}
39+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
40+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
41+
; CHECK-NEXT: [[ROR:%[0-9]+]]:gpr = ROR [[COPY]], [[COPY1]]
42+
; CHECK-NEXT: $x10 = COPY [[ROR]]
43+
; CHECK-NEXT: PseudoRET implicit $x10
44+
%0:gprb(s32) = COPY $x10
45+
%1:gprb(s32) = COPY $x11
46+
%2:gprb(s32) = G_ROTR %0, %1(s32)
47+
$x10 = COPY %2(s32)
48+
PseudoRET implicit $x10
49+
50+
...
51+
---
52+
name: rotl_imm_i32
53+
legalized: true
54+
regBankSelected: true
55+
body: |
56+
bb.0:
57+
liveins: $x10
58+
59+
; CHECK-LABEL: name: rotl_imm_i32
60+
; CHECK: liveins: $x10
61+
; CHECK-NEXT: {{ $}}
62+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
63+
; CHECK-NEXT: [[RORI:%[0-9]+]]:gpr = RORI [[COPY]], 27
64+
; CHECK-NEXT: $x10 = COPY [[RORI]]
65+
; CHECK-NEXT: PseudoRET implicit $x10
66+
%0:gprb(s32) = COPY $x10
67+
%1:gprb(s32) = G_CONSTANT i32 5
68+
%2:gprb(s32) = G_ROTL %0, %1(s32)
69+
$x10 = COPY %2(s32)
70+
PseudoRET implicit $x10
71+
72+
...
73+
---
74+
name: rotr_imm_i32
75+
legalized: true
76+
regBankSelected: true
77+
body: |
78+
bb.0:
79+
liveins: $x10
80+
81+
; CHECK-LABEL: name: rotr_imm_i32
82+
; CHECK: liveins: $x10
83+
; CHECK-NEXT: {{ $}}
84+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
85+
; CHECK-NEXT: [[RORI:%[0-9]+]]:gpr = RORI [[COPY]], 5
86+
; CHECK-NEXT: $x10 = COPY [[RORI]]
87+
; CHECK-NEXT: PseudoRET implicit $x10
88+
%0:gprb(s32) = COPY $x10
89+
%1:gprb(s32) = G_CONSTANT i32 5
90+
%2:gprb(s32) = G_ROTR %0, %1(s32)
91+
$x10 = COPY %2(s32)
92+
PseudoRET implicit $x10
93+
94+
...

0 commit comments

Comments
 (0)