xref: /llvm-project/llvm/test/CodeGen/RISCV/local-stack-slot-allocation.ll (revision 97982a8c605fac7c86d02e641a6cd7898b3ca343)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV32I
3; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64I
4
5; This test case test the LocalStackSlotAllocation pass that use a base register
6; for the frame index that its offset is out-of-range (for RISC-V. the immediate
7; is 12 bits for the load store instruction (excludes vector load / store))
8define void @use_frame_base_reg() {
9; RV32I-LABEL: use_frame_base_reg:
10; RV32I:       # %bb.0:
11; RV32I-NEXT:    lui a0, 24
12; RV32I-NEXT:    addi a0, a0, 1712
13; RV32I-NEXT:    sub sp, sp, a0
14; RV32I-NEXT:    .cfi_def_cfa_offset 100016
15; RV32I-NEXT:    lui a0, 24
16; RV32I-NEXT:    addi a0, a0, 1704
17; RV32I-NEXT:    add a0, sp, a0
18; RV32I-NEXT:    lbu zero, 4(a0)
19; RV32I-NEXT:    lbu zero, 0(a0)
20; RV32I-NEXT:    lui a0, 24
21; RV32I-NEXT:    addi a0, a0, 1712
22; RV32I-NEXT:    add sp, sp, a0
23; RV32I-NEXT:    .cfi_def_cfa_offset 0
24; RV32I-NEXT:    ret
25;
26; RV64I-LABEL: use_frame_base_reg:
27; RV64I:       # %bb.0:
28; RV64I-NEXT:    lui a0, 24
29; RV64I-NEXT:    addiw a0, a0, 1712
30; RV64I-NEXT:    sub sp, sp, a0
31; RV64I-NEXT:    .cfi_def_cfa_offset 100016
32; RV64I-NEXT:    lui a0, 24
33; RV64I-NEXT:    addiw a0, a0, 1704
34; RV64I-NEXT:    add a0, sp, a0
35; RV64I-NEXT:    lbu zero, 4(a0)
36; RV64I-NEXT:    lbu zero, 0(a0)
37; RV64I-NEXT:    lui a0, 24
38; RV64I-NEXT:    addiw a0, a0, 1712
39; RV64I-NEXT:    add sp, sp, a0
40; RV64I-NEXT:    .cfi_def_cfa_offset 0
41; RV64I-NEXT:    ret
42
43  %va = alloca i8, align 4
44  %va1 = alloca i8, align 4
45  %large = alloca [ 100000 x i8 ]
46  %argp.cur = load volatile i8, ptr %va, align 4
47  %argp.next = load volatile i8, ptr %va1, align 4
48  ret void
49}
50
51; Test containing a load with its own local offset. Make sure isFrameOffsetLegal
52; considers it and creates a virtual base register.
53define void @load_with_offset() {
54; RV32I-LABEL: load_with_offset:
55; RV32I:       # %bb.0:
56; RV32I-NEXT:    addi sp, sp, -2048
57; RV32I-NEXT:    addi sp, sp, -464
58; RV32I-NEXT:    .cfi_def_cfa_offset 2512
59; RV32I-NEXT:    addi a0, sp, 2012
60; RV32I-NEXT:    lbu a1, 0(a0)
61; RV32I-NEXT:    sb a1, 0(a0)
62; RV32I-NEXT:    addi sp, sp, 2032
63; RV32I-NEXT:    addi sp, sp, 480
64; RV32I-NEXT:    .cfi_def_cfa_offset 0
65; RV32I-NEXT:    ret
66;
67; RV64I-LABEL: load_with_offset:
68; RV64I:       # %bb.0:
69; RV64I-NEXT:    addi sp, sp, -2048
70; RV64I-NEXT:    addi sp, sp, -464
71; RV64I-NEXT:    .cfi_def_cfa_offset 2512
72; RV64I-NEXT:    addi a0, sp, 2012
73; RV64I-NEXT:    lbu a1, 0(a0)
74; RV64I-NEXT:    sb a1, 0(a0)
75; RV64I-NEXT:    addi sp, sp, 2032
76; RV64I-NEXT:    addi sp, sp, 480
77; RV64I-NEXT:    .cfi_def_cfa_offset 0
78; RV64I-NEXT:    ret
79
80  %va = alloca [2500 x i8], align 4
81  %va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 2000
82  %load = load volatile i8, ptr %va_gep, align 4
83  store volatile i8 %load, ptr %va_gep, align 4
84  ret void
85}
86
87; Test containing a load with its own local offset that is smaller than the
88; previous test case. Make sure we don't create a virtual base register.
89define void @load_with_offset2() {
90; RV32I-LABEL: load_with_offset2:
91; RV32I:       # %bb.0:
92; RV32I-NEXT:    addi sp, sp, -2048
93; RV32I-NEXT:    addi sp, sp, -464
94; RV32I-NEXT:    .cfi_def_cfa_offset 2512
95; RV32I-NEXT:    lbu a0, 1412(sp)
96; RV32I-NEXT:    sb a0, 1412(sp)
97; RV32I-NEXT:    addi sp, sp, 2032
98; RV32I-NEXT:    addi sp, sp, 480
99; RV32I-NEXT:    .cfi_def_cfa_offset 0
100; RV32I-NEXT:    ret
101;
102; RV64I-LABEL: load_with_offset2:
103; RV64I:       # %bb.0:
104; RV64I-NEXT:    addi sp, sp, -2048
105; RV64I-NEXT:    addi sp, sp, -464
106; RV64I-NEXT:    .cfi_def_cfa_offset 2512
107; RV64I-NEXT:    lbu a0, 1412(sp)
108; RV64I-NEXT:    sb a0, 1412(sp)
109; RV64I-NEXT:    addi sp, sp, 2032
110; RV64I-NEXT:    addi sp, sp, 480
111; RV64I-NEXT:    .cfi_def_cfa_offset 0
112; RV64I-NEXT:    ret
113
114  %va = alloca [2500 x i8], align 4
115  %va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 1400
116  %load = load volatile i8, ptr %va_gep, align 4
117  store volatile i8 %load, ptr %va_gep, align 4
118  ret void
119}
120
121define void @frame_pointer() "frame-pointer"="all" {
122; RV32I-LABEL: frame_pointer:
123; RV32I:       # %bb.0:
124; RV32I-NEXT:    addi sp, sp, -2032
125; RV32I-NEXT:    .cfi_def_cfa_offset 2032
126; RV32I-NEXT:    sw ra, 2028(sp) # 4-byte Folded Spill
127; RV32I-NEXT:    sw s0, 2024(sp) # 4-byte Folded Spill
128; RV32I-NEXT:    .cfi_offset ra, -4
129; RV32I-NEXT:    .cfi_offset s0, -8
130; RV32I-NEXT:    addi s0, sp, 2032
131; RV32I-NEXT:    .cfi_def_cfa s0, 0
132; RV32I-NEXT:    addi sp, sp, -480
133; RV32I-NEXT:    lbu a0, -1960(s0)
134; RV32I-NEXT:    sb a0, -1960(s0)
135; RV32I-NEXT:    addi sp, sp, 480
136; RV32I-NEXT:    .cfi_def_cfa sp, 2032
137; RV32I-NEXT:    lw ra, 2028(sp) # 4-byte Folded Reload
138; RV32I-NEXT:    lw s0, 2024(sp) # 4-byte Folded Reload
139; RV32I-NEXT:    .cfi_restore ra
140; RV32I-NEXT:    .cfi_restore s0
141; RV32I-NEXT:    addi sp, sp, 2032
142; RV32I-NEXT:    .cfi_def_cfa_offset 0
143; RV32I-NEXT:    ret
144;
145; RV64I-LABEL: frame_pointer:
146; RV64I:       # %bb.0:
147; RV64I-NEXT:    addi sp, sp, -2032
148; RV64I-NEXT:    .cfi_def_cfa_offset 2032
149; RV64I-NEXT:    sd ra, 2024(sp) # 8-byte Folded Spill
150; RV64I-NEXT:    sd s0, 2016(sp) # 8-byte Folded Spill
151; RV64I-NEXT:    .cfi_offset ra, -8
152; RV64I-NEXT:    .cfi_offset s0, -16
153; RV64I-NEXT:    addi s0, sp, 2032
154; RV64I-NEXT:    .cfi_def_cfa s0, 0
155; RV64I-NEXT:    addi sp, sp, -496
156; RV64I-NEXT:    addi a0, s0, -1972
157; RV64I-NEXT:    lbu a1, 0(a0)
158; RV64I-NEXT:    sb a1, 0(a0)
159; RV64I-NEXT:    addi sp, sp, 496
160; RV64I-NEXT:    .cfi_def_cfa sp, 2032
161; RV64I-NEXT:    ld ra, 2024(sp) # 8-byte Folded Reload
162; RV64I-NEXT:    ld s0, 2016(sp) # 8-byte Folded Reload
163; RV64I-NEXT:    .cfi_restore ra
164; RV64I-NEXT:    .cfi_restore s0
165; RV64I-NEXT:    addi sp, sp, 2032
166; RV64I-NEXT:    .cfi_def_cfa_offset 0
167; RV64I-NEXT:    ret
168
169  %va = alloca [2500 x i8], align 4
170  %va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 552
171  %load = load volatile i8, ptr %va_gep, align 4
172  store volatile i8 %load, ptr %va_gep, align 4
173  ret void
174}
175