1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple riscv32 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV32
3 ; RUN: llc -mtriple riscv64 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV64
4 ; RUN: llc -mtriple riscv32 -mattr=+experimental-zicfilp \
5 ; RUN: -riscv-landing-pad-label=1 < %s | FileCheck %s --check-prefixes=FIXED-ONE,FIXED-ONE-RV32
6 ; RUN: llc -mtriple riscv64 -mattr=+experimental-zicfilp \
7 ; RUN: -riscv-landing-pad-label=1 < %s | FileCheck %s --check-prefixes=FIXED-ONE,FIXED-ONE-RV64
10 @__const.indirctbr.addr = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@indirctbr, %labelA), ptr blockaddress(@indirctbr, %labelB)], align 8
11 define void @indirctbr(i32 %i, ptr %p) {
12 ; RV32-LABEL: indirctbr:
13 ; RV32: # %bb.0: # %entry
15 ; RV32-NEXT: slli a0, a0, 2
16 ; RV32-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
17 ; RV32-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
18 ; RV32-NEXT: add a0, a2, a0
19 ; RV32-NEXT: lw a0, 0(a0)
21 ; RV32-NEXT: .p2align 2
22 ; RV32-NEXT: .Ltmp3: # Block address taken
23 ; RV32-NEXT: .LBB0_1: # %labelA
26 ; RV32-NEXT: sw a0, 0(a1)
27 ; RV32-NEXT: .p2align 2
28 ; RV32-NEXT: .Ltmp4: # Block address taken
29 ; RV32-NEXT: .LBB0_2: # %labelB
32 ; RV32-NEXT: sw a0, 0(a1)
35 ; RV64-LABEL: indirctbr:
36 ; RV64: # %bb.0: # %entry
38 ; RV64-NEXT: sext.w a0, a0
39 ; RV64-NEXT: slli a0, a0, 3
40 ; RV64-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
41 ; RV64-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
42 ; RV64-NEXT: add a0, a2, a0
43 ; RV64-NEXT: ld a0, 0(a0)
45 ; RV64-NEXT: .p2align 2
46 ; RV64-NEXT: .Ltmp3: # Block address taken
47 ; RV64-NEXT: .LBB0_1: # %labelA
50 ; RV64-NEXT: sw a0, 0(a1)
51 ; RV64-NEXT: .p2align 2
52 ; RV64-NEXT: .Ltmp4: # Block address taken
53 ; RV64-NEXT: .LBB0_2: # %labelB
56 ; RV64-NEXT: sw a0, 0(a1)
59 ; FIXED-ONE-RV32-LABEL: indirctbr:
60 ; FIXED-ONE-RV32: # %bb.0: # %entry
61 ; FIXED-ONE-RV32-NEXT: lpad 1
62 ; FIXED-ONE-RV32-NEXT: slli a0, a0, 2
63 ; FIXED-ONE-RV32-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
64 ; FIXED-ONE-RV32-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
65 ; FIXED-ONE-RV32-NEXT: add a0, a2, a0
66 ; FIXED-ONE-RV32-NEXT: lw a0, 0(a0)
67 ; FIXED-ONE-RV32-NEXT: lui t2, 1
68 ; FIXED-ONE-RV32-NEXT: jr a0
69 ; FIXED-ONE-RV32-NEXT: .p2align 2
70 ; FIXED-ONE-RV32-NEXT: .Ltmp3: # Block address taken
71 ; FIXED-ONE-RV32-NEXT: .LBB0_1: # %labelA
72 ; FIXED-ONE-RV32-NEXT: lpad 1
73 ; FIXED-ONE-RV32-NEXT: li a0, 1
74 ; FIXED-ONE-RV32-NEXT: sw a0, 0(a1)
75 ; FIXED-ONE-RV32-NEXT: .p2align 2
76 ; FIXED-ONE-RV32-NEXT: .Ltmp4: # Block address taken
77 ; FIXED-ONE-RV32-NEXT: .LBB0_2: # %labelB
78 ; FIXED-ONE-RV32-NEXT: lpad 1
79 ; FIXED-ONE-RV32-NEXT: li a0, 2
80 ; FIXED-ONE-RV32-NEXT: sw a0, 0(a1)
81 ; FIXED-ONE-RV32-NEXT: ret
83 ; FIXED-ONE-RV64-LABEL: indirctbr:
84 ; FIXED-ONE-RV64: # %bb.0: # %entry
85 ; FIXED-ONE-RV64-NEXT: lpad 1
86 ; FIXED-ONE-RV64-NEXT: sext.w a0, a0
87 ; FIXED-ONE-RV64-NEXT: slli a0, a0, 3
88 ; FIXED-ONE-RV64-NEXT: lui a2, %hi(.L__const.indirctbr.addr)
89 ; FIXED-ONE-RV64-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr)
90 ; FIXED-ONE-RV64-NEXT: add a0, a2, a0
91 ; FIXED-ONE-RV64-NEXT: ld a0, 0(a0)
92 ; FIXED-ONE-RV64-NEXT: lui t2, 1
93 ; FIXED-ONE-RV64-NEXT: jr a0
94 ; FIXED-ONE-RV64-NEXT: .p2align 2
95 ; FIXED-ONE-RV64-NEXT: .Ltmp3: # Block address taken
96 ; FIXED-ONE-RV64-NEXT: .LBB0_1: # %labelA
97 ; FIXED-ONE-RV64-NEXT: lpad 1
98 ; FIXED-ONE-RV64-NEXT: li a0, 1
99 ; FIXED-ONE-RV64-NEXT: sw a0, 0(a1)
100 ; FIXED-ONE-RV64-NEXT: .p2align 2
101 ; FIXED-ONE-RV64-NEXT: .Ltmp4: # Block address taken
102 ; FIXED-ONE-RV64-NEXT: .LBB0_2: # %labelB
103 ; FIXED-ONE-RV64-NEXT: lpad 1
104 ; FIXED-ONE-RV64-NEXT: li a0, 2
105 ; FIXED-ONE-RV64-NEXT: sw a0, 0(a1)
106 ; FIXED-ONE-RV64-NEXT: ret
108 %arrayidx = getelementptr inbounds [2 x ptr], ptr @__const.indirctbr.addr, i64 0, i32 %i
109 %0 = load ptr, ptr %arrayidx
110 indirectbr ptr %0, [label %labelA, label %labelB]
112 labelA: ; preds = %entry
113 store volatile i32 1, ptr %p
116 labelB: ; preds = %labelA, %entry
117 store volatile i32 2, ptr %p
121 ; Check indirect call.
122 define void @call(ptr %0) {
128 ; FIXED-ONE-LABEL: call:
129 ; FIXED-ONE: # %bb.0:
130 ; FIXED-ONE-NEXT: lpad 1
131 ; FIXED-ONE-NEXT: lui t2, 1
132 ; FIXED-ONE-NEXT: jr a0
138 declare dso_local i32 @__gxx_personality_v0(...)
139 define void @invoke(ptr %f) personality ptr @__gxx_personality_v0 {
140 ; RV32-LABEL: invoke:
141 ; RV32: # %bb.0: # %entry
143 ; RV32-NEXT: addi sp, sp, -16
144 ; RV32-NEXT: .cfi_def_cfa_offset 16
145 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
146 ; RV32-NEXT: .cfi_offset ra, -4
147 ; RV32-NEXT: .cfi_remember_state
151 ; RV32-NEXT: .LBB2_1: # %try.cont
152 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
153 ; RV32-NEXT: .cfi_restore ra
154 ; RV32-NEXT: addi sp, sp, 16
155 ; RV32-NEXT: .cfi_def_cfa_offset 0
157 ; RV32-NEXT: .LBB2_2: # %lpad
158 ; RV32-NEXT: .cfi_restore_state
160 ; RV32-NEXT: j .LBB2_1
162 ; RV64-LABEL: invoke:
163 ; RV64: # %bb.0: # %entry
165 ; RV64-NEXT: addi sp, sp, -16
166 ; RV64-NEXT: .cfi_def_cfa_offset 16
167 ; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
168 ; RV64-NEXT: .cfi_offset ra, -8
169 ; RV64-NEXT: .cfi_remember_state
173 ; RV64-NEXT: .LBB2_1: # %try.cont
174 ; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
175 ; RV64-NEXT: .cfi_restore ra
176 ; RV64-NEXT: addi sp, sp, 16
177 ; RV64-NEXT: .cfi_def_cfa_offset 0
179 ; RV64-NEXT: .LBB2_2: # %lpad
180 ; RV64-NEXT: .cfi_restore_state
182 ; RV64-NEXT: j .LBB2_1
184 ; FIXED-ONE-RV32-LABEL: invoke:
185 ; FIXED-ONE-RV32: # %bb.0: # %entry
186 ; FIXED-ONE-RV32-NEXT: lpad 1
187 ; FIXED-ONE-RV32-NEXT: addi sp, sp, -16
188 ; FIXED-ONE-RV32-NEXT: .cfi_def_cfa_offset 16
189 ; FIXED-ONE-RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
190 ; FIXED-ONE-RV32-NEXT: .cfi_offset ra, -4
191 ; FIXED-ONE-RV32-NEXT: .cfi_remember_state
192 ; FIXED-ONE-RV32-NEXT: .Ltmp0:
193 ; FIXED-ONE-RV32-NEXT: lui t2, 1
194 ; FIXED-ONE-RV32-NEXT: jalr a0
195 ; FIXED-ONE-RV32-NEXT: .Ltmp1:
196 ; FIXED-ONE-RV32-NEXT: .LBB2_1: # %try.cont
197 ; FIXED-ONE-RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
198 ; FIXED-ONE-RV32-NEXT: .cfi_restore ra
199 ; FIXED-ONE-RV32-NEXT: addi sp, sp, 16
200 ; FIXED-ONE-RV32-NEXT: .cfi_def_cfa_offset 0
201 ; FIXED-ONE-RV32-NEXT: ret
202 ; FIXED-ONE-RV32-NEXT: .LBB2_2: # %lpad
203 ; FIXED-ONE-RV32-NEXT: .cfi_restore_state
204 ; FIXED-ONE-RV32-NEXT: .Ltmp2:
205 ; FIXED-ONE-RV32-NEXT: j .LBB2_1
207 ; FIXED-ONE-RV64-LABEL: invoke:
208 ; FIXED-ONE-RV64: # %bb.0: # %entry
209 ; FIXED-ONE-RV64-NEXT: lpad 1
210 ; FIXED-ONE-RV64-NEXT: addi sp, sp, -16
211 ; FIXED-ONE-RV64-NEXT: .cfi_def_cfa_offset 16
212 ; FIXED-ONE-RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
213 ; FIXED-ONE-RV64-NEXT: .cfi_offset ra, -8
214 ; FIXED-ONE-RV64-NEXT: .cfi_remember_state
215 ; FIXED-ONE-RV64-NEXT: .Ltmp0:
216 ; FIXED-ONE-RV64-NEXT: lui t2, 1
217 ; FIXED-ONE-RV64-NEXT: jalr a0
218 ; FIXED-ONE-RV64-NEXT: .Ltmp1:
219 ; FIXED-ONE-RV64-NEXT: .LBB2_1: # %try.cont
220 ; FIXED-ONE-RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
221 ; FIXED-ONE-RV64-NEXT: .cfi_restore ra
222 ; FIXED-ONE-RV64-NEXT: addi sp, sp, 16
223 ; FIXED-ONE-RV64-NEXT: .cfi_def_cfa_offset 0
224 ; FIXED-ONE-RV64-NEXT: ret
225 ; FIXED-ONE-RV64-NEXT: .LBB2_2: # %lpad
226 ; FIXED-ONE-RV64-NEXT: .cfi_restore_state
227 ; FIXED-ONE-RV64-NEXT: .Ltmp2:
228 ; FIXED-ONE-RV64-NEXT: j .LBB2_1
230 invoke void %f() to label %try.cont unwind label %lpad
233 %0 = landingpad { ptr, i32 } cleanup
240 ; Check external linkage function.
241 define void @external() {
242 ; CHECK-LABEL: external:
247 ; FIXED-ONE-LABEL: external:
248 ; FIXED-ONE: # %bb.0:
249 ; FIXED-ONE-NEXT: lpad 1
250 ; FIXED-ONE-NEXT: ret
254 ; Check internal linkage function.
255 define internal void @internal() {
256 ; CHECK-LABEL: internal:
260 ; FIXED-ONE-LABEL: internal:
261 ; FIXED-ONE: # %bb.0:
262 ; FIXED-ONE-NEXT: ret
266 ; Check internal linkage function with taken address.
267 @foo = constant ptr @internal2
268 define internal void @internal2() {
269 ; CHECK-LABEL: internal2:
274 ; FIXED-ONE-LABEL: internal2:
275 ; FIXED-ONE: # %bb.0:
276 ; FIXED-ONE-NEXT: lpad 1
277 ; FIXED-ONE-NEXT: ret
281 ; Check interrupt function does not need landing pad.
282 define void @interrupt() "interrupt"="user" {
283 ; CHECK-LABEL: interrupt:
287 ; FIXED-ONE-LABEL: interrupt:
288 ; FIXED-ONE: # %bb.0:
289 ; FIXED-ONE-NEXT: mret