xref: /llvm-project/llvm/test/CodeGen/RISCV/stack-slot-size.ll (revision 2967e5f8007d873a3e9d97870d2461d0827a3976)
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
6
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.
11
12declare void @callee129(i129)
13declare void @callee160(i160)
14declare void @callee161(i161)
15
16define i32 @caller129() nounwind {
17; RV32I-LABEL: caller129:
18; RV32I:       # %bb.0:
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:    mv a0, sp
25; RV32I-NEXT:    sw zero, 0(sp)
26; RV32I-NEXT:    sw zero, 4(sp)
27; RV32I-NEXT:    sw zero, 8(sp)
28; RV32I-NEXT:    sw zero, 12(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
33; RV32I-NEXT:    ret
34;
35; RV64I-LABEL: caller129:
36; RV64I:       # %bb.0:
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:    mv a0, sp
42; RV64I-NEXT:    sd zero, 0(sp)
43; RV64I-NEXT:    sd zero, 8(sp)
44; RV64I-NEXT:    sd zero, 16(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
49; RV64I-NEXT:    ret
50  %1 = alloca i32
51  store i32 42, ptr %1
52  call void @callee129(i129 0)
53  %2 = load i32, ptr %1
54  ret i32 %2
55}
56
57define i32 @caller160() nounwind {
58; RV32I-LABEL: caller160:
59; RV32I:       # %bb.0:
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:    mv a0, sp
66; RV32I-NEXT:    sw zero, 0(sp)
67; RV32I-NEXT:    sw zero, 4(sp)
68; RV32I-NEXT:    sw zero, 8(sp)
69; RV32I-NEXT:    sw zero, 12(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
74; RV32I-NEXT:    ret
75;
76; RV64I-LABEL: caller160:
77; RV64I:       # %bb.0:
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:    mv a0, sp
83; RV64I-NEXT:    sd zero, 0(sp)
84; RV64I-NEXT:    sd zero, 8(sp)
85; RV64I-NEXT:    sd zero, 16(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
90; RV64I-NEXT:    ret
91  %1 = alloca i32
92  store i32 42, ptr %1
93  call void @callee160(i160 0)
94  %2 = load i32, ptr %1
95  ret i32 %2
96}
97
98define i32 @caller161() nounwind {
99; RV32I-LABEL: caller161:
100; RV32I:       # %bb.0:
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, 16(sp)
106; RV32I-NEXT:    sw zero, 20(sp)
107; RV32I-NEXT:    mv a0, sp
108; RV32I-NEXT:    sw zero, 0(sp)
109; RV32I-NEXT:    sw zero, 4(sp)
110; RV32I-NEXT:    sw zero, 8(sp)
111; RV32I-NEXT:    sw zero, 12(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
116; RV32I-NEXT:    ret
117;
118; RV64I-LABEL: caller161:
119; RV64I:       # %bb.0:
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:    mv a0, sp
125; RV64I-NEXT:    sd zero, 0(sp)
126; RV64I-NEXT:    sd zero, 8(sp)
127; RV64I-NEXT:    sd zero, 16(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
132; RV64I-NEXT:    ret
133  %1 = alloca i32
134  store i32 42, ptr %1
135  call void @callee161(i161 0)
136  %2 = load i32, ptr %1
137  ret i32 %2
138}
139