1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s
3
4target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5target triple = "wasm32-unknown-unknown"
6
7; Return multiple values, some of which will be legalized into multiple values.
8declare { i64, i128, i192, i128, i64 } @return_multi_multi()
9
10; Test returning a single value from @return_multi_multi.
11
12define i64 @test0() {
13; CHECK-LABEL: test0
14; CHECK: call    	return_multi_multi
15; CHECK: i64.load	$0=, 8($1)
16; CHECK: local.copy	$push8=, $0
17  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
18  %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0
19  ret i64 %t1
20}
21
22define i128 @test1() {
23; CHECK-LABEL: test1
24; CHECK: call    	return_multi_multi
25; CHECK: i64.load	$1=, 16($2)
26; CHECK: i32.const	$push0=, 24
27; CHECK: i32.add 	$push1=, $2, $pop0
28; CHECK: i64.load	$push2=, 0($pop1)
29; CHECK: i64.store	8($0), $pop2
30; CHECK: i64.store	0($0), $1
31  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
32  %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1
33  ret i128 %t1
34}
35
36define i192 @test2() {
37; CHECK-LABEL: test2
38; CHECK: call    	return_multi_multi
39; CHECK: i32.const	$push0=, 40
40; CHECK: i32.add 	$push1=, $3, $pop0
41; CHECK: i64.load	$1=, 0($pop1)
42; CHECK: i64.load	$2=, 32($3)
43; CHECK: i32.const	$push2=, 48
44; CHECK: i32.add 	$push3=, $3, $pop2
45; CHECK: i64.load	$push4=, 0($pop3)
46; CHECK: i64.store	16($0), $pop4
47; CHECK: i64.store	0($0), $2
48; CHECK: i64.store	8($0), $1
49  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
50  %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 2
51  ret i192 %t1
52}
53
54define i128 @test3() {
55; CHECK-LABEL: test3
56; CHECK: call    	return_multi_multi
57; CHECK: i64.load	$1=, 56($2)
58; CHECK: i32.const	$push0=, 64
59; CHECK: i32.add 	$push1=, $2, $pop0
60; CHECK: i64.load	$push2=, 0($pop1)
61; CHECK: i64.store	8($0), $pop2
62; CHECK: i64.store	0($0), $1
63  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
64  %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 3
65  ret i128 %t1
66}
67
68define i64 @test4() {
69; CHECK-LABEL: test4
70; CHECK: call    	return_multi_multi
71; CHECK: i64.load	$0=, 72($1)
72; CHECK: local.copy	$push8=, $0
73  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
74  %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 4
75  ret i64 %t1
76}
77
78; Test returning multiple values from @return_multi_multi.
79
80define { i64, i128 } @test5() {
81; CHECK-LABEL: test5
82; CHECK: call    	return_multi_multi
83; CHECK: i32.const	$push10=, 8
84; CHECK: i32.add 	$push11=, $3, $pop10
85; CHECK: i32.const	$push0=, 16
86; CHECK: i32.add 	$push1=, $pop11, $pop0
87; CHECK: i64.load	$1=, 0($pop1)
88; CHECK: i64.load	$2=, 8($3)
89; CHECK: i64.load	$push2=, 16($3)
90; CHECK: i64.store	8($0), $pop2
91; CHECK: i32.const	$push12=, 16
92; CHECK: i32.add 	$push3=, $0, $pop12
93; CHECK: i64.store	0($pop3), $1
94; CHECK: i64.store	0($0), $2
95  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
96  %r0 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0
97  %r1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1
98  %s0 = insertvalue { i64, i128 } undef, i64 %r0, 0
99  %s1 = insertvalue { i64, i128 } %s0, i128 %r1, 1
100  ret { i64, i128 } %s1
101}
102
103define { i128, i128 } @test6() {
104; CHECK-LABEL: test6
105; CHECK: call    	return_multi_multi
106; CHECK: i32.const	$push0=, 24
107; CHECK: i32.add 	$push1=, $4, $pop0
108; CHECK: i64.load	$1=, 0($pop1)
109; CHECK: i32.const	$push2=, 64
110; CHECK: i32.add 	$push3=, $4, $pop2
111; CHECK: i64.load	$2=, 0($pop3)
112; CHECK: i64.load	$3=, 16($4)
113; CHECK: i64.load	$push4=, 56($4)
114; CHECK: i64.store	16($0), $pop4
115; CHECK: i32.const	$push5=, 24
116; CHECK: i32.add 	$push6=, $0, $pop5
117; CHECK: i64.store	0($pop6), $2
118; CHECK: i64.store	0($0), $3
119; CHECK: i64.store	8($0), $1
120  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
121  %r1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1
122  %r3 = extractvalue { i64, i128, i192, i128, i64 } %t0, 3
123  %s0 = insertvalue { i128, i128 } undef, i128 %r1, 0
124  %s1 = insertvalue { i128, i128 } %s0, i128 %r3, 1
125  ret { i128, i128 } %s1
126}
127
128define { i64, i192 } @test7() {
129; CHECK-LABEL: test7
130; CHECK: call    	return_multi_multi
131; CHECK: i32.const	$push2=, 40
132; CHECK: i32.add 	$push3=, $4, $pop2
133; CHECK: i64.load	$1=, 0($pop3)
134; CHECK: i64.load	$2=, 8($4)
135; CHECK: i64.load	$3=, 32($4)
136; CHECK: i32.const	$push0=, 24
137; CHECK: i32.add 	$push1=, $0, $pop0
138; CHECK: i32.const	$push4=, 48
139; CHECK: i32.add 	$push5=, $4, $pop4
140; CHECK: i64.load	$push6=, 0($pop5)
141; CHECK: i64.store	0($pop1), $pop6
142; CHECK: i64.store	8($0), $3
143; CHECK: i32.const	$push7=, 16
144; CHECK: i32.add 	$push8=, $0, $pop7
145; CHECK: i64.store	0($pop8), $1
146; CHECK: i64.store	0($0), $2
147  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
148  %r0 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0
149  %r2 = extractvalue { i64, i128, i192, i128, i64 } %t0, 2
150  %s0 = insertvalue { i64, i192 } undef, i64 %r0, 0
151  %s1 = insertvalue { i64, i192 } %s0, i192 %r2, 1
152  ret { i64, i192 } %s1
153}
154
155define { i128, i192, i128, i64 } @test8() {
156; CHECK-LABEL: test8
157; CHECK: call    	return_multi_multi
158; CHECK: i32.const	$push0=, 64
159; CHECK: i32.add 	$push1=, $8, $pop0
160; CHECK: i64.load	$1=, 0($pop1)
161; CHECK: i32.const	$push20=, 8
162; CHECK: i32.add 	$push21=, $8, $pop20
163; CHECK: i32.const	$push2=, 32
164; CHECK: i32.add 	$push3=, $pop21, $pop2
165; CHECK: i64.load	$2=, 0($pop3)
166; CHECK: i32.const	$push4=, 48
167; CHECK: i32.add 	$push5=, $8, $pop4
168; CHECK: i64.load	$3=, 0($pop5)
169; CHECK: i32.const	$push6=, 24
170; CHECK: i32.add 	$push7=, $8, $pop6
171; CHECK: i64.load	$4=, 0($pop7)
172; CHECK: i64.load	$5=, 8($8)
173; CHECK: i64.load	$6=, 56($8)
174; CHECK: i64.load	$7=, 32($8)
175; CHECK: i64.load	$push8=, 16($8)
176; CHECK: i64.store	40($0), $pop8
177; CHECK: i32.const	$push9=, 48
178; CHECK: i32.add 	$push10=, $0, $pop9
179; CHECK: i64.store	0($pop10), $4
180; CHECK: i32.const	$push22=, 32
181; CHECK: i32.add 	$push11=, $0, $pop22
182; CHECK: i64.store	0($pop11), $3
183; CHECK: i64.store	16($0), $7
184; CHECK: i32.const	$push12=, 24
185; CHECK: i32.add 	$push13=, $0, $pop12
186; CHECK: i64.store	0($pop13), $2
187; CHECK: i64.store	0($0), $6
188; CHECK: i64.store	8($0), $1
189; CHECK: i64.store	56($0), $5
190  %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi()
191  %r0 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0
192  %r1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1
193  %r2 = extractvalue { i64, i128, i192, i128, i64 } %t0, 2
194  %r3 = extractvalue { i64, i128, i192, i128, i64 } %t0, 3
195  %s0 = insertvalue { i128, i192, i128, i64 } undef, i128 %r3, 0
196  %s1 = insertvalue { i128, i192, i128, i64 } %s0, i192 %r2, 1
197  %s2 = insertvalue { i128, i192, i128, i64 } %s1, i128 %r1, 2
198  %s3 = insertvalue { i128, i192, i128, i64 } %s2, i64 %r0, 3
199  ret { i128, i192, i128, i64 } %s3
200}
201