Skip to content

Commit e47fd09

Browse files
authored
[RISCV] Use shNadd for scalable stack offsets (#88062)
If we need to multiply VLENB by 2, 4, or 8 and add it to the stack pointer, we can do so with a shNadd instead of separate shift and add instructions.
1 parent 23b058c commit e47fd09

File tree

2 files changed

+195
-62
lines changed

2 files changed

+195
-62
lines changed

llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,21 @@ void RISCVRegisterInfo::adjustReg(MachineBasicBlock &MBB,
204204
uint32_t NumOfVReg = ScalableValue / 8;
205205
BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), ScratchReg)
206206
.setMIFlag(Flag);
207-
TII->mulImm(MF, MBB, II, DL, ScratchReg, NumOfVReg, Flag);
208-
BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), DestReg)
209-
.addReg(SrcReg).addReg(ScratchReg, RegState::Kill)
210-
.setMIFlag(Flag);
207+
208+
if (ScalableAdjOpc == RISCV::ADD && ST.hasStdExtZba() &&
209+
(NumOfVReg == 2 || NumOfVReg == 4 || NumOfVReg == 8)) {
210+
unsigned Opc = NumOfVReg == 2 ? RISCV::SH1ADD :
211+
(NumOfVReg == 4 ? RISCV::SH2ADD : RISCV::SH3ADD);
212+
BuildMI(MBB, II, DL, TII->get(Opc), DestReg)
213+
.addReg(ScratchReg, RegState::Kill)
214+
.addReg(SrcReg, getKillRegState(KillSrcReg))
215+
.setMIFlag(Flag);
216+
} else {
217+
TII->mulImm(MF, MBB, II, DL, ScratchReg, NumOfVReg, Flag);
218+
BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), DestReg)
219+
.addReg(SrcReg).addReg(ScratchReg, RegState::Kill)
220+
.setMIFlag(Flag);
221+
}
211222
SrcReg = DestReg;
212223
KillSrcReg = true;
213224
}

llvm/test/CodeGen/RISCV/rvv/allocate-lmul-2-4-8.ll

Lines changed: 180 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,67 @@
77
; RUN: | FileCheck %s --check-prefixes=CHECK,NOMUL
88

99
define void @lmul1() nounwind {
10-
; CHECK-LABEL: lmul1:
11-
; CHECK: # %bb.0:
12-
; CHECK-NEXT: csrr a0, vlenb
13-
; CHECK-NEXT: slli a0, a0, 1
14-
; CHECK-NEXT: sub sp, sp, a0
15-
; CHECK-NEXT: csrr a0, vlenb
16-
; CHECK-NEXT: slli a0, a0, 1
17-
; CHECK-NEXT: add sp, sp, a0
18-
; CHECK-NEXT: ret
10+
; NOZBA-LABEL: lmul1:
11+
; NOZBA: # %bb.0:
12+
; NOZBA-NEXT: csrr a0, vlenb
13+
; NOZBA-NEXT: slli a0, a0, 1
14+
; NOZBA-NEXT: sub sp, sp, a0
15+
; NOZBA-NEXT: csrr a0, vlenb
16+
; NOZBA-NEXT: slli a0, a0, 1
17+
; NOZBA-NEXT: add sp, sp, a0
18+
; NOZBA-NEXT: ret
19+
;
20+
; ZBA-LABEL: lmul1:
21+
; ZBA: # %bb.0:
22+
; ZBA-NEXT: csrr a0, vlenb
23+
; ZBA-NEXT: slli a0, a0, 1
24+
; ZBA-NEXT: sub sp, sp, a0
25+
; ZBA-NEXT: csrr a0, vlenb
26+
; ZBA-NEXT: sh1add sp, a0, sp
27+
; ZBA-NEXT: ret
28+
;
29+
; NOMUL-LABEL: lmul1:
30+
; NOMUL: # %bb.0:
31+
; NOMUL-NEXT: csrr a0, vlenb
32+
; NOMUL-NEXT: slli a0, a0, 1
33+
; NOMUL-NEXT: sub sp, sp, a0
34+
; NOMUL-NEXT: csrr a0, vlenb
35+
; NOMUL-NEXT: slli a0, a0, 1
36+
; NOMUL-NEXT: add sp, sp, a0
37+
; NOMUL-NEXT: ret
1938
%v = alloca <vscale x 1 x i64>
2039
ret void
2140
}
2241

2342
define void @lmul2() nounwind {
24-
; CHECK-LABEL: lmul2:
25-
; CHECK: # %bb.0:
26-
; CHECK-NEXT: csrr a0, vlenb
27-
; CHECK-NEXT: slli a0, a0, 1
28-
; CHECK-NEXT: sub sp, sp, a0
29-
; CHECK-NEXT: csrr a0, vlenb
30-
; CHECK-NEXT: slli a0, a0, 1
31-
; CHECK-NEXT: add sp, sp, a0
32-
; CHECK-NEXT: ret
43+
; NOZBA-LABEL: lmul2:
44+
; NOZBA: # %bb.0:
45+
; NOZBA-NEXT: csrr a0, vlenb
46+
; NOZBA-NEXT: slli a0, a0, 1
47+
; NOZBA-NEXT: sub sp, sp, a0
48+
; NOZBA-NEXT: csrr a0, vlenb
49+
; NOZBA-NEXT: slli a0, a0, 1
50+
; NOZBA-NEXT: add sp, sp, a0
51+
; NOZBA-NEXT: ret
52+
;
53+
; ZBA-LABEL: lmul2:
54+
; ZBA: # %bb.0:
55+
; ZBA-NEXT: csrr a0, vlenb
56+
; ZBA-NEXT: slli a0, a0, 1
57+
; ZBA-NEXT: sub sp, sp, a0
58+
; ZBA-NEXT: csrr a0, vlenb
59+
; ZBA-NEXT: sh1add sp, a0, sp
60+
; ZBA-NEXT: ret
61+
;
62+
; NOMUL-LABEL: lmul2:
63+
; NOMUL: # %bb.0:
64+
; NOMUL-NEXT: csrr a0, vlenb
65+
; NOMUL-NEXT: slli a0, a0, 1
66+
; NOMUL-NEXT: sub sp, sp, a0
67+
; NOMUL-NEXT: csrr a0, vlenb
68+
; NOMUL-NEXT: slli a0, a0, 1
69+
; NOMUL-NEXT: add sp, sp, a0
70+
; NOMUL-NEXT: ret
3371
%v = alloca <vscale x 2 x i64>
3472
ret void
3573
}
@@ -75,15 +113,34 @@ define void @lmul8() nounwind {
75113
}
76114

77115
define void @lmul1_and_2() nounwind {
78-
; CHECK-LABEL: lmul1_and_2:
79-
; CHECK: # %bb.0:
80-
; CHECK-NEXT: csrr a0, vlenb
81-
; CHECK-NEXT: slli a0, a0, 2
82-
; CHECK-NEXT: sub sp, sp, a0
83-
; CHECK-NEXT: csrr a0, vlenb
84-
; CHECK-NEXT: slli a0, a0, 2
85-
; CHECK-NEXT: add sp, sp, a0
86-
; CHECK-NEXT: ret
116+
; NOZBA-LABEL: lmul1_and_2:
117+
; NOZBA: # %bb.0:
118+
; NOZBA-NEXT: csrr a0, vlenb
119+
; NOZBA-NEXT: slli a0, a0, 2
120+
; NOZBA-NEXT: sub sp, sp, a0
121+
; NOZBA-NEXT: csrr a0, vlenb
122+
; NOZBA-NEXT: slli a0, a0, 2
123+
; NOZBA-NEXT: add sp, sp, a0
124+
; NOZBA-NEXT: ret
125+
;
126+
; ZBA-LABEL: lmul1_and_2:
127+
; ZBA: # %bb.0:
128+
; ZBA-NEXT: csrr a0, vlenb
129+
; ZBA-NEXT: slli a0, a0, 2
130+
; ZBA-NEXT: sub sp, sp, a0
131+
; ZBA-NEXT: csrr a0, vlenb
132+
; ZBA-NEXT: sh2add sp, a0, sp
133+
; ZBA-NEXT: ret
134+
;
135+
; NOMUL-LABEL: lmul1_and_2:
136+
; NOMUL: # %bb.0:
137+
; NOMUL-NEXT: csrr a0, vlenb
138+
; NOMUL-NEXT: slli a0, a0, 2
139+
; NOMUL-NEXT: sub sp, sp, a0
140+
; NOMUL-NEXT: csrr a0, vlenb
141+
; NOMUL-NEXT: slli a0, a0, 2
142+
; NOMUL-NEXT: add sp, sp, a0
143+
; NOMUL-NEXT: ret
87144
%v1 = alloca <vscale x 1 x i64>
88145
%v2 = alloca <vscale x 2 x i64>
89146
ret void
@@ -132,15 +189,34 @@ define void @lmul1_and_4() nounwind {
132189
}
133190

134191
define void @lmul2_and_1() nounwind {
135-
; CHECK-LABEL: lmul2_and_1:
136-
; CHECK: # %bb.0:
137-
; CHECK-NEXT: csrr a0, vlenb
138-
; CHECK-NEXT: slli a0, a0, 2
139-
; CHECK-NEXT: sub sp, sp, a0
140-
; CHECK-NEXT: csrr a0, vlenb
141-
; CHECK-NEXT: slli a0, a0, 2
142-
; CHECK-NEXT: add sp, sp, a0
143-
; CHECK-NEXT: ret
192+
; NOZBA-LABEL: lmul2_and_1:
193+
; NOZBA: # %bb.0:
194+
; NOZBA-NEXT: csrr a0, vlenb
195+
; NOZBA-NEXT: slli a0, a0, 2
196+
; NOZBA-NEXT: sub sp, sp, a0
197+
; NOZBA-NEXT: csrr a0, vlenb
198+
; NOZBA-NEXT: slli a0, a0, 2
199+
; NOZBA-NEXT: add sp, sp, a0
200+
; NOZBA-NEXT: ret
201+
;
202+
; ZBA-LABEL: lmul2_and_1:
203+
; ZBA: # %bb.0:
204+
; ZBA-NEXT: csrr a0, vlenb
205+
; ZBA-NEXT: slli a0, a0, 2
206+
; ZBA-NEXT: sub sp, sp, a0
207+
; ZBA-NEXT: csrr a0, vlenb
208+
; ZBA-NEXT: sh2add sp, a0, sp
209+
; ZBA-NEXT: ret
210+
;
211+
; NOMUL-LABEL: lmul2_and_1:
212+
; NOMUL: # %bb.0:
213+
; NOMUL-NEXT: csrr a0, vlenb
214+
; NOMUL-NEXT: slli a0, a0, 2
215+
; NOMUL-NEXT: sub sp, sp, a0
216+
; NOMUL-NEXT: csrr a0, vlenb
217+
; NOMUL-NEXT: slli a0, a0, 2
218+
; NOMUL-NEXT: add sp, sp, a0
219+
; NOMUL-NEXT: ret
144220
%v1 = alloca <vscale x 2 x i64>
145221
%v2 = alloca <vscale x 1 x i64>
146222
ret void
@@ -273,19 +349,46 @@ define void @lmul4_and_2_x2_1() nounwind {
273349

274350

275351
define void @gpr_and_lmul1_and_2() nounwind {
276-
; CHECK-LABEL: gpr_and_lmul1_and_2:
277-
; CHECK: # %bb.0:
278-
; CHECK-NEXT: addi sp, sp, -16
279-
; CHECK-NEXT: csrr a0, vlenb
280-
; CHECK-NEXT: slli a0, a0, 2
281-
; CHECK-NEXT: sub sp, sp, a0
282-
; CHECK-NEXT: li a0, 3
283-
; CHECK-NEXT: sd a0, 8(sp)
284-
; CHECK-NEXT: csrr a0, vlenb
285-
; CHECK-NEXT: slli a0, a0, 2
286-
; CHECK-NEXT: add sp, sp, a0
287-
; CHECK-NEXT: addi sp, sp, 16
288-
; CHECK-NEXT: ret
352+
; NOZBA-LABEL: gpr_and_lmul1_and_2:
353+
; NOZBA: # %bb.0:
354+
; NOZBA-NEXT: addi sp, sp, -16
355+
; NOZBA-NEXT: csrr a0, vlenb
356+
; NOZBA-NEXT: slli a0, a0, 2
357+
; NOZBA-NEXT: sub sp, sp, a0
358+
; NOZBA-NEXT: li a0, 3
359+
; NOZBA-NEXT: sd a0, 8(sp)
360+
; NOZBA-NEXT: csrr a0, vlenb
361+
; NOZBA-NEXT: slli a0, a0, 2
362+
; NOZBA-NEXT: add sp, sp, a0
363+
; NOZBA-NEXT: addi sp, sp, 16
364+
; NOZBA-NEXT: ret
365+
;
366+
; ZBA-LABEL: gpr_and_lmul1_and_2:
367+
; ZBA: # %bb.0:
368+
; ZBA-NEXT: addi sp, sp, -16
369+
; ZBA-NEXT: csrr a0, vlenb
370+
; ZBA-NEXT: slli a0, a0, 2
371+
; ZBA-NEXT: sub sp, sp, a0
372+
; ZBA-NEXT: li a0, 3
373+
; ZBA-NEXT: sd a0, 8(sp)
374+
; ZBA-NEXT: csrr a0, vlenb
375+
; ZBA-NEXT: sh2add sp, a0, sp
376+
; ZBA-NEXT: addi sp, sp, 16
377+
; ZBA-NEXT: ret
378+
;
379+
; NOMUL-LABEL: gpr_and_lmul1_and_2:
380+
; NOMUL: # %bb.0:
381+
; NOMUL-NEXT: addi sp, sp, -16
382+
; NOMUL-NEXT: csrr a0, vlenb
383+
; NOMUL-NEXT: slli a0, a0, 2
384+
; NOMUL-NEXT: sub sp, sp, a0
385+
; NOMUL-NEXT: li a0, 3
386+
; NOMUL-NEXT: sd a0, 8(sp)
387+
; NOMUL-NEXT: csrr a0, vlenb
388+
; NOMUL-NEXT: slli a0, a0, 2
389+
; NOMUL-NEXT: add sp, sp, a0
390+
; NOMUL-NEXT: addi sp, sp, 16
391+
; NOMUL-NEXT: ret
289392
%x1 = alloca i64
290393
%v1 = alloca <vscale x 1 x i64>
291394
%v2 = alloca <vscale x 2 x i64>
@@ -396,15 +499,34 @@ define void @lmul_1_2_4_8_x2_1() nounwind {
396499
}
397500

398501
define void @masks() nounwind {
399-
; CHECK-LABEL: masks:
400-
; CHECK: # %bb.0:
401-
; CHECK-NEXT: csrr a0, vlenb
402-
; CHECK-NEXT: slli a0, a0, 2
403-
; CHECK-NEXT: sub sp, sp, a0
404-
; CHECK-NEXT: csrr a0, vlenb
405-
; CHECK-NEXT: slli a0, a0, 2
406-
; CHECK-NEXT: add sp, sp, a0
407-
; CHECK-NEXT: ret
502+
; NOZBA-LABEL: masks:
503+
; NOZBA: # %bb.0:
504+
; NOZBA-NEXT: csrr a0, vlenb
505+
; NOZBA-NEXT: slli a0, a0, 2
506+
; NOZBA-NEXT: sub sp, sp, a0
507+
; NOZBA-NEXT: csrr a0, vlenb
508+
; NOZBA-NEXT: slli a0, a0, 2
509+
; NOZBA-NEXT: add sp, sp, a0
510+
; NOZBA-NEXT: ret
511+
;
512+
; ZBA-LABEL: masks:
513+
; ZBA: # %bb.0:
514+
; ZBA-NEXT: csrr a0, vlenb
515+
; ZBA-NEXT: slli a0, a0, 2
516+
; ZBA-NEXT: sub sp, sp, a0
517+
; ZBA-NEXT: csrr a0, vlenb
518+
; ZBA-NEXT: sh2add sp, a0, sp
519+
; ZBA-NEXT: ret
520+
;
521+
; NOMUL-LABEL: masks:
522+
; NOMUL: # %bb.0:
523+
; NOMUL-NEXT: csrr a0, vlenb
524+
; NOMUL-NEXT: slli a0, a0, 2
525+
; NOMUL-NEXT: sub sp, sp, a0
526+
; NOMUL-NEXT: csrr a0, vlenb
527+
; NOMUL-NEXT: slli a0, a0, 2
528+
; NOMUL-NEXT: add sp, sp, a0
529+
; NOMUL-NEXT: ret
408530
%v1 = alloca <vscale x 1 x i1>
409531
%v2 = alloca <vscale x 2 x i1>
410532
%v4 = alloca <vscale x 4 x i1>

0 commit comments

Comments
 (0)