Skip to content

Commit c62b014

Browse files
author
Hsiangkai Wang
committed
[RISCV] Merge addi into load/store as there is a ADD between them
This patch adds peephole optimizations for the following patterns: (load (add base, (addi src, off1)), off2) -> (load (add base, src), off1+off2) (store val, (add base, (addi src, off1)), off2) -> (store val, (add base, src), off1+off2) Differential Revision: https://reviews.llvm.org/D124231
1 parent 9fc58f1 commit c62b014

File tree

4 files changed

+133
-11
lines changed

4 files changed

+133
-11
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,10 @@ bool RISCVDAGToDAGISel::selectRVVSimm5(SDValue N, unsigned Width,
20532053
// Merge an ADDI into the offset of a load/store instruction where possible.
20542054
// (load (addi base, off1), off2) -> (load base, off1+off2)
20552055
// (store val, (addi base, off1), off2) -> (store val, base, off1+off2)
2056+
// (load (add base, (addi src, off1)), off2)
2057+
// -> (load (add base, src), off1+off2)
2058+
// (store val, (add base, (addi src, off1)), off2)
2059+
// -> (store val, (add base, src), off1+off2)
20562060
// This is possible when off1+off2 fits a 12-bit immediate.
20572061
bool RISCVDAGToDAGISel::doPeepholeLoadStoreADDI(SDNode *N) {
20582062
int OffsetOpIdx;
@@ -2092,8 +2096,34 @@ bool RISCVDAGToDAGISel::doPeepholeLoadStoreADDI(SDNode *N) {
20922096

20932097
SDValue Base = N->getOperand(BaseOpIdx);
20942098

2099+
if (!Base.isMachineOpcode())
2100+
return false;
2101+
2102+
// There is a ADD between ADDI and load/store.
2103+
SDValue Add;
2104+
int AddBaseIdx;
2105+
if (Base.getMachineOpcode() == RISCV::ADD) {
2106+
if (!Base.hasOneUse())
2107+
return false;
2108+
Add = Base;
2109+
SDValue Op0 = Base.getOperand(0);
2110+
SDValue Op1 = Base.getOperand(1);
2111+
if (Op0.isMachineOpcode() && Op0.getMachineOpcode() == RISCV::ADDI &&
2112+
isa<ConstantSDNode>(Op0.getOperand(1)) &&
2113+
cast<ConstantSDNode>(Op0.getOperand(1))->getSExtValue() != 0) {
2114+
AddBaseIdx = 1;
2115+
Base = Op0;
2116+
} else if (Op1.isMachineOpcode() && Op1.getMachineOpcode() == RISCV::ADDI &&
2117+
isa<ConstantSDNode>(Op1.getOperand(1)) &&
2118+
cast<ConstantSDNode>(Op1.getOperand(1))->getSExtValue() != 0) {
2119+
AddBaseIdx = 0;
2120+
Base = Op1;
2121+
} else
2122+
return false;
2123+
}
2124+
20952125
// If the base is an ADDI, we can merge it in to the load/store.
2096-
if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI)
2126+
if (Base.getMachineOpcode() != RISCV::ADDI)
20972127
return false;
20982128

20992129
SDValue ImmOperand = Base.getOperand(1);
@@ -2140,13 +2170,27 @@ bool RISCVDAGToDAGISel::doPeepholeLoadStoreADDI(SDNode *N) {
21402170
LLVM_DEBUG(N->dump(CurDAG));
21412171
LLVM_DEBUG(dbgs() << "\n");
21422172

2173+
if (Add)
2174+
Add = SDValue(CurDAG->UpdateNodeOperands(Add.getNode(),
2175+
Add.getOperand(AddBaseIdx),
2176+
Base.getOperand(0)),
2177+
0);
2178+
21432179
// Modify the offset operand of the load/store.
2144-
if (BaseOpIdx == 0) // Load
2145-
CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand,
2146-
N->getOperand(2));
2147-
else // Store
2148-
CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0),
2149-
ImmOperand, N->getOperand(3));
2180+
if (BaseOpIdx == 0) { // Load
2181+
if (Add)
2182+
N = CurDAG->UpdateNodeOperands(N, Add, ImmOperand, N->getOperand(2));
2183+
else
2184+
N = CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand,
2185+
N->getOperand(2));
2186+
} else { // Store
2187+
if (Add)
2188+
N = CurDAG->UpdateNodeOperands(N, N->getOperand(0), Add, ImmOperand,
2189+
N->getOperand(3));
2190+
else
2191+
N = CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0),
2192+
ImmOperand, N->getOperand(3));
2193+
}
21502194

21512195
return true;
21522196
}

llvm/test/CodeGen/RISCV/large-stack.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,12 @@ define void @test_emergency_spill_slot(i32 %a) {
5959
; RV32I-FPELIM-NEXT: sub sp, sp, a1
6060
; RV32I-FPELIM-NEXT: .cfi_def_cfa_offset 400016
6161
; RV32I-FPELIM-NEXT: lui a1, 78
62-
; RV32I-FPELIM-NEXT: addi a1, a1, 512
6362
; RV32I-FPELIM-NEXT: addi a2, sp, 8
6463
; RV32I-FPELIM-NEXT: add a1, a2, a1
6564
; RV32I-FPELIM-NEXT: #APP
6665
; RV32I-FPELIM-NEXT: nop
6766
; RV32I-FPELIM-NEXT: #NO_APP
68-
; RV32I-FPELIM-NEXT: sw a0, 0(a1)
67+
; RV32I-FPELIM-NEXT: sw a0, 512(a1)
6968
; RV32I-FPELIM-NEXT: #APP
7069
; RV32I-FPELIM-NEXT: nop
7170
; RV32I-FPELIM-NEXT: #NO_APP
@@ -95,15 +94,14 @@ define void @test_emergency_spill_slot(i32 %a) {
9594
; RV32I-WITHFP-NEXT: addi a1, a1, 688
9695
; RV32I-WITHFP-NEXT: sub sp, sp, a1
9796
; RV32I-WITHFP-NEXT: lui a1, 78
98-
; RV32I-WITHFP-NEXT: addi a1, a1, 512
9997
; RV32I-WITHFP-NEXT: lui a2, 1048478
10098
; RV32I-WITHFP-NEXT: addi a2, a2, 1388
10199
; RV32I-WITHFP-NEXT: add a2, s0, a2
102100
; RV32I-WITHFP-NEXT: add a1, a2, a1
103101
; RV32I-WITHFP-NEXT: #APP
104102
; RV32I-WITHFP-NEXT: nop
105103
; RV32I-WITHFP-NEXT: #NO_APP
106-
; RV32I-WITHFP-NEXT: sw a0, 0(a1)
104+
; RV32I-WITHFP-NEXT: sw a0, 512(a1)
107105
; RV32I-WITHFP-NEXT: #APP
108106
; RV32I-WITHFP-NEXT: nop
109107
; RV32I-WITHFP-NEXT: #NO_APP

llvm/test/CodeGen/RISCV/mem.ll

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,42 @@ define dso_local i32 @lw_sw_constant(i32 %a) nounwind {
198198
store i32 %a, i32* %1
199199
ret i32 %2
200200
}
201+
202+
define i32 @lw_far_local(i32* %a) {
203+
; RV32I-LABEL: lw_far_local:
204+
; RV32I: # %bb.0:
205+
; RV32I-NEXT: lui a1, 4
206+
; RV32I-NEXT: add a0, a0, a1
207+
; RV32I-NEXT: lw a0, -4(a0)
208+
; RV32I-NEXT: ret
209+
%1 = getelementptr inbounds i32, i32* %a, i64 4095
210+
%2 = load volatile i32, i32* %1
211+
ret i32 %2
212+
}
213+
214+
define void @st_far_local(i32* %a, i32 %b) {
215+
; RV32I-LABEL: st_far_local:
216+
; RV32I: # %bb.0:
217+
; RV32I-NEXT: lui a2, 4
218+
; RV32I-NEXT: add a0, a0, a2
219+
; RV32I-NEXT: sw a1, -4(a0)
220+
; RV32I-NEXT: ret
221+
%1 = getelementptr inbounds i32, i32* %a, i64 4095
222+
store i32 %b, i32* %1
223+
ret void
224+
}
225+
226+
define i32 @lw_sw_far_local(i32* %a, i32 %b) {
227+
; RV32I-LABEL: lw_sw_far_local:
228+
; RV32I: # %bb.0:
229+
; RV32I-NEXT: lui a2, 4
230+
; RV32I-NEXT: addi a2, a2, -4
231+
; RV32I-NEXT: add a2, a0, a2
232+
; RV32I-NEXT: lw a0, 0(a2)
233+
; RV32I-NEXT: sw a1, 0(a2)
234+
; RV32I-NEXT: ret
235+
%1 = getelementptr inbounds i32, i32* %a, i64 4095
236+
%2 = load volatile i32, i32* %1
237+
store i32 %b, i32* %1
238+
ret i32 %2
239+
}

llvm/test/CodeGen/RISCV/mem64.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,44 @@ define dso_local i64 @ld_sd_global(i64 %a) nounwind {
228228
store i64 %a, i64* %2
229229
ret i64 %1
230230
}
231+
232+
define i64 @lw_far_local(i64* %a) {
233+
; RV64I-LABEL: lw_far_local:
234+
; RV64I: # %bb.0:
235+
; RV64I-NEXT: lui a1, 8
236+
; RV64I-NEXT: addiw a1, a1, -8
237+
; RV64I-NEXT: add a0, a0, a1
238+
; RV64I-NEXT: ld a0, 0(a0)
239+
; RV64I-NEXT: ret
240+
%1 = getelementptr inbounds i64, i64* %a, i64 4095
241+
%2 = load volatile i64, i64* %1
242+
ret i64 %2
243+
}
244+
245+
define void @st_far_local(i64* %a, i64 %b) {
246+
; RV64I-LABEL: st_far_local:
247+
; RV64I: # %bb.0:
248+
; RV64I-NEXT: lui a2, 8
249+
; RV64I-NEXT: addiw a2, a2, -8
250+
; RV64I-NEXT: add a0, a0, a2
251+
; RV64I-NEXT: sd a1, 0(a0)
252+
; RV64I-NEXT: ret
253+
%1 = getelementptr inbounds i64, i64* %a, i64 4095
254+
store i64 %b, i64* %1
255+
ret void
256+
}
257+
258+
define i64 @lw_sw_far_local(i64* %a, i64 %b) {
259+
; RV64I-LABEL: lw_sw_far_local:
260+
; RV64I: # %bb.0:
261+
; RV64I-NEXT: lui a2, 8
262+
; RV64I-NEXT: addiw a2, a2, -8
263+
; RV64I-NEXT: add a2, a0, a2
264+
; RV64I-NEXT: ld a0, 0(a2)
265+
; RV64I-NEXT: sd a1, 0(a2)
266+
; RV64I-NEXT: ret
267+
%1 = getelementptr inbounds i64, i64* %a, i64 4095
268+
%2 = load volatile i64, i64* %1
269+
store i64 %b, i64* %1
270+
ret i64 %2
271+
}

0 commit comments

Comments
 (0)