Skip to content

Commit 48b3c2a

Browse files
committed
[RISCV] ADDI Optimization
Signed-off-by: Luke Quinn <[email protected]>
1 parent b1101e6 commit 48b3c2a

File tree

3 files changed

+70
-49
lines changed

3 files changed

+70
-49
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ class RISCVInstructionSelector : public InstructionSelector {
137137
void renderXLenSubTrailingOnes(MachineInstrBuilder &MIB,
138138
const MachineInstr &MI, int OpIdx) const;
139139

140+
void renderAddiPairImmLarge(MachineInstrBuilder &MIB, const MachineInstr &MI,
141+
int OpIdx) const;
142+
void renderAddiPairImmSmall(MachineInstrBuilder &MIB, const MachineInstr &MI,
143+
int OpIdx) const;
144+
140145
const RISCVSubtarget &STI;
141146
const RISCVInstrInfo &TII;
142147
const RISCVRegisterInfo &TRI;
@@ -871,6 +876,25 @@ void RISCVInstructionSelector::renderXLenSubTrailingOnes(
871876
MIB.addImm(Subtarget->getXLen() - llvm::countr_one(C));
872877
}
873878

879+
void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
880+
const MachineInstr &MI,
881+
int OpIdx) const {
882+
assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
883+
"Expected G_CONSTANT");
884+
int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue();
885+
int64_t Adj = Imm < 0 ? -2048 : 2047;
886+
MIB.addImm(Imm - Adj);
887+
}
888+
889+
void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
890+
const MachineInstr &MI,
891+
int OpIdx) const {
892+
assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
893+
"Expected G_CONSTANT");
894+
int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
895+
MIB.addImm(Imm);
896+
}
897+
874898
const TargetRegisterClass *RISCVInstructionSelector::getRegClassForTypeOnBank(
875899
LLT Ty, const RegisterBank &RB) const {
876900
if (RB.getID() == RISCV::GPRBRegBankID) {

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,14 @@ def AddiPair : PatLeaf<(imm), [{
454454
// The immediate operand must be in range [-4096,-2049] or [2048,4094].
455455
int64_t Imm = N->getSExtValue();
456456
return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
457-
}]>;
457+
}]> {
458+
let GISelPredicateCode = [{
459+
if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
460+
return false;
461+
int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue();
462+
return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
463+
}];
464+
}
458465

459466
// Return imm - (imm < 0 ? -2048 : 2047).
460467
def AddiPairImmSmall : SDNodeXForm<imm, [{
@@ -463,13 +470,17 @@ def AddiPairImmSmall : SDNodeXForm<imm, [{
463470
return CurDAG->getSignedTargetConstant(Imm - Adj, SDLoc(N),
464471
N->getValueType(0));
465472
}]>;
473+
def GIAddiPairImmSmall : GICustomOperandRenderer<"renderAddiPairImmSmall">,
474+
GISDNodeXFormEquiv<AddiPairImmSmall>;
466475

467476
// Return -2048 if immediate is negative or 2047 if positive. These are the
468477
// largest simm12 values.
469478
def AddiPairImmLarge : SDNodeXForm<imm, [{
470479
int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047;
471480
return CurDAG->getSignedTargetConstant(Imm, SDLoc(N), N->getValueType(0));
472481
}]>;
482+
def GIAddiPairImmLarge : GICustomOperandRenderer<"renderAddiPairImmLarge">,
483+
GISDNodeXFormEquiv<AddiPairImmLarge>;
473484

474485
def TrailingZeros : SDNodeXForm<imm, [{
475486
return CurDAG->getTargetConstant(llvm::countr_zero(N->getZExtValue()),
@@ -537,7 +548,6 @@ def LeadingOnesWMask : PatLeaf<(imm), [{
537548
return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&
538549
Imm != UINT64_C(0xffffffff);
539550
}];
540-
541551
}
542552

543553
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/RISCV/GlobalISel/add-imm.ll

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,14 @@ define i32 @add_positive_low_bound_reject(i32 %a) nounwind {
2323
define i32 @add_positive_low_bound_accept(i32 %a) nounwind {
2424
; RV32I-LABEL: add_positive_low_bound_accept:
2525
; RV32I: # %bb.0:
26-
; RV32I-NEXT: li a1, 1
27-
; RV32I-NEXT: slli a1, a1, 11
28-
; RV32I-NEXT: add a0, a0, a1
26+
; RV32I-NEXT: addi a0, a0, 2047
27+
; RV32I-NEXT: addi a0, a0, 1
2928
; RV32I-NEXT: ret
3029
;
3130
; RV64I-LABEL: add_positive_low_bound_accept:
3231
; RV64I: # %bb.0:
33-
; RV64I-NEXT: li a1, 1
34-
; RV64I-NEXT: slli a1, a1, 11
35-
; RV64I-NEXT: add a0, a0, a1
32+
; RV64I-NEXT: addi a0, a0, 2047
33+
; RV64I-NEXT: addi a0, a0, 1
3634
; RV64I-NEXT: ret
3735
%1 = add i32 %a, 2048
3836
ret i32 %1
@@ -41,16 +39,14 @@ define i32 @add_positive_low_bound_accept(i32 %a) nounwind {
4139
define i32 @add_positive_high_bound_accept(i32 %a) nounwind {
4240
; RV32I-LABEL: add_positive_high_bound_accept:
4341
; RV32I: # %bb.0:
44-
; RV32I-NEXT: lui a1, 1
45-
; RV32I-NEXT: addi a1, a1, -2
46-
; RV32I-NEXT: add a0, a0, a1
42+
; RV32I-NEXT: addi a0, a0, 2047
43+
; RV32I-NEXT: addi a0, a0, 2047
4744
; RV32I-NEXT: ret
4845
;
4946
; RV64I-LABEL: add_positive_high_bound_accept:
5047
; RV64I: # %bb.0:
51-
; RV64I-NEXT: lui a1, 1
52-
; RV64I-NEXT: addiw a1, a1, -2
53-
; RV64I-NEXT: add a0, a0, a1
48+
; RV64I-NEXT: addi a0, a0, 2047
49+
; RV64I-NEXT: addi a0, a0, 2047
5450
; RV64I-NEXT: ret
5551
%1 = add i32 %a, 4094
5652
ret i32 %1
@@ -91,16 +87,14 @@ define i32 @add_negative_high_bound_reject(i32 %a) nounwind {
9187
define i32 @add_negative_high_bound_accept(i32 %a) nounwind {
9288
; RV32I-LABEL: add_negative_high_bound_accept:
9389
; RV32I: # %bb.0:
94-
; RV32I-NEXT: lui a1, 1048575
95-
; RV32I-NEXT: addi a1, a1, 2047
96-
; RV32I-NEXT: add a0, a0, a1
90+
; RV32I-NEXT: addi a0, a0, -2048
91+
; RV32I-NEXT: addi a0, a0, -1
9792
; RV32I-NEXT: ret
9893
;
9994
; RV64I-LABEL: add_negative_high_bound_accept:
10095
; RV64I: # %bb.0:
101-
; RV64I-NEXT: lui a1, 1048575
102-
; RV64I-NEXT: addiw a1, a1, 2047
103-
; RV64I-NEXT: add a0, a0, a1
96+
; RV64I-NEXT: addi a0, a0, -2048
97+
; RV64I-NEXT: addi a0, a0, -1
10498
; RV64I-NEXT: ret
10599
%1 = add i32 %a, -2049
106100
ret i32 %1
@@ -109,14 +103,14 @@ define i32 @add_negative_high_bound_accept(i32 %a) nounwind {
109103
define i32 @add_negative_low_bound_accept(i32 %a) nounwind {
110104
; RV32I-LABEL: add_negative_low_bound_accept:
111105
; RV32I: # %bb.0:
112-
; RV32I-NEXT: lui a1, 1048575
113-
; RV32I-NEXT: add a0, a0, a1
106+
; RV32I-NEXT: addi a0, a0, -2048
107+
; RV32I-NEXT: addi a0, a0, -2048
114108
; RV32I-NEXT: ret
115109
;
116110
; RV64I-LABEL: add_negative_low_bound_accept:
117111
; RV64I: # %bb.0:
118-
; RV64I-NEXT: lui a1, 1048575
119-
; RV64I-NEXT: add a0, a0, a1
112+
; RV64I-NEXT: addi a0, a0, -2048
113+
; RV64I-NEXT: addi a0, a0, -2048
120114
; RV64I-NEXT: ret
121115
%1 = add i32 %a, -4096
122116
ret i32 %1
@@ -143,16 +137,14 @@ define i32 @add_negative_low_bound_reject(i32 %a) nounwind {
143137
define i32 @add32_accept(i32 %a) nounwind {
144138
; RV32I-LABEL: add32_accept:
145139
; RV32I: # %bb.0:
146-
; RV32I-NEXT: lui a1, 1
147-
; RV32I-NEXT: addi a1, a1, -1097
148-
; RV32I-NEXT: add a0, a0, a1
140+
; RV32I-NEXT: addi a0, a0, 2047
141+
; RV32I-NEXT: addi a0, a0, 952
149142
; RV32I-NEXT: ret
150143
;
151144
; RV64I-LABEL: add32_accept:
152145
; RV64I: # %bb.0:
153-
; RV64I-NEXT: lui a1, 1
154-
; RV64I-NEXT: addiw a1, a1, -1097
155-
; RV64I-NEXT: add a0, a0, a1
146+
; RV64I-NEXT: addi a0, a0, 2047
147+
; RV64I-NEXT: addi a0, a0, 952
156148
; RV64I-NEXT: ret
157149
%1 = add i32 %a, 2999
158150
ret i32 %1
@@ -161,16 +153,14 @@ define i32 @add32_accept(i32 %a) nounwind {
161153
define signext i32 @add32_sext_accept(i32 signext %a) nounwind {
162154
; RV32I-LABEL: add32_sext_accept:
163155
; RV32I: # %bb.0:
164-
; RV32I-NEXT: lui a1, 1
165-
; RV32I-NEXT: addi a1, a1, -1097
166-
; RV32I-NEXT: add a0, a0, a1
156+
; RV32I-NEXT: addi a0, a0, 2047
157+
; RV32I-NEXT: addi a0, a0, 952
167158
; RV32I-NEXT: ret
168159
;
169160
; RV64I-LABEL: add32_sext_accept:
170161
; RV64I: # %bb.0:
171-
; RV64I-NEXT: lui a1, 1
172-
; RV64I-NEXT: addi a1, a1, -1097
173-
; RV64I-NEXT: addw a0, a0, a1
162+
; RV64I-NEXT: addi a0, a0, 2047
163+
; RV64I-NEXT: addiw a0, a0, 952
174164
; RV64I-NEXT: ret
175165
%1 = add i32 %a, 2999
176166
ret i32 %1
@@ -180,20 +170,18 @@ define signext i32 @add32_sext_accept(i32 signext %a) nounwind {
180170
define signext i32 @add32_sext_reject_on_rv64(i32 signext %a) nounwind {
181171
; RV32I-LABEL: add32_sext_reject_on_rv64:
182172
; RV32I: # %bb.0:
183-
; RV32I-NEXT: lui a1, 1
184-
; RV32I-NEXT: addi a1, a1, -1096
185-
; RV32I-NEXT: lui a2, %hi(gv0)
186-
; RV32I-NEXT: add a0, a0, a1
187-
; RV32I-NEXT: sw a0, %lo(gv0)(a2)
173+
; RV32I-NEXT: lui a1, %hi(gv0)
174+
; RV32I-NEXT: addi a0, a0, 2047
175+
; RV32I-NEXT: addi a0, a0, 953
176+
; RV32I-NEXT: sw a0, %lo(gv0)(a1)
188177
; RV32I-NEXT: ret
189178
;
190179
; RV64I-LABEL: add32_sext_reject_on_rv64:
191180
; RV64I: # %bb.0:
192-
; RV64I-NEXT: lui a1, 1
193-
; RV64I-NEXT: addi a1, a1, -1096
194-
; RV64I-NEXT: lui a2, %hi(gv0)
195-
; RV64I-NEXT: addw a0, a0, a1
196-
; RV64I-NEXT: sw a0, %lo(gv0)(a2)
181+
; RV64I-NEXT: lui a1, %hi(gv0)
182+
; RV64I-NEXT: addi a0, a0, 2047
183+
; RV64I-NEXT: addiw a0, a0, 953
184+
; RV64I-NEXT: sw a0, %lo(gv0)(a1)
197185
; RV64I-NEXT: ret
198186
%b = add nsw i32 %a, 3000
199187
store i32 %b, ptr @gv0, align 4
@@ -212,9 +200,8 @@ define i64 @add64_accept(i64 %a) nounwind {
212200
;
213201
; RV64I-LABEL: add64_accept:
214202
; RV64I: # %bb.0:
215-
; RV64I-NEXT: lui a1, 1
216-
; RV64I-NEXT: addiw a1, a1, -1097
217-
; RV64I-NEXT: add a0, a0, a1
203+
; RV64I-NEXT: addi a0, a0, 2047
204+
; RV64I-NEXT: addi a0, a0, 952
218205
; RV64I-NEXT: ret
219206
%1 = add i64 %a, 2999
220207
ret i64 %1

0 commit comments

Comments
 (0)