xref: /llvm-project/llvm/test/CodeGen/Mips/dynamic-stack-realignment.ll (revision ae26f50aea4ef1a6c7058019f0db11a91bbcdade)
1; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic | FileCheck %s \
2; RUN:    --check-prefixes=ALL,GP32,GP32-M
3; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic | FileCheck %s \
4; RUN:    --check-prefixes=ALL,GP32,GP32-M
5; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic | FileCheck %s \
6; RUN:    --check-prefixes=ALL,GP32,GP32-M
7; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -mattr=+micromips -relocation-model=pic | FileCheck %s \
8; RUN:    --check-prefixes=ALL,GP32,GP32-MM,GP32-MMR2
9; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \
10; RUN:    --check-prefixes=ALL,GP32,GP32-MM,GP32-MMR6
11; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic | FileCheck %s \
12; RUN:    --check-prefixes=ALL,GP64,N64
13; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic | FileCheck %s \
14; RUN:    --check-prefixes=ALL,GP64,N64
15; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \
16; RUN:    --check-prefixes=ALL,GP64,N64
17; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -target-abi n32 -relocation-model=pic | FileCheck %s \
18; RUN:    --check-prefixes=ALL,GP64,N32
19; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -target-abi n32 -relocation-model=pic | FileCheck %s \
20; RUN:    --check-prefixes=ALL,GP64,N32
21; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -target-abi n32 -relocation-model=pic | FileCheck %s \
22; RUN:    --check-prefixes=ALL,GP64,N32
23
24; Check dynamic stack realignment in functions without variable-sized objects.
25
26declare void @helper_01(i32, i32, i32, i32, ptr)
27
28; O32 ABI
29define void @func_01() {
30entry:
31; GP32-LABEL: func_01:
32
33  ; prologue
34  ; FIXME: We are currently over-allocating stack space. This particular case
35  ;        needs a frame of up to between 16 and 512-bytes but currently
36  ;        allocates between 1024 and 1536 bytes
37  ; GP32-M:     addiu   $sp, $sp, -1024
38  ; GP32-MMR2:  addiusp -1024
39  ; GP32-MMR6:  addiu   $sp, $sp, -1024
40  ; GP32:       sw      $ra, 1020($sp)
41  ; GP32:       sw      $fp, 1016($sp)
42  ;
43  ; GP32:       move    $fp, $sp
44  ; GP32:       addiu   $[[T0:[0-9]+|ra|gp]], $zero, -512
45  ; GP32-NEXT:  and     $sp, $sp, $[[T0]]
46
47  ; body
48  ; GP32:       addiu   $[[T1:[0-9]+]], $sp, 512
49  ; GP32-M:     sw      $[[T1]], 16($sp)
50  ; GP32-MM:    sw16    $[[T1]], 16(${{[0-9]+}})
51
52  ; epilogue
53  ; GP32:       move    $sp, $fp
54  ; GP32:       lw      $fp, 1016($sp)
55  ; GP32:       lw      $ra, 1020($sp)
56  ; GP32-M:     addiu   $sp, $sp, 1024
57  ; GP32-MMR2:  addiusp 1024
58  ; GP32-MMR6:  addiu   $sp, $sp, 1024
59
60  %a = alloca i32, align 512
61  call void @helper_01(i32 0, i32 0, i32 0, i32 0, ptr %a)
62  ret void
63}
64
65declare void @helper_02(i32, i32, i32, i32,
66                        i32, i32, i32, i32, ptr)
67
68; N32/N64 ABIs
69define void @func_02() {
70entry:
71; GP64-LABEL: func_02:
72
73  ; prologue
74  ; FIXME: We are currently over-allocating stack space. This particular case
75  ;        needs a frame of up to between 16 and 512-bytes but currently
76  ;        allocates between 1024 and 1536 bytes
77  ; N32:        addiu   $sp, $sp, -1024
78  ; N64:        daddiu  $sp, $sp, -1024
79  ; GP64:       sd      $ra, 1016($sp)
80  ; GP64:       sd      $fp, 1008($sp)
81  ; N32:        sd      $gp, 1000($sp)
82  ;
83  ; GP64:       move    $fp, $sp
84  ; N32:        addiu   $[[T0:[0-9]+|ra]], $zero, -512
85  ; N64:        daddiu  $[[T0:[0-9]+|ra]], $zero, -512
86  ; GP64-NEXT:  and     $sp, $sp, $[[T0]]
87
88  ; body
89  ; N32:        addiu   $[[T1:[0-9]+]], $sp, 512
90  ; N64:        daddiu  $[[T1:[0-9]+]], $sp, 512
91  ; GP64:       sd      $[[T1]], 0($sp)
92
93  ; epilogue
94  ; GP64:       move    $sp, $fp
95  ; N32:        ld      $gp, 1000($sp)
96  ; GP64:       ld      $fp, 1008($sp)
97  ; GP64:       ld      $ra, 1016($sp)
98  ; N32:        addiu   $sp, $sp, 1024
99  ; N64:        daddiu  $sp, $sp, 1024
100
101  %a = alloca i32, align 512
102  call void @helper_02(i32 0, i32 0, i32 0, i32 0,
103                       i32 0, i32 0, i32 0, i32 0, ptr %a)
104  ret void
105}
106
107; Verify that we use $fp for referencing incoming arguments.
108
109declare void @helper_03(i32, i32, i32, i32, ptr, ptr)
110
111; O32 ABI
112define void @func_03(i32 %p0, i32 %p1, i32 %p2, i32 %p3, ptr %b) {
113entry:
114; GP32-LABEL: func_03:
115
116  ; body
117  ; FIXME: We are currently over-allocating stack space.
118  ; GP32-DAG:     addiu   $[[T0:[0-9]+]], $sp, 512
119  ; GP32-M-DAG:   sw      $[[T0]], 16($sp)
120  ; GP32-MM-DAG:  sw16    $[[T0]], 16(${{[0-9]+}})
121  ; GP32-DAG:     lw      $[[T1:[0-9]+]], 1040($fp)
122  ; GP32-M-DAG:   sw      $[[T1]], 20($sp)
123  ; GP32-MM-DAG:  sw16    $[[T1]], 20(${{[0-9]+}})
124
125  %a = alloca i32, align 512
126  call void @helper_03(i32 0, i32 0, i32 0, i32 0, ptr %a, ptr %b)
127  ret void
128}
129
130declare void @helper_04(i32, i32, i32, i32,
131                        i32, i32, i32, i32, ptr, ptr)
132
133; N32/N64 ABIs
134define void @func_04(i32 %p0, i32 %p1, i32 %p2, i32 %p3,
135                     i32 %p4, i32 %p5, i32 %p6, i32 %p7,
136                     ptr %b) {
137entry:
138; GP64-LABEL: func_04:
139
140  ; body
141  ; FIXME: We are currently over-allocating stack space.
142  ; N32-DAG:    addiu   $[[T0:[0-9]+]], $sp, 512
143  ; N64-DAG:    daddiu  $[[T0:[0-9]+]], $sp, 512
144  ; GP64-DAG:   sd      $[[T0]], 0($sp)
145  ; GP64-DAG:   ld      $[[T1:[0-9]+]], 1024($fp)
146  ; GP64-DAG:   sd      $[[T1]], 8($sp)
147
148  %a = alloca i32, align 512
149  call void @helper_04(i32 0, i32 0, i32 0, i32 0,
150                       i32 0, i32 0, i32 0, i32 0, ptr %a, ptr %b)
151  ret void
152}
153
154; Check dynamic stack realignment in functions with variable-sized objects.
155
156; O32 ABI
157define void @func_05(i32 %sz) {
158entry:
159; GP32-LABEL: func_05:
160
161  ; prologue
162  ; FIXME: We are currently over-allocating stack space.
163  ; GP32-M:     addiu   $sp, $sp, -1024
164  ; GP32-MMR2:  addiusp -1024
165  ; GP32-MMR6:  addiu   $sp, $sp, -1024
166  ; GP32:       sw      $ra, 1020($sp)
167  ; GP32:       sw      $fp, 1016($sp)
168  ; GP32:       sw      $23, 1012($sp)
169  ;
170  ; GP32:       move    $fp, $sp
171  ; GP32:       addiu   $[[T0:[0-9]+|gp]], $zero, -512
172  ; GP32-NEXT:  and     $sp, $sp, $[[T0]]
173  ; GP32-NEXT:  move    $23, $sp
174
175  ; body
176  ; GP32:       addiu   $[[T1:[0-9]+]], $zero, 222
177  ; GP32:       sw      $[[T1]], 508($23)
178
179  ; epilogue
180  ; GP32:       move    $sp, $fp
181  ; GP32:       lw      $23, 1012($sp)
182  ; GP32:       lw      $fp, 1016($sp)
183  ; GP32:       lw      $ra, 1020($sp)
184  ; GP32-M:     addiu   $sp, $sp, 1024
185  ; GP32-MMR2:  addiusp 1024
186  ; GP32-MMR6:  addiu   $sp, $sp, 1024
187
188  %a0 = alloca i32, i32 %sz, align 512
189  %a1 = alloca i32, align 4
190
191  store volatile i32 111, ptr %a0, align 512
192  store volatile i32 222, ptr %a1, align 4
193
194  ret void
195}
196
197; N32/N64 ABIs
198define void @func_06(i32 %sz) {
199entry:
200; GP64-LABEL: func_06:
201
202  ; prologue
203  ; FIXME: We are currently over-allocating stack space.
204  ; N32:        addiu   $sp, $sp, -1024
205  ; N64:        daddiu  $sp, $sp, -1024
206  ; GP64:       sd      $ra, 1016($sp)
207  ; GP64:       sd      $fp, 1008($sp)
208  ; GP64:       sd      $23, 1000($sp)
209  ;
210  ; GP64:       move    $fp, $sp
211  ; GP64:       addiu   $[[T0:[0-9]+|gp]], $zero, -512
212  ; GP64-NEXT:  and     $sp, $sp, $[[T0]]
213  ; GP64-NEXT:  move    $23, $sp
214
215  ; body
216  ; GP64:       addiu   $[[T1:[0-9]+]], $zero, 222
217  ; GP64:       sw      $[[T1]], 508($23)
218
219  ; epilogue
220  ; GP64:       move    $sp, $fp
221  ; GP64:       ld      $23, 1000($sp)
222  ; GP64:       ld      $fp, 1008($sp)
223  ; GP64:       ld      $ra, 1016($sp)
224  ; N32:        addiu   $sp, $sp, 1024
225  ; N64:        daddiu  $sp, $sp, 1024
226
227  %a0 = alloca i32, i32 %sz, align 512
228  %a1 = alloca i32, align 4
229
230  store volatile i32 111, ptr %a0, align 512
231  store volatile i32 222, ptr %a1, align 4
232
233  ret void
234}
235
236; Verify that we use $fp for referencing incoming arguments and $sp for
237; building outbound arguments for nested function calls.
238
239; O32 ABI
240define void @func_07(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %sz) {
241entry:
242; GP32-LABEL: func_07:
243
244  ; body
245  ; FIXME: We are currently over-allocating stack space.
246  ; GP32-DAG:       lw      $[[T0:[0-9]+]], 1040($fp)
247  ;
248  ; GP32-DAG:       addiu   $[[T1:[0-9]+]], $zero, 222
249  ; GP32-DAG:       sw      $[[T1]], 508($23)
250  ;
251  ; GP32-M-DAG:     sw      $[[T2:[0-9]+]], 16($sp)
252  ; GP32-MM-DAG:    sw16    $[[T2:[0-9]+]], 16($[[T3:[0-9]+]])
253
254  %a0 = alloca i32, i32 %sz, align 512
255  %a1 = alloca i32, align 4
256
257  store volatile i32 111, ptr %a0, align 512
258  store volatile i32 222, ptr %a1, align 4
259
260  call void @helper_01(i32 0, i32 0, i32 0, i32 0, ptr %a1)
261
262  ret void
263}
264
265; N32/N64 ABIs
266define void @func_08(i32 %p0, i32 %p1, i32 %p2, i32 %p3,
267                     i32 %p4, i32 %p5, i32 %p6, i32 %p7,
268                     i32 %sz) {
269entry:
270; GP64-LABEL: func_08:
271
272  ; body
273  ; FIXME: We are currently over-allocating stack space.
274  ; N32-DAG:        lw      $[[T0:[0-9]+]], 1028($fp)
275  ; N64-DAG:        lwu     $[[T0:[0-9]+]], 1028($fp)
276  ;
277  ; GP64-DAG:       addiu   $[[T1:[0-9]+]], $zero, 222
278  ; GP64-DAG:       sw      $[[T1]], 508($23)
279  ;
280  ; GP64-DAG:       sd      $[[T2:[0-9]+]], 0($sp)
281
282  %a0 = alloca i32, i32 %sz, align 512
283  %a1 = alloca i32, align 4
284
285  store volatile i32 111, ptr %a0, align 512
286  store volatile i32 222, ptr %a1, align 4
287
288  call void @helper_02(i32 0, i32 0, i32 0, i32 0,
289                       i32 0, i32 0, i32 0, i32 0, ptr %a1)
290  ret void
291}
292
293; Check that we do not perform dynamic stack realignment in the presence of
294; the "no-realign-stack" function attribute.
295define void @func_09() "no-realign-stack" {
296entry:
297; ALL-LABEL: func_09:
298
299  ; ALL-NOT:  and     $sp, $sp, $[[T0:[0-9]+|ra|gp]]
300
301  %a = alloca i32, align 512
302  call void @helper_01(i32 0, i32 0, i32 0, i32 0, ptr %a)
303  ret void
304}
305
306define void @func_10(i32 %sz) "no-realign-stack" {
307entry:
308; ALL-LABEL: func_10:
309
310  ; ALL-NOT:  and     $sp, $sp, $[[T0:[0-9]+|ra|gp]]
311
312  %a0 = alloca i32, i32 %sz, align 512
313  %a1 = alloca i32, align 4
314
315  store volatile i32 111, ptr %a0, align 512
316  store volatile i32 222, ptr %a1, align 4
317
318  ret void
319}
320