1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV32I %s
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV64I %s
7 ; When passing a function argument with a size that isn't a multiple of XLEN,
8 ; and the argument is split and passed indirectly, we must ensure that the stack
9 ; slot size appropriately reflects the total size of the parts the argument is
10 ; split into. Otherwise, stack writes can clobber neighboring values.
12 declare void @callee129(i129)
13 declare void @callee160(i160)
14 declare void @callee161(i161)
16 define i32 @caller129() nounwind {
17 ; RV32I-LABEL: caller129:
19 ; RV32I-NEXT: addi sp, sp, -32
20 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
21 ; RV32I-NEXT: li a0, 42
22 ; RV32I-NEXT: sw a0, 24(sp)
23 ; RV32I-NEXT: sw zero, 16(sp)
24 ; RV32I-NEXT: sw zero, 12(sp)
25 ; RV32I-NEXT: sw zero, 8(sp)
26 ; RV32I-NEXT: sw zero, 4(sp)
27 ; RV32I-NEXT: mv a0, sp
28 ; RV32I-NEXT: sw zero, 0(sp)
29 ; RV32I-NEXT: call callee129
30 ; RV32I-NEXT: lw a0, 24(sp)
31 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
32 ; RV32I-NEXT: addi sp, sp, 32
35 ; RV64I-LABEL: caller129:
37 ; RV64I-NEXT: addi sp, sp, -48
38 ; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
39 ; RV64I-NEXT: li a0, 42
40 ; RV64I-NEXT: sw a0, 36(sp)
41 ; RV64I-NEXT: sd zero, 16(sp)
42 ; RV64I-NEXT: sd zero, 8(sp)
43 ; RV64I-NEXT: mv a0, sp
44 ; RV64I-NEXT: sd zero, 0(sp)
45 ; RV64I-NEXT: call callee129
46 ; RV64I-NEXT: lw a0, 36(sp)
47 ; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
48 ; RV64I-NEXT: addi sp, sp, 48
52 call void @callee129(i129 0)
57 define i32 @caller160() nounwind {
58 ; RV32I-LABEL: caller160:
60 ; RV32I-NEXT: addi sp, sp, -32
61 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
62 ; RV32I-NEXT: li a0, 42
63 ; RV32I-NEXT: sw a0, 24(sp)
64 ; RV32I-NEXT: sw zero, 16(sp)
65 ; RV32I-NEXT: sw zero, 12(sp)
66 ; RV32I-NEXT: sw zero, 8(sp)
67 ; RV32I-NEXT: sw zero, 4(sp)
68 ; RV32I-NEXT: mv a0, sp
69 ; RV32I-NEXT: sw zero, 0(sp)
70 ; RV32I-NEXT: call callee160
71 ; RV32I-NEXT: lw a0, 24(sp)
72 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
73 ; RV32I-NEXT: addi sp, sp, 32
76 ; RV64I-LABEL: caller160:
78 ; RV64I-NEXT: addi sp, sp, -48
79 ; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
80 ; RV64I-NEXT: li a0, 42
81 ; RV64I-NEXT: sw a0, 36(sp)
82 ; RV64I-NEXT: sd zero, 16(sp)
83 ; RV64I-NEXT: sd zero, 8(sp)
84 ; RV64I-NEXT: mv a0, sp
85 ; RV64I-NEXT: sd zero, 0(sp)
86 ; RV64I-NEXT: call callee160
87 ; RV64I-NEXT: lw a0, 36(sp)
88 ; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
89 ; RV64I-NEXT: addi sp, sp, 48
93 call void @callee160(i160 0)
98 define i32 @caller161() nounwind {
99 ; RV32I-LABEL: caller161:
101 ; RV32I-NEXT: addi sp, sp, -32
102 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
103 ; RV32I-NEXT: li a0, 42
104 ; RV32I-NEXT: sw a0, 24(sp)
105 ; RV32I-NEXT: sw zero, 20(sp)
106 ; RV32I-NEXT: sw zero, 16(sp)
107 ; RV32I-NEXT: sw zero, 12(sp)
108 ; RV32I-NEXT: sw zero, 8(sp)
109 ; RV32I-NEXT: sw zero, 4(sp)
110 ; RV32I-NEXT: mv a0, sp
111 ; RV32I-NEXT: sw zero, 0(sp)
112 ; RV32I-NEXT: call callee161
113 ; RV32I-NEXT: lw a0, 24(sp)
114 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
115 ; RV32I-NEXT: addi sp, sp, 32
118 ; RV64I-LABEL: caller161:
120 ; RV64I-NEXT: addi sp, sp, -48
121 ; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
122 ; RV64I-NEXT: li a0, 42
123 ; RV64I-NEXT: sw a0, 36(sp)
124 ; RV64I-NEXT: sd zero, 16(sp)
125 ; RV64I-NEXT: sd zero, 8(sp)
126 ; RV64I-NEXT: mv a0, sp
127 ; RV64I-NEXT: sd zero, 0(sp)
128 ; RV64I-NEXT: call callee161
129 ; RV64I-NEXT: lw a0, 36(sp)
130 ; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
131 ; RV64I-NEXT: addi sp, sp, 48
135 call void @callee161(i161 0)
136 %2 = load i32, ptr %1