blob: 77f8f300956af0821fd57f54b618bda37702c78e [file] [log] [blame]
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +00003; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
4; RUN: llc -mtriple=riscv32 -verify-machineinstrs -disable-fp-elim < %s \
5; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
Alex Bradburyc85be0d2018-01-10 19:41:03 +00006
7declare void @llvm.va_start(i8*)
8declare void @llvm.va_end(i8*)
9
10declare void @notdead(i8*)
11
12; Although frontends are recommended to not generate va_arg due to the lack of
13; support for aggregate types, we test simple cases here to ensure they are
14; lowered correctly
15
16define i32 @va1(i8* %fmt, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000017; RV32I-FPELIM-LABEL: va1:
18; RV32I-FPELIM: # %bb.0:
19; RV32I-FPELIM-NEXT: addi sp, sp, -48
Alex Bradbury686ef922018-10-11 11:11:58 +000020; RV32I-FPELIM-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000021; RV32I-FPELIM-NEXT: sw a7, 44(sp)
22; RV32I-FPELIM-NEXT: sw a6, 40(sp)
23; RV32I-FPELIM-NEXT: sw a5, 36(sp)
24; RV32I-FPELIM-NEXT: sw a4, 32(sp)
25; RV32I-FPELIM-NEXT: sw a3, 28(sp)
26; RV32I-FPELIM-NEXT: sw a2, 24(sp)
Alex Bradbury686ef922018-10-11 11:11:58 +000027; RV32I-FPELIM-NEXT: addi a1, sp, 24
28; RV32I-FPELIM-NEXT: sw a1, 12(sp)
29; RV32I-FPELIM-NEXT: sw a0, 20(sp)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000030; RV32I-FPELIM-NEXT: addi sp, sp, 48
31; RV32I-FPELIM-NEXT: ret
32;
33; RV32I-WITHFP-LABEL: va1:
34; RV32I-WITHFP: # %bb.0:
35; RV32I-WITHFP-NEXT: addi sp, sp, -48
36; RV32I-WITHFP-NEXT: sw ra, 12(sp)
37; RV32I-WITHFP-NEXT: sw s0, 8(sp)
38; RV32I-WITHFP-NEXT: addi s0, sp, 16
Alex Bradbury686ef922018-10-11 11:11:58 +000039; RV32I-WITHFP-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000040; RV32I-WITHFP-NEXT: sw a7, 28(s0)
41; RV32I-WITHFP-NEXT: sw a6, 24(s0)
42; RV32I-WITHFP-NEXT: sw a5, 20(s0)
43; RV32I-WITHFP-NEXT: sw a4, 16(s0)
44; RV32I-WITHFP-NEXT: sw a3, 12(s0)
45; RV32I-WITHFP-NEXT: sw a2, 8(s0)
Alex Bradbury686ef922018-10-11 11:11:58 +000046; RV32I-WITHFP-NEXT: addi a1, s0, 8
47; RV32I-WITHFP-NEXT: sw a1, -12(s0)
48; RV32I-WITHFP-NEXT: sw a0, 4(s0)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000049; RV32I-WITHFP-NEXT: lw s0, 8(sp)
50; RV32I-WITHFP-NEXT: lw ra, 12(sp)
51; RV32I-WITHFP-NEXT: addi sp, sp, 48
52; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +000053 %va = alloca i8*, align 4
54 %1 = bitcast i8** %va to i8*
55 call void @llvm.va_start(i8* %1)
56 %argp.cur = load i8*, i8** %va, align 4
57 %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
58 store i8* %argp.next, i8** %va, align 4
59 %2 = bitcast i8* %argp.cur to i32*
60 %3 = load i32, i32* %2, align 4
61 call void @llvm.va_end(i8* %1)
62 ret i32 %3
63}
64
65define i32 @va1_va_arg(i8* %fmt, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000066; RV32I-FPELIM-LABEL: va1_va_arg:
67; RV32I-FPELIM: # %bb.0:
68; RV32I-FPELIM-NEXT: addi sp, sp, -48
Alex Bradbury686ef922018-10-11 11:11:58 +000069; RV32I-FPELIM-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000070; RV32I-FPELIM-NEXT: sw a7, 44(sp)
71; RV32I-FPELIM-NEXT: sw a6, 40(sp)
72; RV32I-FPELIM-NEXT: sw a5, 36(sp)
73; RV32I-FPELIM-NEXT: sw a4, 32(sp)
74; RV32I-FPELIM-NEXT: sw a3, 28(sp)
75; RV32I-FPELIM-NEXT: sw a2, 24(sp)
Alex Bradbury686ef922018-10-11 11:11:58 +000076; RV32I-FPELIM-NEXT: addi a1, sp, 24
77; RV32I-FPELIM-NEXT: sw a1, 12(sp)
78; RV32I-FPELIM-NEXT: sw a0, 20(sp)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000079; RV32I-FPELIM-NEXT: addi sp, sp, 48
80; RV32I-FPELIM-NEXT: ret
81;
82; RV32I-WITHFP-LABEL: va1_va_arg:
83; RV32I-WITHFP: # %bb.0:
84; RV32I-WITHFP-NEXT: addi sp, sp, -48
85; RV32I-WITHFP-NEXT: sw ra, 12(sp)
86; RV32I-WITHFP-NEXT: sw s0, 8(sp)
87; RV32I-WITHFP-NEXT: addi s0, sp, 16
Alex Bradbury686ef922018-10-11 11:11:58 +000088; RV32I-WITHFP-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000089; RV32I-WITHFP-NEXT: sw a7, 28(s0)
90; RV32I-WITHFP-NEXT: sw a6, 24(s0)
91; RV32I-WITHFP-NEXT: sw a5, 20(s0)
92; RV32I-WITHFP-NEXT: sw a4, 16(s0)
93; RV32I-WITHFP-NEXT: sw a3, 12(s0)
94; RV32I-WITHFP-NEXT: sw a2, 8(s0)
Alex Bradbury686ef922018-10-11 11:11:58 +000095; RV32I-WITHFP-NEXT: addi a1, s0, 8
96; RV32I-WITHFP-NEXT: sw a1, -12(s0)
97; RV32I-WITHFP-NEXT: sw a0, 4(s0)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +000098; RV32I-WITHFP-NEXT: lw s0, 8(sp)
99; RV32I-WITHFP-NEXT: lw ra, 12(sp)
100; RV32I-WITHFP-NEXT: addi sp, sp, 48
101; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000102 %va = alloca i8*, align 4
103 %1 = bitcast i8** %va to i8*
104 call void @llvm.va_start(i8* %1)
105 %2 = va_arg i8** %va, i32
106 call void @llvm.va_end(i8* %1)
107 ret i32 %2
108}
109
110; Ensure the adjustment when restoring the stack pointer using the frame
111; pointer is correct
112define i32 @va1_va_arg_alloca(i8* %fmt, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000113; RV32I-FPELIM-LABEL: va1_va_arg_alloca:
114; RV32I-FPELIM: # %bb.0:
115; RV32I-FPELIM-NEXT: addi sp, sp, -48
116; RV32I-FPELIM-NEXT: sw ra, 12(sp)
117; RV32I-FPELIM-NEXT: sw s0, 8(sp)
118; RV32I-FPELIM-NEXT: sw s1, 4(sp)
119; RV32I-FPELIM-NEXT: addi s0, sp, 16
Alex Bradbury686ef922018-10-11 11:11:58 +0000120; RV32I-FPELIM-NEXT: mv s1, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000121; RV32I-FPELIM-NEXT: sw a7, 28(s0)
122; RV32I-FPELIM-NEXT: sw a6, 24(s0)
123; RV32I-FPELIM-NEXT: sw a5, 20(s0)
124; RV32I-FPELIM-NEXT: sw a4, 16(s0)
125; RV32I-FPELIM-NEXT: sw a3, 12(s0)
126; RV32I-FPELIM-NEXT: sw a2, 8(s0)
127; RV32I-FPELIM-NEXT: addi a0, s0, 8
128; RV32I-FPELIM-NEXT: sw a0, -16(s0)
Alex Bradbury686ef922018-10-11 11:11:58 +0000129; RV32I-FPELIM-NEXT: sw a1, 4(s0)
130; RV32I-FPELIM-NEXT: addi a0, a1, 15
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000131; RV32I-FPELIM-NEXT: andi a0, a0, -16
132; RV32I-FPELIM-NEXT: sub a0, sp, a0
133; RV32I-FPELIM-NEXT: mv sp, a0
Shiva Chend58bd8d2018-04-25 14:19:12 +0000134; RV32I-FPELIM-NEXT: call notdead
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000135; RV32I-FPELIM-NEXT: mv a0, s1
136; RV32I-FPELIM-NEXT: addi sp, s0, -16
137; RV32I-FPELIM-NEXT: lw s1, 4(sp)
138; RV32I-FPELIM-NEXT: lw s0, 8(sp)
139; RV32I-FPELIM-NEXT: lw ra, 12(sp)
140; RV32I-FPELIM-NEXT: addi sp, sp, 48
141; RV32I-FPELIM-NEXT: ret
142;
143; RV32I-WITHFP-LABEL: va1_va_arg_alloca:
144; RV32I-WITHFP: # %bb.0:
145; RV32I-WITHFP-NEXT: addi sp, sp, -48
146; RV32I-WITHFP-NEXT: sw ra, 12(sp)
147; RV32I-WITHFP-NEXT: sw s0, 8(sp)
148; RV32I-WITHFP-NEXT: sw s1, 4(sp)
149; RV32I-WITHFP-NEXT: addi s0, sp, 16
Alex Bradbury686ef922018-10-11 11:11:58 +0000150; RV32I-WITHFP-NEXT: mv s1, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000151; RV32I-WITHFP-NEXT: sw a7, 28(s0)
152; RV32I-WITHFP-NEXT: sw a6, 24(s0)
153; RV32I-WITHFP-NEXT: sw a5, 20(s0)
154; RV32I-WITHFP-NEXT: sw a4, 16(s0)
155; RV32I-WITHFP-NEXT: sw a3, 12(s0)
156; RV32I-WITHFP-NEXT: sw a2, 8(s0)
157; RV32I-WITHFP-NEXT: addi a0, s0, 8
158; RV32I-WITHFP-NEXT: sw a0, -16(s0)
Alex Bradbury686ef922018-10-11 11:11:58 +0000159; RV32I-WITHFP-NEXT: sw a1, 4(s0)
160; RV32I-WITHFP-NEXT: addi a0, a1, 15
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000161; RV32I-WITHFP-NEXT: andi a0, a0, -16
162; RV32I-WITHFP-NEXT: sub a0, sp, a0
163; RV32I-WITHFP-NEXT: mv sp, a0
Shiva Chend58bd8d2018-04-25 14:19:12 +0000164; RV32I-WITHFP-NEXT: call notdead
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000165; RV32I-WITHFP-NEXT: mv a0, s1
166; RV32I-WITHFP-NEXT: addi sp, s0, -16
167; RV32I-WITHFP-NEXT: lw s1, 4(sp)
168; RV32I-WITHFP-NEXT: lw s0, 8(sp)
169; RV32I-WITHFP-NEXT: lw ra, 12(sp)
170; RV32I-WITHFP-NEXT: addi sp, sp, 48
171; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000172 %va = alloca i8*, align 4
173 %1 = bitcast i8** %va to i8*
174 call void @llvm.va_start(i8* %1)
175 %2 = va_arg i8** %va, i32
176 %3 = alloca i8, i32 %2
177 call void @notdead(i8* %3)
178 call void @llvm.va_end(i8* %1)
179 ret i32 %2
180}
181
182define void @va1_caller() nounwind {
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000183; Pass a double, as a float would be promoted by a C/C++ frontend
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000184; RV32I-FPELIM-LABEL: va1_caller:
185; RV32I-FPELIM: # %bb.0:
186; RV32I-FPELIM-NEXT: addi sp, sp, -16
187; RV32I-FPELIM-NEXT: sw ra, 12(sp)
Alex Bradbury3ff20222018-04-18 20:34:23 +0000188; RV32I-FPELIM-NEXT: lui a3, 261888
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000189; RV32I-FPELIM-NEXT: addi a4, zero, 2
190; RV32I-FPELIM-NEXT: mv a2, zero
Shiva Chend58bd8d2018-04-25 14:19:12 +0000191; RV32I-FPELIM-NEXT: call va1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000192; RV32I-FPELIM-NEXT: lw ra, 12(sp)
193; RV32I-FPELIM-NEXT: addi sp, sp, 16
194; RV32I-FPELIM-NEXT: ret
195;
196; RV32I-WITHFP-LABEL: va1_caller:
197; RV32I-WITHFP: # %bb.0:
198; RV32I-WITHFP-NEXT: addi sp, sp, -16
199; RV32I-WITHFP-NEXT: sw ra, 12(sp)
200; RV32I-WITHFP-NEXT: sw s0, 8(sp)
201; RV32I-WITHFP-NEXT: addi s0, sp, 16
Alex Bradbury3ff20222018-04-18 20:34:23 +0000202; RV32I-WITHFP-NEXT: lui a3, 261888
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000203; RV32I-WITHFP-NEXT: addi a4, zero, 2
204; RV32I-WITHFP-NEXT: mv a2, zero
Shiva Chend58bd8d2018-04-25 14:19:12 +0000205; RV32I-WITHFP-NEXT: call va1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000206; RV32I-WITHFP-NEXT: lw s0, 8(sp)
207; RV32I-WITHFP-NEXT: lw ra, 12(sp)
208; RV32I-WITHFP-NEXT: addi sp, sp, 16
209; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000210 %1 = call i32 (i8*, ...) @va1(i8* undef, double 1.0, i32 2)
211 ret void
212}
213
214; Ensure that 2x xlen size+alignment varargs are accessed via an "aligned"
215; register pair (where the first register is even-numbered).
216
217define double @va2(i8 *%fmt, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000218; RV32I-FPELIM-LABEL: va2:
219; RV32I-FPELIM: # %bb.0:
220; RV32I-FPELIM-NEXT: addi sp, sp, -48
221; RV32I-FPELIM-NEXT: sw a7, 44(sp)
222; RV32I-FPELIM-NEXT: sw a6, 40(sp)
223; RV32I-FPELIM-NEXT: sw a5, 36(sp)
224; RV32I-FPELIM-NEXT: sw a4, 32(sp)
225; RV32I-FPELIM-NEXT: sw a3, 28(sp)
226; RV32I-FPELIM-NEXT: sw a2, 24(sp)
227; RV32I-FPELIM-NEXT: sw a1, 20(sp)
228; RV32I-FPELIM-NEXT: addi a0, sp, 35
229; RV32I-FPELIM-NEXT: sw a0, 12(sp)
230; RV32I-FPELIM-NEXT: addi a0, sp, 27
231; RV32I-FPELIM-NEXT: andi a1, a0, -8
232; RV32I-FPELIM-NEXT: lw a0, 0(a1)
233; RV32I-FPELIM-NEXT: ori a1, a1, 4
234; RV32I-FPELIM-NEXT: lw a1, 0(a1)
235; RV32I-FPELIM-NEXT: addi sp, sp, 48
236; RV32I-FPELIM-NEXT: ret
237;
238; RV32I-WITHFP-LABEL: va2:
239; RV32I-WITHFP: # %bb.0:
240; RV32I-WITHFP-NEXT: addi sp, sp, -48
241; RV32I-WITHFP-NEXT: sw ra, 12(sp)
242; RV32I-WITHFP-NEXT: sw s0, 8(sp)
243; RV32I-WITHFP-NEXT: addi s0, sp, 16
244; RV32I-WITHFP-NEXT: sw a7, 28(s0)
245; RV32I-WITHFP-NEXT: sw a6, 24(s0)
246; RV32I-WITHFP-NEXT: sw a5, 20(s0)
247; RV32I-WITHFP-NEXT: sw a4, 16(s0)
248; RV32I-WITHFP-NEXT: sw a3, 12(s0)
249; RV32I-WITHFP-NEXT: sw a2, 8(s0)
250; RV32I-WITHFP-NEXT: sw a1, 4(s0)
251; RV32I-WITHFP-NEXT: addi a0, s0, 19
252; RV32I-WITHFP-NEXT: sw a0, -12(s0)
253; RV32I-WITHFP-NEXT: addi a0, s0, 11
254; RV32I-WITHFP-NEXT: andi a1, a0, -8
255; RV32I-WITHFP-NEXT: lw a0, 0(a1)
256; RV32I-WITHFP-NEXT: ori a1, a1, 4
257; RV32I-WITHFP-NEXT: lw a1, 0(a1)
258; RV32I-WITHFP-NEXT: lw s0, 8(sp)
259; RV32I-WITHFP-NEXT: lw ra, 12(sp)
260; RV32I-WITHFP-NEXT: addi sp, sp, 48
261; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000262 %va = alloca i8*, align 4
263 %1 = bitcast i8** %va to i8*
264 call void @llvm.va_start(i8* %1)
265 %2 = bitcast i8** %va to i32*
266 %argp.cur = load i32, i32* %2, align 4
267 %3 = add i32 %argp.cur, 7
268 %4 = and i32 %3, -8
269 %argp.cur.aligned = inttoptr i32 %3 to i8*
270 %argp.next = getelementptr inbounds i8, i8* %argp.cur.aligned, i32 8
271 store i8* %argp.next, i8** %va, align 4
272 %5 = inttoptr i32 %4 to double*
273 %6 = load double, double* %5, align 8
274 call void @llvm.va_end(i8* %1)
275 ret double %6
276}
277
278define double @va2_va_arg(i8 *%fmt, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000279; RV32I-FPELIM-LABEL: va2_va_arg:
280; RV32I-FPELIM: # %bb.0:
281; RV32I-FPELIM-NEXT: addi sp, sp, -48
282; RV32I-FPELIM-NEXT: sw a7, 44(sp)
283; RV32I-FPELIM-NEXT: sw a6, 40(sp)
284; RV32I-FPELIM-NEXT: sw a5, 36(sp)
285; RV32I-FPELIM-NEXT: sw a4, 32(sp)
286; RV32I-FPELIM-NEXT: sw a3, 28(sp)
287; RV32I-FPELIM-NEXT: sw a2, 24(sp)
288; RV32I-FPELIM-NEXT: sw a1, 20(sp)
289; RV32I-FPELIM-NEXT: addi a0, sp, 27
290; RV32I-FPELIM-NEXT: andi a0, a0, -8
291; RV32I-FPELIM-NEXT: ori a1, a0, 4
292; RV32I-FPELIM-NEXT: sw a1, 12(sp)
293; RV32I-FPELIM-NEXT: lw a0, 0(a0)
294; RV32I-FPELIM-NEXT: addi a2, a1, 4
295; RV32I-FPELIM-NEXT: sw a2, 12(sp)
296; RV32I-FPELIM-NEXT: lw a1, 0(a1)
297; RV32I-FPELIM-NEXT: addi sp, sp, 48
298; RV32I-FPELIM-NEXT: ret
299;
300; RV32I-WITHFP-LABEL: va2_va_arg:
301; RV32I-WITHFP: # %bb.0:
302; RV32I-WITHFP-NEXT: addi sp, sp, -48
303; RV32I-WITHFP-NEXT: sw ra, 12(sp)
304; RV32I-WITHFP-NEXT: sw s0, 8(sp)
305; RV32I-WITHFP-NEXT: addi s0, sp, 16
306; RV32I-WITHFP-NEXT: sw a7, 28(s0)
307; RV32I-WITHFP-NEXT: sw a6, 24(s0)
308; RV32I-WITHFP-NEXT: sw a5, 20(s0)
309; RV32I-WITHFP-NEXT: sw a4, 16(s0)
310; RV32I-WITHFP-NEXT: sw a3, 12(s0)
311; RV32I-WITHFP-NEXT: sw a2, 8(s0)
312; RV32I-WITHFP-NEXT: sw a1, 4(s0)
313; RV32I-WITHFP-NEXT: addi a0, s0, 11
314; RV32I-WITHFP-NEXT: andi a0, a0, -8
315; RV32I-WITHFP-NEXT: ori a1, a0, 4
316; RV32I-WITHFP-NEXT: sw a1, -12(s0)
317; RV32I-WITHFP-NEXT: lw a0, 0(a0)
318; RV32I-WITHFP-NEXT: addi a2, a1, 4
319; RV32I-WITHFP-NEXT: sw a2, -12(s0)
320; RV32I-WITHFP-NEXT: lw a1, 0(a1)
321; RV32I-WITHFP-NEXT: lw s0, 8(sp)
322; RV32I-WITHFP-NEXT: lw ra, 12(sp)
323; RV32I-WITHFP-NEXT: addi sp, sp, 48
324; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000325 %va = alloca i8*, align 4
326 %1 = bitcast i8** %va to i8*
327 call void @llvm.va_start(i8* %1)
328 %2 = va_arg i8** %va, double
329 call void @llvm.va_end(i8* %1)
330 ret double %2
331}
332
333define void @va2_caller() nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000334; RV32I-FPELIM-LABEL: va2_caller:
335; RV32I-FPELIM: # %bb.0:
336; RV32I-FPELIM-NEXT: addi sp, sp, -16
337; RV32I-FPELIM-NEXT: sw ra, 12(sp)
Alex Bradbury3ff20222018-04-18 20:34:23 +0000338; RV32I-FPELIM-NEXT: lui a3, 261888
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000339; RV32I-FPELIM-NEXT: mv a2, zero
Shiva Chend58bd8d2018-04-25 14:19:12 +0000340; RV32I-FPELIM-NEXT: call va2
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000341; RV32I-FPELIM-NEXT: lw ra, 12(sp)
342; RV32I-FPELIM-NEXT: addi sp, sp, 16
343; RV32I-FPELIM-NEXT: ret
344;
345; RV32I-WITHFP-LABEL: va2_caller:
346; RV32I-WITHFP: # %bb.0:
347; RV32I-WITHFP-NEXT: addi sp, sp, -16
348; RV32I-WITHFP-NEXT: sw ra, 12(sp)
349; RV32I-WITHFP-NEXT: sw s0, 8(sp)
350; RV32I-WITHFP-NEXT: addi s0, sp, 16
Alex Bradbury3ff20222018-04-18 20:34:23 +0000351; RV32I-WITHFP-NEXT: lui a3, 261888
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000352; RV32I-WITHFP-NEXT: mv a2, zero
Shiva Chend58bd8d2018-04-25 14:19:12 +0000353; RV32I-WITHFP-NEXT: call va2
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000354; RV32I-WITHFP-NEXT: lw s0, 8(sp)
355; RV32I-WITHFP-NEXT: lw ra, 12(sp)
356; RV32I-WITHFP-NEXT: addi sp, sp, 16
357; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000358 %1 = call double (i8*, ...) @va2(i8* undef, double 1.000000e+00)
359 ret void
360}
361
362; Ensure a named double argument is passed in a1 and a2, while the vararg
363; double is passed in a4 and a5 (rather than a3 and a4)
364
365define double @va3(i32 %a, double %b, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000366; RV32I-FPELIM-LABEL: va3:
367; RV32I-FPELIM: # %bb.0:
368; RV32I-FPELIM-NEXT: addi sp, sp, -32
369; RV32I-FPELIM-NEXT: sw ra, 4(sp)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000370; RV32I-FPELIM-NEXT: mv t0, a2
371; RV32I-FPELIM-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000372; RV32I-FPELIM-NEXT: sw a7, 28(sp)
373; RV32I-FPELIM-NEXT: sw a6, 24(sp)
374; RV32I-FPELIM-NEXT: sw a5, 20(sp)
375; RV32I-FPELIM-NEXT: sw a4, 16(sp)
376; RV32I-FPELIM-NEXT: sw a3, 12(sp)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000377; RV32I-FPELIM-NEXT: addi a1, sp, 27
378; RV32I-FPELIM-NEXT: sw a1, 0(sp)
379; RV32I-FPELIM-NEXT: addi a1, sp, 19
380; RV32I-FPELIM-NEXT: andi a1, a1, -8
381; RV32I-FPELIM-NEXT: lw a2, 0(a1)
382; RV32I-FPELIM-NEXT: ori a1, a1, 4
383; RV32I-FPELIM-NEXT: lw a3, 0(a1)
384; RV32I-FPELIM-NEXT: mv a1, t0
Shiva Chend58bd8d2018-04-25 14:19:12 +0000385; RV32I-FPELIM-NEXT: call __adddf3
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000386; RV32I-FPELIM-NEXT: lw ra, 4(sp)
387; RV32I-FPELIM-NEXT: addi sp, sp, 32
388; RV32I-FPELIM-NEXT: ret
389;
390; RV32I-WITHFP-LABEL: va3:
391; RV32I-WITHFP: # %bb.0:
392; RV32I-WITHFP-NEXT: addi sp, sp, -48
393; RV32I-WITHFP-NEXT: sw ra, 20(sp)
394; RV32I-WITHFP-NEXT: sw s0, 16(sp)
395; RV32I-WITHFP-NEXT: addi s0, sp, 24
Alex Bradbury90fc1002018-10-05 18:25:55 +0000396; RV32I-WITHFP-NEXT: mv t0, a2
397; RV32I-WITHFP-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000398; RV32I-WITHFP-NEXT: sw a7, 20(s0)
399; RV32I-WITHFP-NEXT: sw a6, 16(s0)
400; RV32I-WITHFP-NEXT: sw a5, 12(s0)
401; RV32I-WITHFP-NEXT: sw a4, 8(s0)
402; RV32I-WITHFP-NEXT: sw a3, 4(s0)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000403; RV32I-WITHFP-NEXT: addi a1, s0, 19
404; RV32I-WITHFP-NEXT: sw a1, -12(s0)
405; RV32I-WITHFP-NEXT: addi a1, s0, 11
406; RV32I-WITHFP-NEXT: andi a1, a1, -8
407; RV32I-WITHFP-NEXT: lw a2, 0(a1)
408; RV32I-WITHFP-NEXT: ori a1, a1, 4
409; RV32I-WITHFP-NEXT: lw a3, 0(a1)
410; RV32I-WITHFP-NEXT: mv a1, t0
Shiva Chend58bd8d2018-04-25 14:19:12 +0000411; RV32I-WITHFP-NEXT: call __adddf3
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000412; RV32I-WITHFP-NEXT: lw s0, 16(sp)
413; RV32I-WITHFP-NEXT: lw ra, 20(sp)
414; RV32I-WITHFP-NEXT: addi sp, sp, 48
415; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000416 %va = alloca i8*, align 4
417 %1 = bitcast i8** %va to i8*
418 call void @llvm.va_start(i8* %1)
419 %2 = bitcast i8** %va to i32*
420 %argp.cur = load i32, i32* %2, align 4
421 %3 = add i32 %argp.cur, 7
422 %4 = and i32 %3, -8
423 %argp.cur.aligned = inttoptr i32 %3 to i8*
424 %argp.next = getelementptr inbounds i8, i8* %argp.cur.aligned, i32 8
425 store i8* %argp.next, i8** %va, align 4
426 %5 = inttoptr i32 %4 to double*
427 %6 = load double, double* %5, align 8
428 call void @llvm.va_end(i8* %1)
429 %7 = fadd double %b, %6
430 ret double %7
431}
432
433define double @va3_va_arg(i32 %a, double %b, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000434; RV32I-FPELIM-LABEL: va3_va_arg:
435; RV32I-FPELIM: # %bb.0:
436; RV32I-FPELIM-NEXT: addi sp, sp, -32
437; RV32I-FPELIM-NEXT: sw ra, 4(sp)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000438; RV32I-FPELIM-NEXT: mv t0, a2
439; RV32I-FPELIM-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000440; RV32I-FPELIM-NEXT: sw a7, 28(sp)
441; RV32I-FPELIM-NEXT: sw a6, 24(sp)
442; RV32I-FPELIM-NEXT: sw a5, 20(sp)
443; RV32I-FPELIM-NEXT: sw a4, 16(sp)
444; RV32I-FPELIM-NEXT: sw a3, 12(sp)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000445; RV32I-FPELIM-NEXT: addi a1, sp, 19
446; RV32I-FPELIM-NEXT: andi a1, a1, -8
447; RV32I-FPELIM-NEXT: ori a3, a1, 4
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000448; RV32I-FPELIM-NEXT: sw a3, 0(sp)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000449; RV32I-FPELIM-NEXT: lw a2, 0(a1)
450; RV32I-FPELIM-NEXT: addi a1, a3, 4
451; RV32I-FPELIM-NEXT: sw a1, 0(sp)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000452; RV32I-FPELIM-NEXT: lw a3, 0(a3)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000453; RV32I-FPELIM-NEXT: mv a1, t0
Shiva Chend58bd8d2018-04-25 14:19:12 +0000454; RV32I-FPELIM-NEXT: call __adddf3
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000455; RV32I-FPELIM-NEXT: lw ra, 4(sp)
456; RV32I-FPELIM-NEXT: addi sp, sp, 32
457; RV32I-FPELIM-NEXT: ret
458;
459; RV32I-WITHFP-LABEL: va3_va_arg:
460; RV32I-WITHFP: # %bb.0:
461; RV32I-WITHFP-NEXT: addi sp, sp, -48
462; RV32I-WITHFP-NEXT: sw ra, 20(sp)
463; RV32I-WITHFP-NEXT: sw s0, 16(sp)
464; RV32I-WITHFP-NEXT: addi s0, sp, 24
Alex Bradbury90fc1002018-10-05 18:25:55 +0000465; RV32I-WITHFP-NEXT: mv t0, a2
466; RV32I-WITHFP-NEXT: mv a0, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000467; RV32I-WITHFP-NEXT: sw a7, 20(s0)
468; RV32I-WITHFP-NEXT: sw a6, 16(s0)
469; RV32I-WITHFP-NEXT: sw a5, 12(s0)
470; RV32I-WITHFP-NEXT: sw a4, 8(s0)
471; RV32I-WITHFP-NEXT: sw a3, 4(s0)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000472; RV32I-WITHFP-NEXT: addi a1, s0, 11
473; RV32I-WITHFP-NEXT: andi a1, a1, -8
474; RV32I-WITHFP-NEXT: ori a3, a1, 4
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000475; RV32I-WITHFP-NEXT: sw a3, -12(s0)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000476; RV32I-WITHFP-NEXT: lw a2, 0(a1)
477; RV32I-WITHFP-NEXT: addi a1, a3, 4
478; RV32I-WITHFP-NEXT: sw a1, -12(s0)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000479; RV32I-WITHFP-NEXT: lw a3, 0(a3)
Alex Bradbury90fc1002018-10-05 18:25:55 +0000480; RV32I-WITHFP-NEXT: mv a1, t0
Shiva Chend58bd8d2018-04-25 14:19:12 +0000481; RV32I-WITHFP-NEXT: call __adddf3
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000482; RV32I-WITHFP-NEXT: lw s0, 16(sp)
483; RV32I-WITHFP-NEXT: lw ra, 20(sp)
484; RV32I-WITHFP-NEXT: addi sp, sp, 48
485; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000486 %va = alloca i8*, align 4
487 %1 = bitcast i8** %va to i8*
488 call void @llvm.va_start(i8* %1)
489 %2 = va_arg i8** %va, double
490 call void @llvm.va_end(i8* %1)
491 %3 = fadd double %b, %2
492 ret double %3
493}
494
495define void @va3_caller() nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000496; RV32I-FPELIM-LABEL: va3_caller:
497; RV32I-FPELIM: # %bb.0:
498; RV32I-FPELIM-NEXT: addi sp, sp, -16
499; RV32I-FPELIM-NEXT: sw ra, 12(sp)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000500; RV32I-FPELIM-NEXT: addi a0, zero, 2
Alex Bradbury3ff20222018-04-18 20:34:23 +0000501; RV32I-FPELIM-NEXT: lui a2, 261888
502; RV32I-FPELIM-NEXT: lui a5, 262144
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000503; RV32I-FPELIM-NEXT: mv a1, zero
504; RV32I-FPELIM-NEXT: mv a4, zero
Shiva Chend58bd8d2018-04-25 14:19:12 +0000505; RV32I-FPELIM-NEXT: call va3
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000506; RV32I-FPELIM-NEXT: lw ra, 12(sp)
507; RV32I-FPELIM-NEXT: addi sp, sp, 16
508; RV32I-FPELIM-NEXT: ret
509;
510; RV32I-WITHFP-LABEL: va3_caller:
511; RV32I-WITHFP: # %bb.0:
512; RV32I-WITHFP-NEXT: addi sp, sp, -16
513; RV32I-WITHFP-NEXT: sw ra, 12(sp)
514; RV32I-WITHFP-NEXT: sw s0, 8(sp)
515; RV32I-WITHFP-NEXT: addi s0, sp, 16
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000516; RV32I-WITHFP-NEXT: addi a0, zero, 2
Alex Bradbury3ff20222018-04-18 20:34:23 +0000517; RV32I-WITHFP-NEXT: lui a2, 261888
518; RV32I-WITHFP-NEXT: lui a5, 262144
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000519; RV32I-WITHFP-NEXT: mv a1, zero
520; RV32I-WITHFP-NEXT: mv a4, zero
Shiva Chend58bd8d2018-04-25 14:19:12 +0000521; RV32I-WITHFP-NEXT: call va3
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000522; RV32I-WITHFP-NEXT: lw s0, 8(sp)
523; RV32I-WITHFP-NEXT: lw ra, 12(sp)
524; RV32I-WITHFP-NEXT: addi sp, sp, 16
525; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000526 %1 = call double (i32, double, ...) @va3(i32 2, double 1.000000e+00, double 2.000000e+00)
527 ret void
528}
529
530declare void @llvm.va_copy(i8*, i8*)
531
532define i32 @va4_va_copy(i32 %argno, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000533; RV32I-FPELIM-LABEL: va4_va_copy:
534; RV32I-FPELIM: # %bb.0:
535; RV32I-FPELIM-NEXT: addi sp, sp, -48
536; RV32I-FPELIM-NEXT: sw ra, 12(sp)
537; RV32I-FPELIM-NEXT: sw s1, 8(sp)
Alex Bradbury686ef922018-10-11 11:11:58 +0000538; RV32I-FPELIM-NEXT: mv s1, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000539; RV32I-FPELIM-NEXT: sw a7, 44(sp)
540; RV32I-FPELIM-NEXT: sw a6, 40(sp)
541; RV32I-FPELIM-NEXT: sw a5, 36(sp)
542; RV32I-FPELIM-NEXT: sw a4, 32(sp)
543; RV32I-FPELIM-NEXT: sw a3, 28(sp)
544; RV32I-FPELIM-NEXT: sw a2, 24(sp)
Alex Bradbury686ef922018-10-11 11:11:58 +0000545; RV32I-FPELIM-NEXT: sw a1, 20(sp)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000546; RV32I-FPELIM-NEXT: addi a0, sp, 24
547; RV32I-FPELIM-NEXT: sw a0, 4(sp)
548; RV32I-FPELIM-NEXT: sw a0, 0(sp)
Shiva Chend58bd8d2018-04-25 14:19:12 +0000549; RV32I-FPELIM-NEXT: call notdead
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000550; RV32I-FPELIM-NEXT: lw a0, 4(sp)
551; RV32I-FPELIM-NEXT: addi a0, a0, 3
552; RV32I-FPELIM-NEXT: andi a0, a0, -4
553; RV32I-FPELIM-NEXT: addi a1, a0, 4
554; RV32I-FPELIM-NEXT: sw a1, 4(sp)
555; RV32I-FPELIM-NEXT: lw a1, 0(a0)
556; RV32I-FPELIM-NEXT: addi a0, a0, 7
557; RV32I-FPELIM-NEXT: andi a0, a0, -4
558; RV32I-FPELIM-NEXT: addi a2, a0, 4
559; RV32I-FPELIM-NEXT: sw a2, 4(sp)
560; RV32I-FPELIM-NEXT: lw a2, 0(a0)
561; RV32I-FPELIM-NEXT: addi a0, a0, 7
562; RV32I-FPELIM-NEXT: andi a0, a0, -4
563; RV32I-FPELIM-NEXT: addi a3, a0, 4
564; RV32I-FPELIM-NEXT: sw a3, 4(sp)
565; RV32I-FPELIM-NEXT: add a1, a1, s1
566; RV32I-FPELIM-NEXT: add a1, a1, a2
567; RV32I-FPELIM-NEXT: lw a0, 0(a0)
568; RV32I-FPELIM-NEXT: add a0, a1, a0
569; RV32I-FPELIM-NEXT: lw s1, 8(sp)
570; RV32I-FPELIM-NEXT: lw ra, 12(sp)
571; RV32I-FPELIM-NEXT: addi sp, sp, 48
572; RV32I-FPELIM-NEXT: ret
573;
574; RV32I-WITHFP-LABEL: va4_va_copy:
575; RV32I-WITHFP: # %bb.0:
576; RV32I-WITHFP-NEXT: addi sp, sp, -64
577; RV32I-WITHFP-NEXT: sw ra, 28(sp)
578; RV32I-WITHFP-NEXT: sw s0, 24(sp)
579; RV32I-WITHFP-NEXT: sw s1, 20(sp)
580; RV32I-WITHFP-NEXT: addi s0, sp, 32
Alex Bradbury686ef922018-10-11 11:11:58 +0000581; RV32I-WITHFP-NEXT: mv s1, a1
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000582; RV32I-WITHFP-NEXT: sw a7, 28(s0)
583; RV32I-WITHFP-NEXT: sw a6, 24(s0)
584; RV32I-WITHFP-NEXT: sw a5, 20(s0)
585; RV32I-WITHFP-NEXT: sw a4, 16(s0)
586; RV32I-WITHFP-NEXT: sw a3, 12(s0)
587; RV32I-WITHFP-NEXT: sw a2, 8(s0)
Alex Bradbury686ef922018-10-11 11:11:58 +0000588; RV32I-WITHFP-NEXT: sw a1, 4(s0)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000589; RV32I-WITHFP-NEXT: addi a0, s0, 8
590; RV32I-WITHFP-NEXT: sw a0, -16(s0)
591; RV32I-WITHFP-NEXT: sw a0, -20(s0)
Shiva Chend58bd8d2018-04-25 14:19:12 +0000592; RV32I-WITHFP-NEXT: call notdead
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000593; RV32I-WITHFP-NEXT: lw a0, -16(s0)
594; RV32I-WITHFP-NEXT: addi a0, a0, 3
595; RV32I-WITHFP-NEXT: andi a0, a0, -4
596; RV32I-WITHFP-NEXT: addi a1, a0, 4
597; RV32I-WITHFP-NEXT: sw a1, -16(s0)
598; RV32I-WITHFP-NEXT: lw a1, 0(a0)
599; RV32I-WITHFP-NEXT: addi a0, a0, 7
600; RV32I-WITHFP-NEXT: andi a0, a0, -4
601; RV32I-WITHFP-NEXT: addi a2, a0, 4
602; RV32I-WITHFP-NEXT: sw a2, -16(s0)
603; RV32I-WITHFP-NEXT: lw a2, 0(a0)
604; RV32I-WITHFP-NEXT: addi a0, a0, 7
605; RV32I-WITHFP-NEXT: andi a0, a0, -4
606; RV32I-WITHFP-NEXT: addi a3, a0, 4
607; RV32I-WITHFP-NEXT: sw a3, -16(s0)
608; RV32I-WITHFP-NEXT: add a1, a1, s1
609; RV32I-WITHFP-NEXT: add a1, a1, a2
610; RV32I-WITHFP-NEXT: lw a0, 0(a0)
611; RV32I-WITHFP-NEXT: add a0, a1, a0
612; RV32I-WITHFP-NEXT: lw s1, 20(sp)
613; RV32I-WITHFP-NEXT: lw s0, 24(sp)
614; RV32I-WITHFP-NEXT: lw ra, 28(sp)
615; RV32I-WITHFP-NEXT: addi sp, sp, 64
616; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000617 %vargs = alloca i8*, align 4
618 %wargs = alloca i8*, align 4
619 %1 = bitcast i8** %vargs to i8*
620 %2 = bitcast i8** %wargs to i8*
621 call void @llvm.va_start(i8* %1)
622 %3 = va_arg i8** %vargs, i32
623 call void @llvm.va_copy(i8* %2, i8* %1)
624 %4 = load i8*, i8** %wargs, align 4
625 call void @notdead(i8* %4)
626 %5 = va_arg i8** %vargs, i32
627 %6 = va_arg i8** %vargs, i32
628 %7 = va_arg i8** %vargs, i32
629 call void @llvm.va_end(i8* %1)
630 call void @llvm.va_end(i8* %2)
631 %add1 = add i32 %5, %3
632 %add2 = add i32 %add1, %6
633 %add3 = add i32 %add2, %7
634 ret i32 %add3
635}
636
637; Check 2x*xlen values are aligned appropriately when passed on the stack in a vararg call
638
639define i32 @va5_aligned_stack_callee(i32 %a, ...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000640; RV32I-FPELIM-LABEL: va5_aligned_stack_callee:
641; RV32I-FPELIM: # %bb.0:
642; RV32I-FPELIM-NEXT: addi sp, sp, -32
643; RV32I-FPELIM-NEXT: sw a7, 28(sp)
644; RV32I-FPELIM-NEXT: sw a6, 24(sp)
645; RV32I-FPELIM-NEXT: sw a5, 20(sp)
646; RV32I-FPELIM-NEXT: sw a4, 16(sp)
647; RV32I-FPELIM-NEXT: sw a3, 12(sp)
648; RV32I-FPELIM-NEXT: sw a2, 8(sp)
649; RV32I-FPELIM-NEXT: sw a1, 4(sp)
650; RV32I-FPELIM-NEXT: addi a0, zero, 1
651; RV32I-FPELIM-NEXT: addi sp, sp, 32
652; RV32I-FPELIM-NEXT: ret
653;
654; RV32I-WITHFP-LABEL: va5_aligned_stack_callee:
655; RV32I-WITHFP: # %bb.0:
656; RV32I-WITHFP-NEXT: addi sp, sp, -48
657; RV32I-WITHFP-NEXT: sw ra, 12(sp)
658; RV32I-WITHFP-NEXT: sw s0, 8(sp)
659; RV32I-WITHFP-NEXT: addi s0, sp, 16
660; RV32I-WITHFP-NEXT: sw a7, 28(s0)
661; RV32I-WITHFP-NEXT: sw a6, 24(s0)
662; RV32I-WITHFP-NEXT: sw a5, 20(s0)
663; RV32I-WITHFP-NEXT: sw a4, 16(s0)
664; RV32I-WITHFP-NEXT: sw a3, 12(s0)
665; RV32I-WITHFP-NEXT: sw a2, 8(s0)
666; RV32I-WITHFP-NEXT: sw a1, 4(s0)
667; RV32I-WITHFP-NEXT: addi a0, zero, 1
668; RV32I-WITHFP-NEXT: lw s0, 8(sp)
669; RV32I-WITHFP-NEXT: lw ra, 12(sp)
670; RV32I-WITHFP-NEXT: addi sp, sp, 48
671; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000672 ret i32 1
673}
674
675define void @va5_aligned_stack_caller() nounwind {
676; The double should be 8-byte aligned on the stack, but the two-element array
677; should only be 4-byte aligned
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000678; RV32I-FPELIM-LABEL: va5_aligned_stack_caller:
679; RV32I-FPELIM: # %bb.0:
680; RV32I-FPELIM-NEXT: addi sp, sp, -64
681; RV32I-FPELIM-NEXT: sw ra, 60(sp)
682; RV32I-FPELIM-NEXT: addi a0, zero, 17
683; RV32I-FPELIM-NEXT: sw a0, 24(sp)
684; RV32I-FPELIM-NEXT: addi a0, zero, 16
685; RV32I-FPELIM-NEXT: sw a0, 20(sp)
686; RV32I-FPELIM-NEXT: addi a0, zero, 15
687; RV32I-FPELIM-NEXT: sw a0, 16(sp)
688; RV32I-FPELIM-NEXT: lui a0, 262236
689; RV32I-FPELIM-NEXT: addi a0, a0, 655
690; RV32I-FPELIM-NEXT: sw a0, 12(sp)
691; RV32I-FPELIM-NEXT: lui a0, 377487
692; RV32I-FPELIM-NEXT: addi a0, a0, 1475
693; RV32I-FPELIM-NEXT: sw a0, 8(sp)
694; RV32I-FPELIM-NEXT: addi a0, zero, 14
695; RV32I-FPELIM-NEXT: sw a0, 0(sp)
696; RV32I-FPELIM-NEXT: lui a0, 262153
697; RV32I-FPELIM-NEXT: addi a0, a0, 491
698; RV32I-FPELIM-NEXT: sw a0, 44(sp)
699; RV32I-FPELIM-NEXT: lui a0, 545260
700; RV32I-FPELIM-NEXT: addi a0, a0, -1967
701; RV32I-FPELIM-NEXT: sw a0, 40(sp)
702; RV32I-FPELIM-NEXT: lui a0, 964690
703; RV32I-FPELIM-NEXT: addi a0, a0, -328
704; RV32I-FPELIM-NEXT: sw a0, 36(sp)
705; RV32I-FPELIM-NEXT: lui a0, 335544
706; RV32I-FPELIM-NEXT: addi a0, a0, 1311
707; RV32I-FPELIM-NEXT: sw a0, 32(sp)
Alex Bradbury099c7202018-04-18 19:02:31 +0000708; RV32I-FPELIM-NEXT: lui a0, 688509
709; RV32I-FPELIM-NEXT: addi a6, a0, -2048
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000710; RV32I-FPELIM-NEXT: addi a0, zero, 1
711; RV32I-FPELIM-NEXT: addi a1, zero, 11
712; RV32I-FPELIM-NEXT: addi a2, sp, 32
713; RV32I-FPELIM-NEXT: addi a3, zero, 12
714; RV32I-FPELIM-NEXT: addi a4, zero, 13
715; RV32I-FPELIM-NEXT: addi a7, zero, 4
Shiva Chend58bd8d2018-04-25 14:19:12 +0000716; RV32I-FPELIM-NEXT: call va5_aligned_stack_callee
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000717; RV32I-FPELIM-NEXT: lw ra, 60(sp)
718; RV32I-FPELIM-NEXT: addi sp, sp, 64
719; RV32I-FPELIM-NEXT: ret
720;
721; RV32I-WITHFP-LABEL: va5_aligned_stack_caller:
722; RV32I-WITHFP: # %bb.0:
723; RV32I-WITHFP-NEXT: addi sp, sp, -64
724; RV32I-WITHFP-NEXT: sw ra, 60(sp)
725; RV32I-WITHFP-NEXT: sw s0, 56(sp)
726; RV32I-WITHFP-NEXT: addi s0, sp, 64
727; RV32I-WITHFP-NEXT: addi a0, zero, 17
728; RV32I-WITHFP-NEXT: sw a0, 24(sp)
729; RV32I-WITHFP-NEXT: addi a0, zero, 16
730; RV32I-WITHFP-NEXT: sw a0, 20(sp)
731; RV32I-WITHFP-NEXT: addi a0, zero, 15
732; RV32I-WITHFP-NEXT: sw a0, 16(sp)
733; RV32I-WITHFP-NEXT: lui a0, 262236
734; RV32I-WITHFP-NEXT: addi a0, a0, 655
735; RV32I-WITHFP-NEXT: sw a0, 12(sp)
736; RV32I-WITHFP-NEXT: lui a0, 377487
737; RV32I-WITHFP-NEXT: addi a0, a0, 1475
738; RV32I-WITHFP-NEXT: sw a0, 8(sp)
739; RV32I-WITHFP-NEXT: addi a0, zero, 14
740; RV32I-WITHFP-NEXT: sw a0, 0(sp)
741; RV32I-WITHFP-NEXT: lui a0, 262153
742; RV32I-WITHFP-NEXT: addi a0, a0, 491
743; RV32I-WITHFP-NEXT: sw a0, -20(s0)
744; RV32I-WITHFP-NEXT: lui a0, 545260
745; RV32I-WITHFP-NEXT: addi a0, a0, -1967
746; RV32I-WITHFP-NEXT: sw a0, -24(s0)
747; RV32I-WITHFP-NEXT: lui a0, 964690
748; RV32I-WITHFP-NEXT: addi a0, a0, -328
749; RV32I-WITHFP-NEXT: sw a0, -28(s0)
750; RV32I-WITHFP-NEXT: lui a0, 335544
751; RV32I-WITHFP-NEXT: addi a0, a0, 1311
752; RV32I-WITHFP-NEXT: sw a0, -32(s0)
Alex Bradbury099c7202018-04-18 19:02:31 +0000753; RV32I-WITHFP-NEXT: lui a0, 688509
754; RV32I-WITHFP-NEXT: addi a6, a0, -2048
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000755; RV32I-WITHFP-NEXT: addi a0, zero, 1
756; RV32I-WITHFP-NEXT: addi a1, zero, 11
757; RV32I-WITHFP-NEXT: addi a2, s0, -32
758; RV32I-WITHFP-NEXT: addi a3, zero, 12
759; RV32I-WITHFP-NEXT: addi a4, zero, 13
760; RV32I-WITHFP-NEXT: addi a7, zero, 4
Shiva Chend58bd8d2018-04-25 14:19:12 +0000761; RV32I-WITHFP-NEXT: call va5_aligned_stack_callee
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000762; RV32I-WITHFP-NEXT: lw s0, 56(sp)
763; RV32I-WITHFP-NEXT: lw ra, 60(sp)
764; RV32I-WITHFP-NEXT: addi sp, sp, 64
765; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000766 %1 = call i32 (i32, ...) @va5_aligned_stack_callee(i32 1, i32 11,
767 fp128 0xLEB851EB851EB851F400091EB851EB851, i32 12, i32 13, i64 20000000000,
768 i32 14, double 2.720000e+00, i32 15, [2 x i32] [i32 16, i32 17])
769 ret void
770}
771
772; A function with no fixed arguments is not valid C, but can be
773; specified in LLVM IR. We must ensure the vararg save area is
774; still set up correctly.
775
776define i32 @va6_no_fixed_args(...) nounwind {
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000777; RV32I-FPELIM-LABEL: va6_no_fixed_args:
778; RV32I-FPELIM: # %bb.0:
779; RV32I-FPELIM-NEXT: addi sp, sp, -48
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000780; RV32I-FPELIM-NEXT: sw a7, 44(sp)
781; RV32I-FPELIM-NEXT: sw a6, 40(sp)
782; RV32I-FPELIM-NEXT: sw a5, 36(sp)
783; RV32I-FPELIM-NEXT: sw a4, 32(sp)
784; RV32I-FPELIM-NEXT: sw a3, 28(sp)
785; RV32I-FPELIM-NEXT: sw a2, 24(sp)
786; RV32I-FPELIM-NEXT: sw a1, 20(sp)
Alex Bradbury686ef922018-10-11 11:11:58 +0000787; RV32I-FPELIM-NEXT: addi a1, sp, 20
788; RV32I-FPELIM-NEXT: sw a1, 12(sp)
789; RV32I-FPELIM-NEXT: sw a0, 16(sp)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000790; RV32I-FPELIM-NEXT: addi sp, sp, 48
791; RV32I-FPELIM-NEXT: ret
792;
793; RV32I-WITHFP-LABEL: va6_no_fixed_args:
794; RV32I-WITHFP: # %bb.0:
795; RV32I-WITHFP-NEXT: addi sp, sp, -48
796; RV32I-WITHFP-NEXT: sw ra, 12(sp)
797; RV32I-WITHFP-NEXT: sw s0, 8(sp)
798; RV32I-WITHFP-NEXT: addi s0, sp, 16
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000799; RV32I-WITHFP-NEXT: sw a7, 28(s0)
800; RV32I-WITHFP-NEXT: sw a6, 24(s0)
801; RV32I-WITHFP-NEXT: sw a5, 20(s0)
802; RV32I-WITHFP-NEXT: sw a4, 16(s0)
803; RV32I-WITHFP-NEXT: sw a3, 12(s0)
804; RV32I-WITHFP-NEXT: sw a2, 8(s0)
805; RV32I-WITHFP-NEXT: sw a1, 4(s0)
Alex Bradbury686ef922018-10-11 11:11:58 +0000806; RV32I-WITHFP-NEXT: addi a1, s0, 4
807; RV32I-WITHFP-NEXT: sw a1, -12(s0)
808; RV32I-WITHFP-NEXT: sw a0, 0(s0)
Alex Bradbury7d6aa1f2018-01-18 11:34:02 +0000809; RV32I-WITHFP-NEXT: lw s0, 8(sp)
810; RV32I-WITHFP-NEXT: lw ra, 12(sp)
811; RV32I-WITHFP-NEXT: addi sp, sp, 48
812; RV32I-WITHFP-NEXT: ret
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000813 %va = alloca i8*, align 4
814 %1 = bitcast i8** %va to i8*
815 call void @llvm.va_start(i8* %1)
816 %2 = va_arg i8** %va, i32
817 call void @llvm.va_end(i8* %1)
818 ret i32 %2
819}