xref: /llvm-project/llvm/test/CodeGen/RISCV/lpad.ll (revision 97982a8c605fac7c86d02e641a6cd7898b3ca343)
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
8
9; Check indirectbr.
10@__const.indirctbr.addr = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@indirctbr, %labelA), ptr blockaddress(@indirctbr, %labelB)], align 8
11define void @indirctbr(i32 %i, ptr %p) {
12; RV32-LABEL: indirctbr:
13; RV32:       # %bb.0: # %entry
14; RV32-NEXT:    lpad 0
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)
20; RV32-NEXT:    jr a0
21; RV32-NEXT:    .p2align 2
22; RV32-NEXT:  .Ltmp3: # Block address taken
23; RV32-NEXT:  .LBB0_1: # %labelA
24; RV32-NEXT:    lpad 0
25; RV32-NEXT:    li a0, 1
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
30; RV32-NEXT:    lpad 0
31; RV32-NEXT:    li a0, 2
32; RV32-NEXT:    sw a0, 0(a1)
33; RV32-NEXT:    ret
34;
35; RV64-LABEL: indirctbr:
36; RV64:       # %bb.0: # %entry
37; RV64-NEXT:    lpad 0
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)
44; RV64-NEXT:    jr a0
45; RV64-NEXT:    .p2align 2
46; RV64-NEXT:  .Ltmp3: # Block address taken
47; RV64-NEXT:  .LBB0_1: # %labelA
48; RV64-NEXT:    lpad 0
49; RV64-NEXT:    li a0, 1
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
54; RV64-NEXT:    lpad 0
55; RV64-NEXT:    li a0, 2
56; RV64-NEXT:    sw a0, 0(a1)
57; RV64-NEXT:    ret
58;
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
82;
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
107entry:
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]
111
112labelA:                                           ; preds = %entry
113  store volatile i32 1, ptr %p
114  br label %labelB
115
116labelB:                                           ; preds = %labelA, %entry
117  store volatile i32 2, ptr %p
118  ret void
119}
120
121; Check indirect call.
122define void @call(ptr %0) {
123; CHECK-LABEL: call:
124; CHECK:       # %bb.0:
125; CHECK-NEXT:    lpad 0
126; CHECK-NEXT:    jr a0
127;
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
133  tail call void %0()
134  ret void
135}
136
137; Check invoke.
138declare dso_local i32 @__gxx_personality_v0(...)
139define void @invoke(ptr %f) personality ptr @__gxx_personality_v0 {
140; RV32-LABEL: invoke:
141; RV32:       # %bb.0: # %entry
142; RV32-NEXT:    lpad 0
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
148; RV32-NEXT:  .Ltmp0:
149; RV32-NEXT:    jalr a0
150; RV32-NEXT:  .Ltmp1:
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
156; RV32-NEXT:    ret
157; RV32-NEXT:  .LBB2_2: # %lpad
158; RV32-NEXT:    .cfi_restore_state
159; RV32-NEXT:  .Ltmp2:
160; RV32-NEXT:    j .LBB2_1
161;
162; RV64-LABEL: invoke:
163; RV64:       # %bb.0: # %entry
164; RV64-NEXT:    lpad 0
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
170; RV64-NEXT:  .Ltmp0:
171; RV64-NEXT:    jalr a0
172; RV64-NEXT:  .Ltmp1:
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
178; RV64-NEXT:    ret
179; RV64-NEXT:  .LBB2_2: # %lpad
180; RV64-NEXT:    .cfi_restore_state
181; RV64-NEXT:  .Ltmp2:
182; RV64-NEXT:    j .LBB2_1
183;
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
206;
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
229entry:
230  invoke void %f() to label %try.cont unwind label %lpad
231
232lpad:
233  %0 = landingpad { ptr, i32 } cleanup
234  br label %try.cont
235
236try.cont:
237  ret void
238}
239
240; Check external linkage function.
241define void @external() {
242; CHECK-LABEL: external:
243; CHECK:       # %bb.0:
244; CHECK-NEXT:    lpad 0
245; CHECK-NEXT:    ret
246;
247; FIXED-ONE-LABEL: external:
248; FIXED-ONE:       # %bb.0:
249; FIXED-ONE-NEXT:    lpad 1
250; FIXED-ONE-NEXT:    ret
251  ret void
252}
253
254; Check internal linkage function.
255define internal void @internal() {
256; CHECK-LABEL: internal:
257; CHECK:       # %bb.0:
258; CHECK-NEXT:    ret
259;
260; FIXED-ONE-LABEL: internal:
261; FIXED-ONE:       # %bb.0:
262; FIXED-ONE-NEXT:    ret
263  ret void
264}
265
266; Check internal linkage function with taken address.
267@foo = constant ptr @internal2
268define internal void @internal2() {
269; CHECK-LABEL: internal2:
270; CHECK:       # %bb.0:
271; CHECK-NEXT:    lpad 0
272; CHECK-NEXT:    ret
273;
274; FIXED-ONE-LABEL: internal2:
275; FIXED-ONE:       # %bb.0:
276; FIXED-ONE-NEXT:    lpad 1
277; FIXED-ONE-NEXT:    ret
278  ret void
279}
280
281; Check interrupt function does not need landing pad.
282define void @interrupt() "interrupt"="user" {
283; CHECK-LABEL: interrupt:
284; CHECK:       # %bb.0:
285; CHECK-NEXT:    mret
286;
287; FIXED-ONE-LABEL: interrupt:
288; FIXED-ONE:       # %bb.0:
289; FIXED-ONE-NEXT:    mret
290  ret void
291}
292