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