1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s --check-prefix=RV32
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s --check-prefix=RV64
6 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfiss < %s \
7 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=RV32-ZICFISS
8 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfiss < %s \
9 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=RV64-ZICFISS
10 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfiss,forced-sw-shadow-stack \
11 ; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV32
12 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfiss,forced-sw-shadow-stack \
13 ; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64
15 define void @f1() shadowcallstack {
24 ; RV32-ZICFISS-LABEL: f1:
25 ; RV32-ZICFISS: # %bb.0:
26 ; RV32-ZICFISS-NEXT: ret
28 ; RV64-ZICFISS-LABEL: f1:
29 ; RV64-ZICFISS: # %bb.0:
30 ; RV64-ZICFISS-NEXT: ret
36 define void @f2() shadowcallstack {
45 ; RV32-ZICFISS-LABEL: f2:
46 ; RV32-ZICFISS: # %bb.0:
47 ; RV32-ZICFISS-NEXT: tail foo
49 ; RV64-ZICFISS-LABEL: f2:
50 ; RV64-ZICFISS: # %bb.0:
51 ; RV64-ZICFISS-NEXT: tail foo
58 define i32 @f3() shadowcallstack {
61 ; RV32-NEXT: addi gp, gp, 4
62 ; RV32-NEXT: sw ra, -4(gp)
63 ; RV32-NEXT: .cfi_escape 0x16, 0x03, 0x02, 0x73, 0x7c #
64 ; RV32-NEXT: addi sp, sp, -16
65 ; RV32-NEXT: .cfi_def_cfa_offset 16
66 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
67 ; RV32-NEXT: .cfi_offset ra, -4
69 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
70 ; RV32-NEXT: addi sp, sp, 16
71 ; RV32-NEXT: lw ra, -4(gp)
72 ; RV32-NEXT: addi gp, gp, -4
73 ; RV32-NEXT: .cfi_restore gp
78 ; RV64-NEXT: addi gp, gp, 8
79 ; RV64-NEXT: sd ra, -8(gp)
80 ; RV64-NEXT: .cfi_escape 0x16, 0x03, 0x02, 0x73, 0x78 #
81 ; RV64-NEXT: addi sp, sp, -16
82 ; RV64-NEXT: .cfi_def_cfa_offset 16
83 ; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
84 ; RV64-NEXT: .cfi_offset ra, -8
86 ; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
87 ; RV64-NEXT: addi sp, sp, 16
88 ; RV64-NEXT: ld ra, -8(gp)
89 ; RV64-NEXT: addi gp, gp, -8
90 ; RV64-NEXT: .cfi_restore gp
93 ; RV32-ZICFISS-LABEL: f3:
94 ; RV32-ZICFISS: # %bb.0:
95 ; RV32-ZICFISS-NEXT: sspush ra
96 ; RV32-ZICFISS-NEXT: addi sp, sp, -16
97 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
98 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
99 ; RV32-ZICFISS-NEXT: .cfi_offset ra, -4
100 ; RV32-ZICFISS-NEXT: call bar
101 ; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
102 ; RV32-ZICFISS-NEXT: addi sp, sp, 16
103 ; RV32-ZICFISS-NEXT: sspopchk ra
104 ; RV32-ZICFISS-NEXT: ret
106 ; RV64-ZICFISS-LABEL: f3:
107 ; RV64-ZICFISS: # %bb.0:
108 ; RV64-ZICFISS-NEXT: sspush ra
109 ; RV64-ZICFISS-NEXT: addi sp, sp, -16
110 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 16
111 ; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
112 ; RV64-ZICFISS-NEXT: .cfi_offset ra, -8
113 ; RV64-ZICFISS-NEXT: call bar
114 ; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
115 ; RV64-ZICFISS-NEXT: addi sp, sp, 16
116 ; RV64-ZICFISS-NEXT: sspopchk ra
117 ; RV64-ZICFISS-NEXT: ret
118 %res = call i32 @bar()
119 %res1 = add i32 %res, 1
123 define i32 @f4() shadowcallstack {
126 ; RV32-NEXT: addi gp, gp, 4
127 ; RV32-NEXT: sw ra, -4(gp)
128 ; RV32-NEXT: .cfi_escape 0x16, 0x03, 0x02, 0x73, 0x7c #
129 ; RV32-NEXT: addi sp, sp, -16
130 ; RV32-NEXT: .cfi_def_cfa_offset 16
131 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
132 ; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
133 ; RV32-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
134 ; RV32-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
135 ; RV32-NEXT: .cfi_offset ra, -4
136 ; RV32-NEXT: .cfi_offset s0, -8
137 ; RV32-NEXT: .cfi_offset s1, -12
138 ; RV32-NEXT: .cfi_offset s2, -16
139 ; RV32-NEXT: call bar
140 ; RV32-NEXT: mv s0, a0
141 ; RV32-NEXT: call bar
142 ; RV32-NEXT: mv s1, a0
143 ; RV32-NEXT: call bar
144 ; RV32-NEXT: mv s2, a0
145 ; RV32-NEXT: call bar
146 ; RV32-NEXT: add s0, s0, s1
147 ; RV32-NEXT: add a0, s2, a0
148 ; RV32-NEXT: add a0, s0, a0
149 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
150 ; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
151 ; RV32-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
152 ; RV32-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
153 ; RV32-NEXT: addi sp, sp, 16
154 ; RV32-NEXT: lw ra, -4(gp)
155 ; RV32-NEXT: addi gp, gp, -4
156 ; RV32-NEXT: .cfi_restore gp
161 ; RV64-NEXT: addi gp, gp, 8
162 ; RV64-NEXT: sd ra, -8(gp)
163 ; RV64-NEXT: .cfi_escape 0x16, 0x03, 0x02, 0x73, 0x78 #
164 ; RV64-NEXT: addi sp, sp, -32
165 ; RV64-NEXT: .cfi_def_cfa_offset 32
166 ; RV64-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
167 ; RV64-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
168 ; RV64-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
169 ; RV64-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
170 ; RV64-NEXT: .cfi_offset ra, -8
171 ; RV64-NEXT: .cfi_offset s0, -16
172 ; RV64-NEXT: .cfi_offset s1, -24
173 ; RV64-NEXT: .cfi_offset s2, -32
174 ; RV64-NEXT: call bar
175 ; RV64-NEXT: mv s0, a0
176 ; RV64-NEXT: call bar
177 ; RV64-NEXT: mv s1, a0
178 ; RV64-NEXT: call bar
179 ; RV64-NEXT: mv s2, a0
180 ; RV64-NEXT: call bar
181 ; RV64-NEXT: add s0, s0, s1
182 ; RV64-NEXT: add a0, s2, a0
183 ; RV64-NEXT: addw a0, s0, a0
184 ; RV64-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
185 ; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
186 ; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
187 ; RV64-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
188 ; RV64-NEXT: addi sp, sp, 32
189 ; RV64-NEXT: ld ra, -8(gp)
190 ; RV64-NEXT: addi gp, gp, -8
191 ; RV64-NEXT: .cfi_restore gp
194 ; RV32-ZICFISS-LABEL: f4:
195 ; RV32-ZICFISS: # %bb.0:
196 ; RV32-ZICFISS-NEXT: sspush ra
197 ; RV32-ZICFISS-NEXT: addi sp, sp, -16
198 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
199 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
200 ; RV32-ZICFISS-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
201 ; RV32-ZICFISS-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
202 ; RV32-ZICFISS-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
203 ; RV32-ZICFISS-NEXT: .cfi_offset ra, -4
204 ; RV32-ZICFISS-NEXT: .cfi_offset s0, -8
205 ; RV32-ZICFISS-NEXT: .cfi_offset s1, -12
206 ; RV32-ZICFISS-NEXT: .cfi_offset s2, -16
207 ; RV32-ZICFISS-NEXT: call bar
208 ; RV32-ZICFISS-NEXT: mv s0, a0
209 ; RV32-ZICFISS-NEXT: call bar
210 ; RV32-ZICFISS-NEXT: mv s1, a0
211 ; RV32-ZICFISS-NEXT: call bar
212 ; RV32-ZICFISS-NEXT: mv s2, a0
213 ; RV32-ZICFISS-NEXT: call bar
214 ; RV32-ZICFISS-NEXT: add s0, s0, s1
215 ; RV32-ZICFISS-NEXT: add a0, s2, a0
216 ; RV32-ZICFISS-NEXT: add a0, s0, a0
217 ; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
218 ; RV32-ZICFISS-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
219 ; RV32-ZICFISS-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
220 ; RV32-ZICFISS-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
221 ; RV32-ZICFISS-NEXT: addi sp, sp, 16
222 ; RV32-ZICFISS-NEXT: sspopchk ra
223 ; RV32-ZICFISS-NEXT: ret
225 ; RV64-ZICFISS-LABEL: f4:
226 ; RV64-ZICFISS: # %bb.0:
227 ; RV64-ZICFISS-NEXT: sspush ra
228 ; RV64-ZICFISS-NEXT: addi sp, sp, -32
229 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 32
230 ; RV64-ZICFISS-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
231 ; RV64-ZICFISS-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
232 ; RV64-ZICFISS-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
233 ; RV64-ZICFISS-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
234 ; RV64-ZICFISS-NEXT: .cfi_offset ra, -8
235 ; RV64-ZICFISS-NEXT: .cfi_offset s0, -16
236 ; RV64-ZICFISS-NEXT: .cfi_offset s1, -24
237 ; RV64-ZICFISS-NEXT: .cfi_offset s2, -32
238 ; RV64-ZICFISS-NEXT: call bar
239 ; RV64-ZICFISS-NEXT: mv s0, a0
240 ; RV64-ZICFISS-NEXT: call bar
241 ; RV64-ZICFISS-NEXT: mv s1, a0
242 ; RV64-ZICFISS-NEXT: call bar
243 ; RV64-ZICFISS-NEXT: mv s2, a0
244 ; RV64-ZICFISS-NEXT: call bar
245 ; RV64-ZICFISS-NEXT: add s0, s0, s1
246 ; RV64-ZICFISS-NEXT: add a0, s2, a0
247 ; RV64-ZICFISS-NEXT: addw a0, s0, a0
248 ; RV64-ZICFISS-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
249 ; RV64-ZICFISS-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
250 ; RV64-ZICFISS-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
251 ; RV64-ZICFISS-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
252 ; RV64-ZICFISS-NEXT: addi sp, sp, 32
253 ; RV64-ZICFISS-NEXT: sspopchk ra
254 ; RV64-ZICFISS-NEXT: ret
255 %res1 = call i32 @bar()
256 %res2 = call i32 @bar()
257 %res3 = call i32 @bar()
258 %res4 = call i32 @bar()
259 %res12 = add i32 %res1, %res2
260 %res34 = add i32 %res3, %res4
261 %res1234 = add i32 %res12, %res34
265 define i32 @f5() shadowcallstack nounwind {
268 ; RV32-NEXT: addi gp, gp, 4
269 ; RV32-NEXT: sw ra, -4(gp)
270 ; RV32-NEXT: addi sp, sp, -16
271 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
272 ; RV32-NEXT: call bar
273 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
274 ; RV32-NEXT: addi sp, sp, 16
275 ; RV32-NEXT: lw ra, -4(gp)
276 ; RV32-NEXT: addi gp, gp, -4
281 ; RV64-NEXT: addi gp, gp, 8
282 ; RV64-NEXT: sd ra, -8(gp)
283 ; RV64-NEXT: addi sp, sp, -16
284 ; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
285 ; RV64-NEXT: call bar
286 ; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
287 ; RV64-NEXT: addi sp, sp, 16
288 ; RV64-NEXT: ld ra, -8(gp)
289 ; RV64-NEXT: addi gp, gp, -8
292 ; RV32-ZICFISS-LABEL: f5:
293 ; RV32-ZICFISS: # %bb.0:
294 ; RV32-ZICFISS-NEXT: sspush ra
295 ; RV32-ZICFISS-NEXT: addi sp, sp, -16
296 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
297 ; RV32-ZICFISS-NEXT: call bar
298 ; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
299 ; RV32-ZICFISS-NEXT: addi sp, sp, 16
300 ; RV32-ZICFISS-NEXT: sspopchk ra
301 ; RV32-ZICFISS-NEXT: ret
303 ; RV64-ZICFISS-LABEL: f5:
304 ; RV64-ZICFISS: # %bb.0:
305 ; RV64-ZICFISS-NEXT: sspush ra
306 ; RV64-ZICFISS-NEXT: addi sp, sp, -16
307 ; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
308 ; RV64-ZICFISS-NEXT: call bar
309 ; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
310 ; RV64-ZICFISS-NEXT: addi sp, sp, 16
311 ; RV64-ZICFISS-NEXT: sspopchk ra
312 ; RV64-ZICFISS-NEXT: ret
313 %res = call i32 @bar()
314 %res1 = add i32 %res, 1