Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / SPARC / bigreturn.ll
blob9dd7fad78567d11f9802201d2a749cde5532f6d2
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=sparc -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck --check-prefix=SPARC %s
3 ; RUN: llc < %s -mtriple=sparc64 -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck --check-prefix=SPARC64 %s
5 ;; Structs up to six registers in size can be returned in registers.
6 ;; Note that the maximum return size and member placement is NOT
7 ;; compatible with the C ABI - see SparcCallingConv.td.
8 define { i32, i32 } @ret_i32_pair(i32 %a0, i32 %a1, i32* %p, i32* %q) {
9 ; SPARC-LABEL: ret_i32_pair:
10 ; SPARC:         .cfi_startproc
11 ; SPARC-NEXT:  ! %bb.0:
12 ; SPARC-NEXT:    save %sp, -96, %sp
13 ; SPARC-NEXT:    .cfi_def_cfa_register %fp
14 ; SPARC-NEXT:    .cfi_window_save
15 ; SPARC-NEXT:    .cfi_register %o7, %i7
16 ; SPARC-NEXT:    ld [%i2], %i0
17 ; SPARC-NEXT:    st %g0, [%i2]
18 ; SPARC-NEXT:    ld [%i3], %i1
19 ; SPARC-NEXT:    restore
20 ; SPARC-NEXT:    retl
21 ; SPARC-NEXT:    nop
23 ; SPARC64-LABEL: ret_i32_pair:
24 ; SPARC64:         .cfi_startproc
25 ; SPARC64-NEXT:  ! %bb.0:
26 ; SPARC64-NEXT:    save %sp, -128, %sp
27 ; SPARC64-NEXT:    .cfi_def_cfa_register %fp
28 ; SPARC64-NEXT:    .cfi_window_save
29 ; SPARC64-NEXT:    .cfi_register %o7, %i7
30 ; SPARC64-NEXT:    ld [%i2], %i0
31 ; SPARC64-NEXT:    st %g0, [%i2]
32 ; SPARC64-NEXT:    ld [%i3], %i1
33 ; SPARC64-NEXT:    restore
34 ; SPARC64-NEXT:    retl
35 ; SPARC64-NEXT:    nop
36   %r1 = load i32, i32* %p
37   %rv1 = insertvalue { i32, i32 } undef, i32 %r1, 0
38   store i32 0, i32* %p
39   %r2 = load i32, i32* %q
40   %rv2 = insertvalue { i32, i32 } %rv1, i32 %r2, 1
41   ret { i32, i32 } %rv2
44 define void @call_ret_i32_pair(i32* %i0) {
45 ; SPARC-LABEL: call_ret_i32_pair:
46 ; SPARC:         .cfi_startproc
47 ; SPARC-NEXT:  ! %bb.0:
48 ; SPARC-NEXT:    save %sp, -96, %sp
49 ; SPARC-NEXT:    .cfi_def_cfa_register %fp
50 ; SPARC-NEXT:    .cfi_window_save
51 ; SPARC-NEXT:    .cfi_register %o7, %i7
52 ; SPARC-NEXT:    call ret_i32_pair
53 ; SPARC-NEXT:    nop
54 ; SPARC-NEXT:    st %o0, [%i0]
55 ; SPARC-NEXT:    st %o1, [%i0]
56 ; SPARC-NEXT:    restore
57 ; SPARC-NEXT:    retl
58 ; SPARC-NEXT:    nop
60 ; SPARC64-LABEL: call_ret_i32_pair:
61 ; SPARC64:         .cfi_startproc
62 ; SPARC64-NEXT:  ! %bb.0:
63 ; SPARC64-NEXT:    save %sp, -176, %sp
64 ; SPARC64-NEXT:    .cfi_def_cfa_register %fp
65 ; SPARC64-NEXT:    .cfi_window_save
66 ; SPARC64-NEXT:    .cfi_register %o7, %i7
67 ; SPARC64-NEXT:    call ret_i32_pair
68 ; SPARC64-NEXT:    nop
69 ; SPARC64-NEXT:    st %o0, [%i0]
70 ; SPARC64-NEXT:    st %o1, [%i0]
71 ; SPARC64-NEXT:    restore
72 ; SPARC64-NEXT:    retl
73 ; SPARC64-NEXT:    nop
74   %rv = call { i32, i32 } @ret_i32_pair(i32 undef, i32 undef,
75                                         i32* undef, i32* undef)
76   %e0 = extractvalue { i32, i32 } %rv, 0
77   store volatile i32 %e0, i32* %i0
78   %e1 = extractvalue { i32, i32 } %rv, 1
79   store i32 %e1, i32* %i0
80   ret void
83 ;; Functions returning structs more than six registers' worth of space
84 ;; should be automatically treated as an sret function.
85 declare { [16 x i32] } @ret_i32_arr(i32 %input)
87 define i32 @call_ret_i32_arr(i32 %0) {
88 ; SPARC-LABEL: call_ret_i32_arr:
89 ; SPARC:         .cfi_startproc
90 ; SPARC-NEXT:  ! %bb.0:
91 ; SPARC-NEXT:    save %sp, -160, %sp
92 ; SPARC-NEXT:    .cfi_def_cfa_register %fp
93 ; SPARC-NEXT:    .cfi_window_save
94 ; SPARC-NEXT:    .cfi_register %o7, %i7
95 ; SPARC-NEXT:    add %fp, -64, %i1
96 ; SPARC-NEXT:    st %i1, [%sp+64]
97 ; SPARC-NEXT:    mov %i0, %o0
98 ; SPARC-NEXT:    call ret_i32_arr
99 ; SPARC-NEXT:    nop
100 ; SPARC-NEXT:    unimp 64
101 ; SPARC-NEXT:    ld [%fp+-4], %i0
102 ; SPARC-NEXT:    restore
103 ; SPARC-NEXT:    retl
104 ; SPARC-NEXT:    nop
106 ; SPARC64-LABEL: call_ret_i32_arr:
107 ; SPARC64:         .cfi_startproc
108 ; SPARC64-NEXT:  ! %bb.0:
109 ; SPARC64-NEXT:    save %sp, -240, %sp
110 ; SPARC64-NEXT:    .cfi_def_cfa_register %fp
111 ; SPARC64-NEXT:    .cfi_window_save
112 ; SPARC64-NEXT:    .cfi_register %o7, %i7
113 ; SPARC64-NEXT:    add %fp, 1983, %o0
114 ; SPARC64-NEXT:    mov %i0, %o1
115 ; SPARC64-NEXT:    call ret_i32_arr
116 ; SPARC64-NEXT:    nop
117 ; SPARC64-NEXT:    ld [%fp+2043], %i0
118 ; SPARC64-NEXT:    restore
119 ; SPARC64-NEXT:    retl
120 ; SPARC64-NEXT:    nop
121   %2 = call { [16 x i32] } @ret_i32_arr(i32 %0)
122   %3 = extractvalue { [16 x i32] } %2, 0
123   %4 = extractvalue [16 x i32] %3, 15
124   ret i32 %4
127 ;; Structs up to six registers in size can be returned in registers.
128 ;; Note that the maximum return size and member placement is NOT
129 ;; compatible with the C ABI - see SparcCallingConv.td.
130 define { i64, i64 } @ret_i64_pair(i32 %a0, i32 %a1, i64* %p, i64* %q) {
131 ; SPARC-LABEL: ret_i64_pair:
132 ; SPARC:         .cfi_startproc
133 ; SPARC-NEXT:  ! %bb.0:
134 ; SPARC-NEXT:    save %sp, -96, %sp
135 ; SPARC-NEXT:    .cfi_def_cfa_register %fp
136 ; SPARC-NEXT:    .cfi_window_save
137 ; SPARC-NEXT:    .cfi_register %o7, %i7
138 ; SPARC-NEXT:    mov %g0, %i4
139 ; SPARC-NEXT:    ldd [%i2], %i0
140 ; SPARC-NEXT:    mov %g0, %i5
141 ; SPARC-NEXT:    std %i4, [%i2]
142 ; SPARC-NEXT:    ldd [%i3], %i2
143 ; SPARC-NEXT:    restore
144 ; SPARC-NEXT:    retl
145 ; SPARC-NEXT:    nop
147 ; SPARC64-LABEL: ret_i64_pair:
148 ; SPARC64:         .cfi_startproc
149 ; SPARC64-NEXT:  ! %bb.0:
150 ; SPARC64-NEXT:    save %sp, -128, %sp
151 ; SPARC64-NEXT:    .cfi_def_cfa_register %fp
152 ; SPARC64-NEXT:    .cfi_window_save
153 ; SPARC64-NEXT:    .cfi_register %o7, %i7
154 ; SPARC64-NEXT:    ldx [%i2], %i0
155 ; SPARC64-NEXT:    stx %g0, [%i2]
156 ; SPARC64-NEXT:    ldx [%i3], %i1
157 ; SPARC64-NEXT:    restore
158 ; SPARC64-NEXT:    retl
159 ; SPARC64-NEXT:    nop
160   %r1 = load i64, i64* %p
161   %rv1 = insertvalue { i64, i64 } undef, i64 %r1, 0
162   store i64 0, i64* %p
163   %r2 = load i64, i64* %q
164   %rv2 = insertvalue { i64, i64 } %rv1, i64 %r2, 1
165   ret { i64, i64 } %rv2
168 define void @call_ret_i64_pair(i64* %i0) {
169 ; SPARC-LABEL: call_ret_i64_pair:
170 ; SPARC:         .cfi_startproc
171 ; SPARC-NEXT:  ! %bb.0:
172 ; SPARC-NEXT:    save %sp, -96, %sp
173 ; SPARC-NEXT:    .cfi_def_cfa_register %fp
174 ; SPARC-NEXT:    .cfi_window_save
175 ; SPARC-NEXT:    .cfi_register %o7, %i7
176 ; SPARC-NEXT:    call ret_i64_pair
177 ; SPARC-NEXT:    nop
178 ; SPARC-NEXT:    ! kill: def $o0 killed $o0 killed $o0_o1 def $o0_o1
179 ; SPARC-NEXT:    ! kill: def $o2 killed $o2 killed $o2_o3 def $o2_o3
180 ; SPARC-NEXT:    ! kill: def $o1 killed $o1 killed $o0_o1 def $o0_o1
181 ; SPARC-NEXT:    std %o0, [%i0]
182 ; SPARC-NEXT:    ! kill: def $o3 killed $o3 killed $o2_o3 def $o2_o3
183 ; SPARC-NEXT:    std %o2, [%i0]
184 ; SPARC-NEXT:    restore
185 ; SPARC-NEXT:    retl
186 ; SPARC-NEXT:    nop
188 ; SPARC64-LABEL: call_ret_i64_pair:
189 ; SPARC64:         .cfi_startproc
190 ; SPARC64-NEXT:  ! %bb.0:
191 ; SPARC64-NEXT:    save %sp, -176, %sp
192 ; SPARC64-NEXT:    .cfi_def_cfa_register %fp
193 ; SPARC64-NEXT:    .cfi_window_save
194 ; SPARC64-NEXT:    .cfi_register %o7, %i7
195 ; SPARC64-NEXT:    call ret_i64_pair
196 ; SPARC64-NEXT:    nop
197 ; SPARC64-NEXT:    stx %o0, [%i0]
198 ; SPARC64-NEXT:    stx %o1, [%i0]
199 ; SPARC64-NEXT:    restore
200 ; SPARC64-NEXT:    retl
201 ; SPARC64-NEXT:    nop
202   %rv = call { i64, i64 } @ret_i64_pair(i32 undef, i32 undef,
203                                         i64* undef, i64* undef)
204   %e0 = extractvalue { i64, i64 } %rv, 0
205   store volatile i64 %e0, i64* %i0
206   %e1 = extractvalue { i64, i64 } %rv, 1
207   store i64 %e1, i64* %i0
208   ret void
211 ;; Functions returning structs more than six registers' worth of space
212 ;; should be automatically treated as an sret function.
213 declare { [16 x i64] } @ret_i64_arr(i64 %input)
215 define i64 @call_ret_i64_arr(i64 %0) {
216 ; SPARC-LABEL: call_ret_i64_arr:
217 ; SPARC:         .cfi_startproc
218 ; SPARC-NEXT:  ! %bb.0:
219 ; SPARC-NEXT:    save %sp, -224, %sp
220 ; SPARC-NEXT:    .cfi_def_cfa_register %fp
221 ; SPARC-NEXT:    .cfi_window_save
222 ; SPARC-NEXT:    .cfi_register %o7, %i7
223 ; SPARC-NEXT:    add %fp, -128, %i2
224 ; SPARC-NEXT:    st %i2, [%sp+64]
225 ; SPARC-NEXT:    mov %i0, %o0
226 ; SPARC-NEXT:    mov %i1, %o1
227 ; SPARC-NEXT:    call ret_i64_arr
228 ; SPARC-NEXT:    nop
229 ; SPARC-NEXT:    unimp 128
230 ; SPARC-NEXT:    ldd [%fp+-8], %i0
231 ; SPARC-NEXT:    restore
232 ; SPARC-NEXT:    retl
233 ; SPARC-NEXT:    nop
235 ; SPARC64-LABEL: call_ret_i64_arr:
236 ; SPARC64:         .cfi_startproc
237 ; SPARC64-NEXT:  ! %bb.0:
238 ; SPARC64-NEXT:    save %sp, -304, %sp
239 ; SPARC64-NEXT:    .cfi_def_cfa_register %fp
240 ; SPARC64-NEXT:    .cfi_window_save
241 ; SPARC64-NEXT:    .cfi_register %o7, %i7
242 ; SPARC64-NEXT:    add %fp, 1919, %o0
243 ; SPARC64-NEXT:    mov %i0, %o1
244 ; SPARC64-NEXT:    call ret_i64_arr
245 ; SPARC64-NEXT:    nop
246 ; SPARC64-NEXT:    ldx [%fp+2039], %i0
247 ; SPARC64-NEXT:    restore
248 ; SPARC64-NEXT:    retl
249 ; SPARC64-NEXT:    nop
250   %2 = call { [16 x i64] } @ret_i64_arr(i64 %0)
251   %3 = extractvalue { [16 x i64] } %2, 0
252   %4 = extractvalue [16 x i64] %3, 15
253   ret i64 %4