llvm.org GIT mirror llvm / d48ca22
Merging r368300: ------------------------------------------------------------------------ r368300 | lenary | 2019-08-08 16:40:54 +0200 (Thu, 08 Aug 2019) | 18 lines [RISCV] Minimal stack realignment support Summary: Currently the RISC-V backend does not realign the stack. This can be an issue even for the RV32I/RV64I ABIs (where the stack is 16-byte aligned), though is rare. It will be much more comment with RV32E (though the alignment requirements for common data types remain under-documented...). This patch adds minimal support for stack realignment. It should cope with large realignments. It will error out if the stack needs realignment and variable sized objects are present. It feels like a lot of the code like getFrameIndexReference and determineFrameLayout could be refactored somehow, as right now it feels fiddly and brittle. We also seem to allocate a lot more memory than GCC does for equivalent C code. Reviewers: asb Reviewed By: asb Subscribers: wwei, jrtc27, s.egerton, MaskRay, Jim, lenary, hiraditya, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, kito-cheng, shiva0217, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62007 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_90@368846 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 1 year, 3 months ago
3 changed file(s) with 686 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
3939 uint64_t FrameSize = MFI.getStackSize();
4040
4141 // Get the alignment.
42 uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment()
43 : getStackAlignment();
42 unsigned StackAlign = getStackAlignment();
43 if (RI->needsStackRealignment(MF)) {
44 unsigned MaxStackAlign = std::max(StackAlign, MFI.getMaxAlignment());
45 FrameSize += (MaxStackAlign - StackAlign);
46 StackAlign = MaxStackAlign;
47 }
48
49 // Set Max Call Frame Size
50 uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign);
51 MFI.setMaxCallFrameSize(MaxCallSize);
4452
4553 // Make sure the frame is aligned.
4654 FrameSize = alignTo(FrameSize, StackAlign);
100108 const RISCVInstrInfo *TII = STI.getInstrInfo();
101109 MachineBasicBlock::iterator MBBI = MBB.begin();
102110
111 if (RI->needsStackRealignment(MF) && MFI.hasVarSizedObjects()) {
112 report_fatal_error(
113 "RISC-V backend can't currently handle functions that need stack "
114 "realignment and have variable sized objects");
115 }
116
103117 unsigned FPReg = getFPReg(STI);
104118 unsigned SPReg = getSPReg(STI);
105119
157171 nullptr, RI->getDwarfRegNum(FPReg, true), 0));
158172 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
159173 .addCFIIndex(CFIIndex);
174
175 // Realign Stack
176 const RISCVRegisterInfo *RI = STI.getRegisterInfo();
177 if (RI->needsStackRealignment(MF)) {
178 unsigned MaxAlignment = MFI.getMaxAlignment();
179
180 const RISCVInstrInfo *TII = STI.getInstrInfo();
181 if (isInt<12>(-(int)MaxAlignment)) {
182 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg)
183 .addReg(SPReg)
184 .addImm(-(int)MaxAlignment);
185 } else {
186 unsigned ShiftAmount = countTrailingZeros(MaxAlignment);
187 unsigned VR =
188 MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
189 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR)
190 .addReg(SPReg)
191 .addImm(ShiftAmount);
192 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg)
193 .addReg(VR)
194 .addImm(ShiftAmount);
195 }
196 }
160197 }
161198 }
162199
256293 if (FI >= MinCSFI && FI <= MaxCSFI) {
257294 FrameReg = RISCV::X2;
258295 Offset += MF.getFrameInfo().getStackSize();
296 } else if (RI->needsStackRealignment(MF)) {
297 assert(!MFI.hasVarSizedObjects() &&
298 "Unexpected combination of stack realignment and varsized objects");
299 // If the stack was realigned, the frame pointer is set in order to allow
300 // SP to be restored, but we still access stack objects using SP.
301 FrameReg = RISCV::X2;
302 Offset += MF.getFrameInfo().getStackSize();
259303 } else {
260304 FrameReg = RI->getFrameRegister(MF);
261305 if (hasFP(MF))
0 ; RUN: not llc -mtriple=riscv32 < %s 2>&1 | FileCheck %s
1 ; RUN: not llc -mtriple=riscv64 < %s 2>&1 | FileCheck %s
2
3 ; CHECK: LLVM ERROR: RISC-V backend can't currently handle functions that need stack realignment and have variable sized objects
4
5 declare void @callee(i8*, i32*)
6
7 define void @caller(i32 %n) nounwind {
8 %1 = alloca i8, i32 %n
9 %2 = alloca i32, align 64
10 call void @callee(i8* %1, i32 *%2)
11 ret void
12 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
2 ; RUN: | FileCheck %s -check-prefix=RV32I
3 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
4 ; RUN: | FileCheck %s -check-prefix=RV64I
5
6 declare void @callee(i8*)
7
8 define void @caller32() nounwind {
9 ; RV32I-LABEL: caller32:
10 ; RV32I: # %bb.0:
11 ; RV32I-NEXT: addi sp, sp, -64
12 ; RV32I-NEXT: sw ra, 60(sp)
13 ; RV32I-NEXT: sw s0, 56(sp)
14 ; RV32I-NEXT: addi s0, sp, 64
15 ; RV32I-NEXT: andi sp, sp, -32
16 ; RV32I-NEXT: addi a0, sp, 32
17 ; RV32I-NEXT: call callee
18 ; RV32I-NEXT: addi sp, s0, -64
19 ; RV32I-NEXT: lw s0, 56(sp)
20 ; RV32I-NEXT: lw ra, 60(sp)
21 ; RV32I-NEXT: addi sp, sp, 64
22 ; RV32I-NEXT: ret
23 ;
24 ; RV64I-LABEL: caller32:
25 ; RV64I: # %bb.0:
26 ; RV64I-NEXT: addi sp, sp, -64
27 ; RV64I-NEXT: sd ra, 56(sp)
28 ; RV64I-NEXT: sd s0, 48(sp)
29 ; RV64I-NEXT: addi s0, sp, 64
30 ; RV64I-NEXT: andi sp, sp, -32
31 ; RV64I-NEXT: addi a0, sp, 32
32 ; RV64I-NEXT: call callee
33 ; RV64I-NEXT: addi sp, s0, -64
34 ; RV64I-NEXT: ld s0, 48(sp)
35 ; RV64I-NEXT: ld ra, 56(sp)
36 ; RV64I-NEXT: addi sp, sp, 64
37 ; RV64I-NEXT: ret
38 %1 = alloca i8, align 32
39 call void @callee(i8* %1)
40 ret void
41 }
42
43 define void @caller_no_realign32() nounwind "no-realign-stack" {
44 ; RV32I-LABEL: caller_no_realign32:
45 ; RV32I: # %bb.0:
46 ; RV32I-NEXT: addi sp, sp, -16
47 ; RV32I-NEXT: sw ra, 12(sp)
48 ; RV32I-NEXT: mv a0, sp
49 ; RV32I-NEXT: call callee
50 ; RV32I-NEXT: lw ra, 12(sp)
51 ; RV32I-NEXT: addi sp, sp, 16
52 ; RV32I-NEXT: ret
53 ;
54 ; RV64I-LABEL: caller_no_realign32:
55 ; RV64I: # %bb.0:
56 ; RV64I-NEXT: addi sp, sp, -16
57 ; RV64I-NEXT: sd ra, 8(sp)
58 ; RV64I-NEXT: mv a0, sp
59 ; RV64I-NEXT: call callee
60 ; RV64I-NEXT: ld ra, 8(sp)
61 ; RV64I-NEXT: addi sp, sp, 16
62 ; RV64I-NEXT: ret
63 %1 = alloca i8, align 32
64 call void @callee(i8* %1)
65 ret void
66 }
67
68 define void @caller64() nounwind {
69 ; RV32I-LABEL: caller64:
70 ; RV32I: # %bb.0:
71 ; RV32I-NEXT: addi sp, sp, -128
72 ; RV32I-NEXT: sw ra, 124(sp)
73 ; RV32I-NEXT: sw s0, 120(sp)
74 ; RV32I-NEXT: addi s0, sp, 128
75 ; RV32I-NEXT: andi sp, sp, -64
76 ; RV32I-NEXT: addi a0, sp, 64
77 ; RV32I-NEXT: call callee
78 ; RV32I-NEXT: addi sp, s0, -128
79 ; RV32I-NEXT: lw s0, 120(sp)
80 ; RV32I-NEXT: lw ra, 124(sp)
81 ; RV32I-NEXT: addi sp, sp, 128
82 ; RV32I-NEXT: ret
83 ;
84 ; RV64I-LABEL: caller64:
85 ; RV64I: # %bb.0:
86 ; RV64I-NEXT: addi sp, sp, -128
87 ; RV64I-NEXT: sd ra, 120(sp)
88 ; RV64I-NEXT: sd s0, 112(sp)
89 ; RV64I-NEXT: addi s0, sp, 128
90 ; RV64I-NEXT: andi sp, sp, -64
91 ; RV64I-NEXT: addi a0, sp, 64
92 ; RV64I-NEXT: call callee
93 ; RV64I-NEXT: addi sp, s0, -128
94 ; RV64I-NEXT: ld s0, 112(sp)
95 ; RV64I-NEXT: ld ra, 120(sp)
96 ; RV64I-NEXT: addi sp, sp, 128
97 ; RV64I-NEXT: ret
98 %1 = alloca i8, align 64
99 call void @callee(i8* %1)
100 ret void
101 }
102
103 define void @caller_no_realign64() nounwind "no-realign-stack" {
104 ; RV32I-LABEL: caller_no_realign64:
105 ; RV32I: # %bb.0:
106 ; RV32I-NEXT: addi sp, sp, -16
107 ; RV32I-NEXT: sw ra, 12(sp)
108 ; RV32I-NEXT: mv a0, sp
109 ; RV32I-NEXT: call callee
110 ; RV32I-NEXT: lw ra, 12(sp)
111 ; RV32I-NEXT: addi sp, sp, 16
112 ; RV32I-NEXT: ret
113 ;
114 ; RV64I-LABEL: caller_no_realign64:
115 ; RV64I: # %bb.0:
116 ; RV64I-NEXT: addi sp, sp, -16
117 ; RV64I-NEXT: sd ra, 8(sp)
118 ; RV64I-NEXT: mv a0, sp
119 ; RV64I-NEXT: call callee
120 ; RV64I-NEXT: ld ra, 8(sp)
121 ; RV64I-NEXT: addi sp, sp, 16
122 ; RV64I-NEXT: ret
123 %1 = alloca i8, align 64
124 call void @callee(i8* %1)
125 ret void
126 }
127
128 define void @caller128() nounwind {
129 ; RV32I-LABEL: caller128:
130 ; RV32I: # %bb.0:
131 ; RV32I-NEXT: addi sp, sp, -256
132 ; RV32I-NEXT: sw ra, 252(sp)
133 ; RV32I-NEXT: sw s0, 248(sp)
134 ; RV32I-NEXT: addi s0, sp, 256
135 ; RV32I-NEXT: andi sp, sp, -128
136 ; RV32I-NEXT: addi a0, sp, 128
137 ; RV32I-NEXT: call callee
138 ; RV32I-NEXT: addi sp, s0, -256
139 ; RV32I-NEXT: lw s0, 248(sp)
140 ; RV32I-NEXT: lw ra, 252(sp)
141 ; RV32I-NEXT: addi sp, sp, 256
142 ; RV32I-NEXT: ret
143 ;
144 ; RV64I-LABEL: caller128:
145 ; RV64I: # %bb.0:
146 ; RV64I-NEXT: addi sp, sp, -256
147 ; RV64I-NEXT: sd ra, 248(sp)
148 ; RV64I-NEXT: sd s0, 240(sp)
149 ; RV64I-NEXT: addi s0, sp, 256
150 ; RV64I-NEXT: andi sp, sp, -128
151 ; RV64I-NEXT: addi a0, sp, 128
152 ; RV64I-NEXT: call callee
153 ; RV64I-NEXT: addi sp, s0, -256
154 ; RV64I-NEXT: ld s0, 240(sp)
155 ; RV64I-NEXT: ld ra, 248(sp)
156 ; RV64I-NEXT: addi sp, sp, 256
157 ; RV64I-NEXT: ret
158 %1 = alloca i8, align 128
159 call void @callee(i8* %1)
160 ret void
161 }
162
163 define void @caller_no_realign128() nounwind "no-realign-stack" {
164 ; RV32I-LABEL: caller_no_realign128:
165 ; RV32I: # %bb.0:
166 ; RV32I-NEXT: addi sp, sp, -16
167 ; RV32I-NEXT: sw ra, 12(sp)
168 ; RV32I-NEXT: mv a0, sp
169 ; RV32I-NEXT: call callee
170 ; RV32I-NEXT: lw ra, 12(sp)
171 ; RV32I-NEXT: addi sp, sp, 16
172 ; RV32I-NEXT: ret
173 ;
174 ; RV64I-LABEL: caller_no_realign128:
175 ; RV64I: # %bb.0:
176 ; RV64I-NEXT: addi sp, sp, -16
177 ; RV64I-NEXT: sd ra, 8(sp)
178 ; RV64I-NEXT: mv a0, sp
179 ; RV64I-NEXT: call callee
180 ; RV64I-NEXT: ld ra, 8(sp)
181 ; RV64I-NEXT: addi sp, sp, 16
182 ; RV64I-NEXT: ret
183 %1 = alloca i8, align 128
184 call void @callee(i8* %1)
185 ret void
186 }
187
188 define void @caller256() nounwind {
189 ; RV32I-LABEL: caller256:
190 ; RV32I: # %bb.0:
191 ; RV32I-NEXT: addi sp, sp, -512
192 ; RV32I-NEXT: sw ra, 508(sp)
193 ; RV32I-NEXT: sw s0, 504(sp)
194 ; RV32I-NEXT: addi s0, sp, 512
195 ; RV32I-NEXT: andi sp, sp, -256
196 ; RV32I-NEXT: addi a0, sp, 256
197 ; RV32I-NEXT: call callee
198 ; RV32I-NEXT: addi sp, s0, -512
199 ; RV32I-NEXT: lw s0, 504(sp)
200 ; RV32I-NEXT: lw ra, 508(sp)
201 ; RV32I-NEXT: addi sp, sp, 512
202 ; RV32I-NEXT: ret
203 ;
204 ; RV64I-LABEL: caller256:
205 ; RV64I: # %bb.0:
206 ; RV64I-NEXT: addi sp, sp, -512
207 ; RV64I-NEXT: sd ra, 504(sp)
208 ; RV64I-NEXT: sd s0, 496(sp)
209 ; RV64I-NEXT: addi s0, sp, 512
210 ; RV64I-NEXT: andi sp, sp, -256
211 ; RV64I-NEXT: addi a0, sp, 256
212 ; RV64I-NEXT: call callee
213 ; RV64I-NEXT: addi sp, s0, -512
214 ; RV64I-NEXT: ld s0, 496(sp)
215 ; RV64I-NEXT: ld ra, 504(sp)
216 ; RV64I-NEXT: addi sp, sp, 512
217 ; RV64I-NEXT: ret
218 %1 = alloca i8, align 256
219 call void @callee(i8* %1)
220 ret void
221 }
222
223 define void @caller_no_realign256() nounwind "no-realign-stack" {
224 ; RV32I-LABEL: caller_no_realign256:
225 ; RV32I: # %bb.0:
226 ; RV32I-NEXT: addi sp, sp, -16
227 ; RV32I-NEXT: sw ra, 12(sp)
228 ; RV32I-NEXT: mv a0, sp
229 ; RV32I-NEXT: call callee
230 ; RV32I-NEXT: lw ra, 12(sp)
231 ; RV32I-NEXT: addi sp, sp, 16
232 ; RV32I-NEXT: ret
233 ;
234 ; RV64I-LABEL: caller_no_realign256:
235 ; RV64I: # %bb.0:
236 ; RV64I-NEXT: addi sp, sp, -16
237 ; RV64I-NEXT: sd ra, 8(sp)
238 ; RV64I-NEXT: mv a0, sp
239 ; RV64I-NEXT: call callee
240 ; RV64I-NEXT: ld ra, 8(sp)
241 ; RV64I-NEXT: addi sp, sp, 16
242 ; RV64I-NEXT: ret
243 %1 = alloca i8, align 256
244 call void @callee(i8* %1)
245 ret void
246 }
247
248 define void @caller512() nounwind {
249 ; RV32I-LABEL: caller512:
250 ; RV32I: # %bb.0:
251 ; RV32I-NEXT: addi sp, sp, -1536
252 ; RV32I-NEXT: sw ra, 1532(sp)
253 ; RV32I-NEXT: sw s0, 1528(sp)
254 ; RV32I-NEXT: addi s0, sp, 1536
255 ; RV32I-NEXT: andi sp, sp, -512
256 ; RV32I-NEXT: addi a0, sp, 1024
257 ; RV32I-NEXT: call callee
258 ; RV32I-NEXT: addi sp, s0, -1536
259 ; RV32I-NEXT: lw s0, 1528(sp)
260 ; RV32I-NEXT: lw ra, 1532(sp)
261 ; RV32I-NEXT: addi sp, sp, 1536
262 ; RV32I-NEXT: ret
263 ;
264 ; RV64I-LABEL: caller512:
265 ; RV64I: # %bb.0:
266 ; RV64I-NEXT: addi sp, sp, -1536
267 ; RV64I-NEXT: sd ra, 1528(sp)
268 ; RV64I-NEXT: sd s0, 1520(sp)
269 ; RV64I-NEXT: addi s0, sp, 1536
270 ; RV64I-NEXT: andi sp, sp, -512
271 ; RV64I-NEXT: addi a0, sp, 1024
272 ; RV64I-NEXT: call callee
273 ; RV64I-NEXT: addi sp, s0, -1536
274 ; RV64I-NEXT: ld s0, 1520(sp)
275 ; RV64I-NEXT: ld ra, 1528(sp)
276 ; RV64I-NEXT: addi sp, sp, 1536
277 ; RV64I-NEXT: ret
278 %1 = alloca i8, align 512
279 call void @callee(i8* %1)
280 ret void
281 }
282
283 define void @caller_no_realign512() nounwind "no-realign-stack" {
284 ; RV32I-LABEL: caller_no_realign512:
285 ; RV32I: # %bb.0:
286 ; RV32I-NEXT: addi sp, sp, -16
287 ; RV32I-NEXT: sw ra, 12(sp)
288 ; RV32I-NEXT: mv a0, sp
289 ; RV32I-NEXT: call callee
290 ; RV32I-NEXT: lw ra, 12(sp)
291 ; RV32I-NEXT: addi sp, sp, 16
292 ; RV32I-NEXT: ret
293 ;
294 ; RV64I-LABEL: caller_no_realign512:
295 ; RV64I: # %bb.0:
296 ; RV64I-NEXT: addi sp, sp, -16
297 ; RV64I-NEXT: sd ra, 8(sp)
298 ; RV64I-NEXT: mv a0, sp
299 ; RV64I-NEXT: call callee
300 ; RV64I-NEXT: ld ra, 8(sp)
301 ; RV64I-NEXT: addi sp, sp, 16
302 ; RV64I-NEXT: ret
303 %1 = alloca i8, align 512
304 call void @callee(i8* %1)
305 ret void
306 }
307
308 define void @caller1024() nounwind {
309 ; RV32I-LABEL: caller1024:
310 ; RV32I: # %bb.0:
311 ; RV32I-NEXT: lui a0, 1
312 ; RV32I-NEXT: addi a0, a0, -1024
313 ; RV32I-NEXT: sub sp, sp, a0
314 ; RV32I-NEXT: lui a0, 1
315 ; RV32I-NEXT: addi a0, a0, -1028
316 ; RV32I-NEXT: add a0, sp, a0
317 ; RV32I-NEXT: sw ra, 0(a0)
318 ; RV32I-NEXT: lui a0, 1
319 ; RV32I-NEXT: addi a0, a0, -1032
320 ; RV32I-NEXT: add a0, sp, a0
321 ; RV32I-NEXT: sw s0, 0(a0)
322 ; RV32I-NEXT: lui a0, 1
323 ; RV32I-NEXT: addi a0, a0, -1024
324 ; RV32I-NEXT: add s0, sp, a0
325 ; RV32I-NEXT: andi sp, sp, -1024
326 ; RV32I-NEXT: lui a0, 1
327 ; RV32I-NEXT: addi a0, a0, -2048
328 ; RV32I-NEXT: add a0, sp, a0
329 ; RV32I-NEXT: mv a0, a0
330 ; RV32I-NEXT: call callee
331 ; RV32I-NEXT: lui a0, 1
332 ; RV32I-NEXT: addi a0, a0, -1024
333 ; RV32I-NEXT: sub sp, s0, a0
334 ; RV32I-NEXT: lui a0, 1
335 ; RV32I-NEXT: addi a0, a0, -1032
336 ; RV32I-NEXT: add a0, sp, a0
337 ; RV32I-NEXT: lw s0, 0(a0)
338 ; RV32I-NEXT: lui a0, 1
339 ; RV32I-NEXT: addi a0, a0, -1028
340 ; RV32I-NEXT: add a0, sp, a0
341 ; RV32I-NEXT: lw ra, 0(a0)
342 ; RV32I-NEXT: lui a0, 1
343 ; RV32I-NEXT: addi a0, a0, -1024
344 ; RV32I-NEXT: add sp, sp, a0
345 ; RV32I-NEXT: ret
346 ;
347 ; RV64I-LABEL: caller1024:
348 ; RV64I: # %bb.0:
349 ; RV64I-NEXT: lui a0, 1
350 ; RV64I-NEXT: addi a0, a0, -1024
351 ; RV64I-NEXT: sub sp, sp, a0
352 ; RV64I-NEXT: lui a0, 1
353 ; RV64I-NEXT: addi a0, a0, -1032
354 ; RV64I-NEXT: add a0, sp, a0
355 ; RV64I-NEXT: sd ra, 0(a0)
356 ; RV64I-NEXT: lui a0, 1
357 ; RV64I-NEXT: addi a0, a0, -1040
358 ; RV64I-NEXT: add a0, sp, a0
359 ; RV64I-NEXT: sd s0, 0(a0)
360 ; RV64I-NEXT: lui a0, 1
361 ; RV64I-NEXT: addi a0, a0, -1024
362 ; RV64I-NEXT: add s0, sp, a0
363 ; RV64I-NEXT: andi sp, sp, -1024
364 ; RV64I-NEXT: lui a0, 1
365 ; RV64I-NEXT: addi a0, a0, -2048
366 ; RV64I-NEXT: add a0, sp, a0
367 ; RV64I-NEXT: mv a0, a0
368 ; RV64I-NEXT: call callee
369 ; RV64I-NEXT: lui a0, 1
370 ; RV64I-NEXT: addi a0, a0, -1024
371 ; RV64I-NEXT: sub sp, s0, a0
372 ; RV64I-NEXT: lui a0, 1
373 ; RV64I-NEXT: addi a0, a0, -1040
374 ; RV64I-NEXT: add a0, sp, a0
375 ; RV64I-NEXT: ld s0, 0(a0)
376 ; RV64I-NEXT: lui a0, 1
377 ; RV64I-NEXT: addi a0, a0, -1032
378 ; RV64I-NEXT: add a0, sp, a0
379 ; RV64I-NEXT: ld ra, 0(a0)
380 ; RV64I-NEXT: lui a0, 1
381 ; RV64I-NEXT: addi a0, a0, -1024
382 ; RV64I-NEXT: add sp, sp, a0
383 ; RV64I-NEXT: ret
384 %1 = alloca i8, align 1024
385 call void @callee(i8* %1)
386 ret void
387 }
388
389 define void @caller_no_realign1024() nounwind "no-realign-stack" {
390 ; RV32I-LABEL: caller_no_realign1024:
391 ; RV32I: # %bb.0:
392 ; RV32I-NEXT: addi sp, sp, -16
393 ; RV32I-NEXT: sw ra, 12(sp)
394 ; RV32I-NEXT: mv a0, sp
395 ; RV32I-NEXT: call callee
396 ; RV32I-NEXT: lw ra, 12(sp)
397 ; RV32I-NEXT: addi sp, sp, 16
398 ; RV32I-NEXT: ret
399 ;
400 ; RV64I-LABEL: caller_no_realign1024:
401 ; RV64I: # %bb.0:
402 ; RV64I-NEXT: addi sp, sp, -16
403 ; RV64I-NEXT: sd ra, 8(sp)
404 ; RV64I-NEXT: mv a0, sp
405 ; RV64I-NEXT: call callee
406 ; RV64I-NEXT: ld ra, 8(sp)
407 ; RV64I-NEXT: addi sp, sp, 16
408 ; RV64I-NEXT: ret
409 %1 = alloca i8, align 1024
410 call void @callee(i8* %1)
411 ret void
412 }
413
414 define void @caller2048() nounwind {
415 ; RV32I-LABEL: caller2048:
416 ; RV32I: # %bb.0:
417 ; RV32I-NEXT: lui a0, 2
418 ; RV32I-NEXT: addi a0, a0, -2048
419 ; RV32I-NEXT: sub sp, sp, a0
420 ; RV32I-NEXT: lui a0, 1
421 ; RV32I-NEXT: addi a0, a0, 2044
422 ; RV32I-NEXT: add a0, sp, a0
423 ; RV32I-NEXT: sw ra, 0(a0)
424 ; RV32I-NEXT: lui a0, 1
425 ; RV32I-NEXT: addi a0, a0, 2040
426 ; RV32I-NEXT: add a0, sp, a0
427 ; RV32I-NEXT: sw s0, 0(a0)
428 ; RV32I-NEXT: lui a0, 2
429 ; RV32I-NEXT: addi a0, a0, -2048
430 ; RV32I-NEXT: add s0, sp, a0
431 ; RV32I-NEXT: andi sp, sp, -2048
432 ; RV32I-NEXT: lui a0, 1
433 ; RV32I-NEXT: mv a0, a0
434 ; RV32I-NEXT: add a0, sp, a0
435 ; RV32I-NEXT: mv a0, a0
436 ; RV32I-NEXT: call callee
437 ; RV32I-NEXT: lui a0, 2
438 ; RV32I-NEXT: addi a0, a0, -2048
439 ; RV32I-NEXT: sub sp, s0, a0
440 ; RV32I-NEXT: lui a0, 1
441 ; RV32I-NEXT: addi a0, a0, 2040
442 ; RV32I-NEXT: add a0, sp, a0
443 ; RV32I-NEXT: lw s0, 0(a0)
444 ; RV32I-NEXT: lui a0, 1
445 ; RV32I-NEXT: addi a0, a0, 2044
446 ; RV32I-NEXT: add a0, sp, a0
447 ; RV32I-NEXT: lw ra, 0(a0)
448 ; RV32I-NEXT: lui a0, 2
449 ; RV32I-NEXT: addi a0, a0, -2048
450 ; RV32I-NEXT: add sp, sp, a0
451 ; RV32I-NEXT: ret
452 ;
453 ; RV64I-LABEL: caller2048:
454 ; RV64I: # %bb.0:
455 ; RV64I-NEXT: lui a0, 2
456 ; RV64I-NEXT: addi a0, a0, -2048
457 ; RV64I-NEXT: sub sp, sp, a0
458 ; RV64I-NEXT: lui a0, 1
459 ; RV64I-NEXT: addi a0, a0, 2040
460 ; RV64I-NEXT: add a0, sp, a0
461 ; RV64I-NEXT: sd ra, 0(a0)
462 ; RV64I-NEXT: lui a0, 1
463 ; RV64I-NEXT: addi a0, a0, 2032
464 ; RV64I-NEXT: add a0, sp, a0
465 ; RV64I-NEXT: sd s0, 0(a0)
466 ; RV64I-NEXT: lui a0, 2
467 ; RV64I-NEXT: addi a0, a0, -2048
468 ; RV64I-NEXT: add s0, sp, a0
469 ; RV64I-NEXT: andi sp, sp, -2048
470 ; RV64I-NEXT: lui a0, 1
471 ; RV64I-NEXT: mv a0, a0
472 ; RV64I-NEXT: add a0, sp, a0
473 ; RV64I-NEXT: mv a0, a0
474 ; RV64I-NEXT: call callee
475 ; RV64I-NEXT: lui a0, 2
476 ; RV64I-NEXT: addi a0, a0, -2048
477 ; RV64I-NEXT: sub sp, s0, a0
478 ; RV64I-NEXT: lui a0, 1
479 ; RV64I-NEXT: addi a0, a0, 2032
480 ; RV64I-NEXT: add a0, sp, a0
481 ; RV64I-NEXT: ld s0, 0(a0)
482 ; RV64I-NEXT: lui a0, 1
483 ; RV64I-NEXT: addi a0, a0, 2040
484 ; RV64I-NEXT: add a0, sp, a0
485 ; RV64I-NEXT: ld ra, 0(a0)
486 ; RV64I-NEXT: lui a0, 2
487 ; RV64I-NEXT: addi a0, a0, -2048
488 ; RV64I-NEXT: add sp, sp, a0
489 ; RV64I-NEXT: ret
490 %1 = alloca i8, align 2048
491 call void @callee(i8* %1)
492 ret void
493 }
494
495 define void @caller_no_realign2048() nounwind "no-realign-stack" {
496 ; RV32I-LABEL: caller_no_realign2048:
497 ; RV32I: # %bb.0:
498 ; RV32I-NEXT: addi sp, sp, -16
499 ; RV32I-NEXT: sw ra, 12(sp)
500 ; RV32I-NEXT: mv a0, sp
501 ; RV32I-NEXT: call callee
502 ; RV32I-NEXT: lw ra, 12(sp)
503 ; RV32I-NEXT: addi sp, sp, 16
504 ; RV32I-NEXT: ret
505 ;
506 ; RV64I-LABEL: caller_no_realign2048:
507 ; RV64I: # %bb.0:
508 ; RV64I-NEXT: addi sp, sp, -16
509 ; RV64I-NEXT: sd ra, 8(sp)
510 ; RV64I-NEXT: mv a0, sp
511 ; RV64I-NEXT: call callee
512 ; RV64I-NEXT: ld ra, 8(sp)
513 ; RV64I-NEXT: addi sp, sp, 16
514 ; RV64I-NEXT: ret
515 %1 = alloca i8, align 2048
516 call void @callee(i8* %1)
517 ret void
518 }
519
520 define void @caller4096() nounwind {
521 ; RV32I-LABEL: caller4096:
522 ; RV32I: # %bb.0:
523 ; RV32I-NEXT: lui a0, 3
524 ; RV32I-NEXT: mv a0, a0
525 ; RV32I-NEXT: sub sp, sp, a0
526 ; RV32I-NEXT: lui a0, 3
527 ; RV32I-NEXT: addi a0, a0, -4
528 ; RV32I-NEXT: add a0, sp, a0
529 ; RV32I-NEXT: sw ra, 0(a0)
530 ; RV32I-NEXT: lui a0, 3
531 ; RV32I-NEXT: addi a0, a0, -8
532 ; RV32I-NEXT: add a0, sp, a0
533 ; RV32I-NEXT: sw s0, 0(a0)
534 ; RV32I-NEXT: lui a0, 3
535 ; RV32I-NEXT: mv a0, a0
536 ; RV32I-NEXT: add s0, sp, a0
537 ; RV32I-NEXT: srli a0, sp, 12
538 ; RV32I-NEXT: slli sp, a0, 12
539 ; RV32I-NEXT: lui a0, 2
540 ; RV32I-NEXT: mv a0, a0
541 ; RV32I-NEXT: add a0, sp, a0
542 ; RV32I-NEXT: mv a0, a0
543 ; RV32I-NEXT: call callee
544 ; RV32I-NEXT: lui a0, 3
545 ; RV32I-NEXT: mv a0, a0
546 ; RV32I-NEXT: sub sp, s0, a0
547 ; RV32I-NEXT: lui a0, 3
548 ; RV32I-NEXT: addi a0, a0, -8
549 ; RV32I-NEXT: add a0, sp, a0
550 ; RV32I-NEXT: lw s0, 0(a0)
551 ; RV32I-NEXT: lui a0, 3
552 ; RV32I-NEXT: addi a0, a0, -4
553 ; RV32I-NEXT: add a0, sp, a0
554 ; RV32I-NEXT: lw ra, 0(a0)
555 ; RV32I-NEXT: lui a0, 3
556 ; RV32I-NEXT: mv a0, a0
557 ; RV32I-NEXT: add sp, sp, a0
558 ; RV32I-NEXT: ret
559 ;
560 ; RV64I-LABEL: caller4096:
561 ; RV64I: # %bb.0:
562 ; RV64I-NEXT: lui a0, 3
563 ; RV64I-NEXT: mv a0, a0
564 ; RV64I-NEXT: sub sp, sp, a0
565 ; RV64I-NEXT: lui a0, 3
566 ; RV64I-NEXT: addi a0, a0, -8
567 ; RV64I-NEXT: add a0, sp, a0
568 ; RV64I-NEXT: sd ra, 0(a0)
569 ; RV64I-NEXT: lui a0, 3
570 ; RV64I-NEXT: addi a0, a0, -16
571 ; RV64I-NEXT: add a0, sp, a0
572 ; RV64I-NEXT: sd s0, 0(a0)
573 ; RV64I-NEXT: lui a0, 3
574 ; RV64I-NEXT: mv a0, a0
575 ; RV64I-NEXT: add s0, sp, a0
576 ; RV64I-NEXT: srli a0, sp, 12
577 ; RV64I-NEXT: slli sp, a0, 12
578 ; RV64I-NEXT: lui a0, 2
579 ; RV64I-NEXT: mv a0, a0
580 ; RV64I-NEXT: add a0, sp, a0
581 ; RV64I-NEXT: mv a0, a0
582 ; RV64I-NEXT: call callee
583 ; RV64I-NEXT: lui a0, 3
584 ; RV64I-NEXT: mv a0, a0
585 ; RV64I-NEXT: sub sp, s0, a0
586 ; RV64I-NEXT: lui a0, 3
587 ; RV64I-NEXT: addi a0, a0, -16
588 ; RV64I-NEXT: add a0, sp, a0
589 ; RV64I-NEXT: ld s0, 0(a0)
590 ; RV64I-NEXT: lui a0, 3
591 ; RV64I-NEXT: addi a0, a0, -8
592 ; RV64I-NEXT: add a0, sp, a0
593 ; RV64I-NEXT: ld ra, 0(a0)
594 ; RV64I-NEXT: lui a0, 3
595 ; RV64I-NEXT: mv a0, a0
596 ; RV64I-NEXT: add sp, sp, a0
597 ; RV64I-NEXT: ret
598 %1 = alloca i8, align 4096
599 call void @callee(i8* %1)
600 ret void
601 }
602
603 define void @caller_no_realign4096() nounwind "no-realign-stack" {
604 ; RV32I-LABEL: caller_no_realign4096:
605 ; RV32I: # %bb.0:
606 ; RV32I-NEXT: addi sp, sp, -16
607 ; RV32I-NEXT: sw ra, 12(sp)
608 ; RV32I-NEXT: mv a0, sp
609 ; RV32I-NEXT: call callee
610 ; RV32I-NEXT: lw ra, 12(sp)
611 ; RV32I-NEXT: addi sp, sp, 16
612 ; RV32I-NEXT: ret
613 ;
614 ; RV64I-LABEL: caller_no_realign4096:
615 ; RV64I: # %bb.0:
616 ; RV64I-NEXT: addi sp, sp, -16
617 ; RV64I-NEXT: sd ra, 8(sp)
618 ; RV64I-NEXT: mv a0, sp
619 ; RV64I-NEXT: call callee
620 ; RV64I-NEXT: ld ra, 8(sp)
621 ; RV64I-NEXT: addi sp, sp, 16
622 ; RV64I-NEXT: ret
623 %1 = alloca i8, align 4096
624 call void @callee(i8* %1)
625 ret void
626 }