Skip to content

Commit e8fb5c6

Browse files
jaidTwSterling-Augustine
authored andcommitted
[RISCV] Software guard direct calls in large code model (llvm#109377)
Support for large code model are added recently, and sementically direct calls are lowered to an indirect branch with a constant pool target. By default it does not use the x7 register and this is suboptimal with Zicfilp because it introduces landing pad check, which is unnecessary since the constant pool is read-only and unlikely to be tampered. Change direct calls and tail calls to use x7 as the scratch register (a.k.a. software guarded branch in the CFI spec)
1 parent 3238a12 commit e8fb5c6

File tree

5 files changed

+470
-9
lines changed

5 files changed

+470
-9
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19752,11 +19752,14 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
1975219752
// If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
1975319753
// TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
1975419754
// split it and then direct call can be matched by PseudoCALL.
19755+
bool CalleeIsLargeExternalSymbol = false;
1975519756
if (getTargetMachine().getCodeModel() == CodeModel::Large) {
1975619757
if (auto *S = dyn_cast<GlobalAddressSDNode>(Callee))
1975719758
Callee = getLargeGlobalAddress(S, DL, PtrVT, DAG);
19758-
else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee))
19759+
else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1975919760
Callee = getLargeExternalSymbol(S, DL, PtrVT, DAG);
19761+
CalleeIsLargeExternalSymbol = true;
19762+
}
1976019763
} else if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
1976119764
const GlobalValue *GV = S->getGlobal();
1976219765
Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, RISCVII::MO_CALL);
@@ -19792,16 +19795,28 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
1979219795
// Emit the call.
1979319796
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1979419797

19798+
// Use software guarded branch for large code model non-indirect calls
19799+
// Tail call to external symbol will have a null CLI.CB and we need another
19800+
// way to determine the callsite type
19801+
bool NeedSWGuarded = false;
19802+
if (getTargetMachine().getCodeModel() == CodeModel::Large &&
19803+
Subtarget.hasStdExtZicfilp() &&
19804+
((CLI.CB && !CLI.CB->isIndirectCall()) || CalleeIsLargeExternalSymbol))
19805+
NeedSWGuarded = true;
19806+
1979519807
if (IsTailCall) {
1979619808
MF.getFrameInfo().setHasTailCall();
19797-
SDValue Ret = DAG.getNode(RISCVISD::TAIL, DL, NodeTys, Ops);
19809+
unsigned CallOpc =
19810+
NeedSWGuarded ? RISCVISD::SW_GUARDED_TAIL : RISCVISD::TAIL;
19811+
SDValue Ret = DAG.getNode(CallOpc, DL, NodeTys, Ops);
1979819812
if (CLI.CFIType)
1979919813
Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
1980019814
DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
1980119815
return Ret;
1980219816
}
1980319817

19804-
Chain = DAG.getNode(RISCVISD::CALL, DL, NodeTys, Ops);
19818+
unsigned CallOpc = NeedSWGuarded ? RISCVISD::SW_GUARDED_CALL : RISCVISD::CALL;
19819+
Chain = DAG.getNode(CallOpc, DL, NodeTys, Ops);
1980519820
if (CLI.CFIType)
1980619821
Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
1980719822
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
@@ -20249,6 +20264,8 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
2024920264
NODE_NAME_CASE(CZERO_EQZ)
2025020265
NODE_NAME_CASE(CZERO_NEZ)
2025120266
NODE_NAME_CASE(SW_GUARDED_BRIND)
20267+
NODE_NAME_CASE(SW_GUARDED_CALL)
20268+
NODE_NAME_CASE(SW_GUARDED_TAIL)
2025220269
NODE_NAME_CASE(TUPLE_INSERT)
2025320270
NODE_NAME_CASE(TUPLE_EXTRACT)
2025420271
NODE_NAME_CASE(SF_VC_XV_SE)

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,12 @@ enum NodeType : unsigned {
411411
CZERO_EQZ, // vt.maskc for XVentanaCondOps.
412412
CZERO_NEZ, // vt.maskcn for XVentanaCondOps.
413413

414-
/// Software guarded BRIND node. Operand 0 is the chain operand and
415-
/// operand 1 is the target address.
414+
// Software guarded BRIND node. Operand 0 is the chain operand and
415+
// operand 1 is the target address.
416416
SW_GUARDED_BRIND,
417+
// Software guarded calls for large code model
418+
SW_GUARDED_CALL,
419+
SW_GUARDED_TAIL,
417420

418421
SF_VC_XV_SE,
419422
SF_VC_IV_SE,

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
5757
def riscv_call : SDNode<"RISCVISD::CALL", SDT_RISCVCall,
5858
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
5959
SDNPVariadic]>;
60+
def riscv_sw_guarded_call : SDNode<"RISCVISD::SW_GUARDED_CALL", SDT_RISCVCall,
61+
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
62+
SDNPVariadic]>;
6063
def riscv_ret_glue : SDNode<"RISCVISD::RET_GLUE", SDTNone,
6164
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
6265
def riscv_sret_glue : SDNode<"RISCVISD::SRET_GLUE", SDTNone,
@@ -69,6 +72,9 @@ def riscv_brcc : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC,
6972
def riscv_tail : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
7073
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
7174
SDNPVariadic]>;
75+
def riscv_sw_guarded_tail : SDNode<"RISCVISD::SW_GUARDED_TAIL", SDT_RISCVCall,
76+
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
77+
SDNPVariadic]>;
7278
def riscv_sw_guarded_brind : SDNode<"RISCVISD::SW_GUARDED_BRIND",
7379
SDTBrind, [SDNPHasChain]>;
7480
def riscv_sllw : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
@@ -1555,10 +1561,15 @@ let Predicates = [NoStdExtZicfilp] in
15551561
def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1),
15561562
[(riscv_call GPRJALR:$rs1)]>,
15571563
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
1558-
let Predicates = [HasStdExtZicfilp] in
1564+
let Predicates = [HasStdExtZicfilp] in {
15591565
def PseudoCALLIndirectNonX7 : Pseudo<(outs), (ins GPRJALRNonX7:$rs1),
15601566
[(riscv_call GPRJALRNonX7:$rs1)]>,
15611567
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
1568+
// For large code model, non-indirect calls could be software-guarded
1569+
def PseudoCALLIndirectX7 : Pseudo<(outs), (ins GPRX7:$rs1),
1570+
[(riscv_sw_guarded_call GPRX7:$rs1)]>,
1571+
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
1572+
}
15621573
}
15631574

15641575
let isBarrier = 1, isReturn = 1, isTerminator = 1 in
@@ -1579,10 +1590,15 @@ let Predicates = [NoStdExtZicfilp] in
15791590
def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),
15801591
[(riscv_tail GPRTC:$rs1)]>,
15811592
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
1582-
let Predicates = [HasStdExtZicfilp] in
1593+
let Predicates = [HasStdExtZicfilp] in {
15831594
def PseudoTAILIndirectNonX7 : Pseudo<(outs), (ins GPRTCNonX7:$rs1),
15841595
[(riscv_tail GPRTCNonX7:$rs1)]>,
15851596
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
1597+
// For large code model, non-indirect calls could be software-guarded
1598+
def PseudoTAILIndirectX7 : Pseudo<(outs), (ins GPRX7:$rs1),
1599+
[(riscv_sw_guarded_tail GPRX7:$rs1)]>,
1600+
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
1601+
}
15861602
}
15871603

15881604
def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),

llvm/test/CodeGen/RISCV/calls.ll

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
; RUN: | FileCheck -check-prefix=RV64I-MEDIUM %s
1212
; RUN: llc -code-model=large -mtriple=riscv64 -verify-machineinstrs < %s \
1313
; RUN: | FileCheck -check-prefix=RV64I-LARGE %s
14+
; RUN: llc -code-model=large -mtriple=riscv64 -mattr=experimental-zicfilp -verify-machineinstrs < %s \
15+
; RUN: | FileCheck -check-prefix=RV64I-LARGE-ZICFILP %s
1416

1517
declare i32 @external_function(i32)
1618

@@ -62,6 +64,19 @@ define i32 @test_call_external(i32 %a) nounwind {
6264
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
6365
; RV64I-LARGE-NEXT: addi sp, sp, 16
6466
; RV64I-LARGE-NEXT: ret
67+
;
68+
; RV64I-LARGE-ZICFILP-LABEL: test_call_external:
69+
; RV64I-LARGE-ZICFILP: # %bb.0:
70+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
71+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
72+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
73+
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi0:
74+
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI0_0)
75+
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi0)(a1)
76+
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
77+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
78+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
79+
; RV64I-LARGE-ZICFILP-NEXT: ret
6580
%1 = call i32 @external_function(i32 %a)
6681
ret i32 %1
6782
}
@@ -116,6 +131,19 @@ define i32 @test_call_dso_local(i32 %a) nounwind {
116131
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
117132
; RV64I-LARGE-NEXT: addi sp, sp, 16
118133
; RV64I-LARGE-NEXT: ret
134+
;
135+
; RV64I-LARGE-ZICFILP-LABEL: test_call_dso_local:
136+
; RV64I-LARGE-ZICFILP: # %bb.0:
137+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
138+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
139+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
140+
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi1:
141+
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI1_0)
142+
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi1)(a1)
143+
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
144+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
145+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
146+
; RV64I-LARGE-ZICFILP-NEXT: ret
119147
%1 = call i32 @dso_local_function(i32 %a)
120148
ret i32 %1
121149
}
@@ -145,6 +173,12 @@ define i32 @defined_function(i32 %a) nounwind {
145173
; RV64I-LARGE: # %bb.0:
146174
; RV64I-LARGE-NEXT: addiw a0, a0, 1
147175
; RV64I-LARGE-NEXT: ret
176+
;
177+
; RV64I-LARGE-ZICFILP-LABEL: defined_function:
178+
; RV64I-LARGE-ZICFILP: # %bb.0:
179+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
180+
; RV64I-LARGE-ZICFILP-NEXT: addiw a0, a0, 1
181+
; RV64I-LARGE-ZICFILP-NEXT: ret
148182
%1 = add i32 %a, 1
149183
ret i32 %1
150184
}
@@ -197,6 +231,19 @@ define i32 @test_call_defined(i32 %a) nounwind {
197231
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
198232
; RV64I-LARGE-NEXT: addi sp, sp, 16
199233
; RV64I-LARGE-NEXT: ret
234+
;
235+
; RV64I-LARGE-ZICFILP-LABEL: test_call_defined:
236+
; RV64I-LARGE-ZICFILP: # %bb.0:
237+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
238+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
239+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
240+
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi2:
241+
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI3_0)
242+
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi2)(a1)
243+
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
244+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
245+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
246+
; RV64I-LARGE-ZICFILP-NEXT: ret
200247
%1 = call i32 @defined_function(i32 %a)
201248
ret i32 %1
202249
}
@@ -256,6 +303,18 @@ define i32 @test_call_indirect(ptr %a, i32 %b) nounwind {
256303
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
257304
; RV64I-LARGE-NEXT: addi sp, sp, 16
258305
; RV64I-LARGE-NEXT: ret
306+
;
307+
; RV64I-LARGE-ZICFILP-LABEL: test_call_indirect:
308+
; RV64I-LARGE-ZICFILP: # %bb.0:
309+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
310+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
311+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
312+
; RV64I-LARGE-ZICFILP-NEXT: mv a2, a0
313+
; RV64I-LARGE-ZICFILP-NEXT: mv a0, a1
314+
; RV64I-LARGE-ZICFILP-NEXT: jalr a2
315+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
316+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
317+
; RV64I-LARGE-ZICFILP-NEXT: ret
259318
%1 = call i32 %a(i32 %b)
260319
ret i32 %1
261320
}
@@ -347,6 +406,24 @@ define i32 @test_call_indirect_no_t0(ptr %a, i32 %b, i32 %c, i32 %d, i32 %e, i32
347406
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
348407
; RV64I-LARGE-NEXT: addi sp, sp, 16
349408
; RV64I-LARGE-NEXT: ret
409+
;
410+
; RV64I-LARGE-ZICFILP-LABEL: test_call_indirect_no_t0:
411+
; RV64I-LARGE-ZICFILP: # %bb.0:
412+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
413+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
414+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
415+
; RV64I-LARGE-ZICFILP-NEXT: mv t1, a0
416+
; RV64I-LARGE-ZICFILP-NEXT: mv a0, a1
417+
; RV64I-LARGE-ZICFILP-NEXT: mv a1, a2
418+
; RV64I-LARGE-ZICFILP-NEXT: mv a2, a3
419+
; RV64I-LARGE-ZICFILP-NEXT: mv a3, a4
420+
; RV64I-LARGE-ZICFILP-NEXT: mv a4, a5
421+
; RV64I-LARGE-ZICFILP-NEXT: mv a5, a6
422+
; RV64I-LARGE-ZICFILP-NEXT: mv a6, a7
423+
; RV64I-LARGE-ZICFILP-NEXT: jalr t1
424+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
425+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
426+
; RV64I-LARGE-ZICFILP-NEXT: ret
350427
%1 = call i32 %a(i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h)
351428
ret i32 %1
352429
}
@@ -379,6 +456,12 @@ define fastcc i32 @fastcc_function(i32 %a, i32 %b) nounwind {
379456
; RV64I-LARGE: # %bb.0:
380457
; RV64I-LARGE-NEXT: addw a0, a0, a1
381458
; RV64I-LARGE-NEXT: ret
459+
;
460+
; RV64I-LARGE-ZICFILP-LABEL: fastcc_function:
461+
; RV64I-LARGE-ZICFILP: # %bb.0:
462+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
463+
; RV64I-LARGE-ZICFILP-NEXT: addw a0, a0, a1
464+
; RV64I-LARGE-ZICFILP-NEXT: ret
382465
%1 = add i32 %a, %b
383466
ret i32 %1
384467
}
@@ -452,6 +535,24 @@ define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind {
452535
; RV64I-LARGE-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
453536
; RV64I-LARGE-NEXT: addi sp, sp, 16
454537
; RV64I-LARGE-NEXT: ret
538+
;
539+
; RV64I-LARGE-ZICFILP-LABEL: test_call_fastcc:
540+
; RV64I-LARGE-ZICFILP: # %bb.0:
541+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
542+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
543+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
544+
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
545+
; RV64I-LARGE-ZICFILP-NEXT: mv s0, a0
546+
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi3:
547+
; RV64I-LARGE-ZICFILP-NEXT: auipc a0, %pcrel_hi(.LCPI7_0)
548+
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi3)(a0)
549+
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
550+
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
551+
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
552+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
553+
; RV64I-LARGE-ZICFILP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
554+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
555+
; RV64I-LARGE-ZICFILP-NEXT: ret
455556
%1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
456557
ret i32 %a
457558
}
@@ -572,6 +673,33 @@ define i32 @test_call_external_many_args(i32 %a) nounwind {
572673
; RV64I-LARGE-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
573674
; RV64I-LARGE-NEXT: addi sp, sp, 32
574675
; RV64I-LARGE-NEXT: ret
676+
;
677+
; RV64I-LARGE-ZICFILP-LABEL: test_call_external_many_args:
678+
; RV64I-LARGE-ZICFILP: # %bb.0:
679+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
680+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -32
681+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
682+
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
683+
; RV64I-LARGE-ZICFILP-NEXT: mv s0, a0
684+
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi4:
685+
; RV64I-LARGE-ZICFILP-NEXT: auipc a0, %pcrel_hi(.LCPI8_0)
686+
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi4)(a0)
687+
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 8(sp)
688+
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 0(sp)
689+
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
690+
; RV64I-LARGE-ZICFILP-NEXT: mv a1, s0
691+
; RV64I-LARGE-ZICFILP-NEXT: mv a2, s0
692+
; RV64I-LARGE-ZICFILP-NEXT: mv a3, s0
693+
; RV64I-LARGE-ZICFILP-NEXT: mv a4, s0
694+
; RV64I-LARGE-ZICFILP-NEXT: mv a5, s0
695+
; RV64I-LARGE-ZICFILP-NEXT: mv a6, s0
696+
; RV64I-LARGE-ZICFILP-NEXT: mv a7, s0
697+
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
698+
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
699+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
700+
; RV64I-LARGE-ZICFILP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
701+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 32
702+
; RV64I-LARGE-ZICFILP-NEXT: ret
575703
%1 = call i32 @external_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
576704
i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
577705
ret i32 %a
@@ -607,6 +735,13 @@ define i32 @defined_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 %
607735
; RV64I-LARGE-NEXT: lw a0, 8(sp)
608736
; RV64I-LARGE-NEXT: addiw a0, a0, 1
609737
; RV64I-LARGE-NEXT: ret
738+
;
739+
; RV64I-LARGE-ZICFILP-LABEL: defined_many_args:
740+
; RV64I-LARGE-ZICFILP: # %bb.0:
741+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
742+
; RV64I-LARGE-ZICFILP-NEXT: lw a0, 8(sp)
743+
; RV64I-LARGE-ZICFILP-NEXT: addiw a0, a0, 1
744+
; RV64I-LARGE-ZICFILP-NEXT: ret
610745
%added = add i32 %j, 1
611746
ret i32 %added
612747
}
@@ -704,6 +839,28 @@ define i32 @test_call_defined_many_args(i32 %a) nounwind {
704839
; RV64I-LARGE-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
705840
; RV64I-LARGE-NEXT: addi sp, sp, 32
706841
; RV64I-LARGE-NEXT: ret
842+
;
843+
; RV64I-LARGE-ZICFILP-LABEL: test_call_defined_many_args:
844+
; RV64I-LARGE-ZICFILP: # %bb.0:
845+
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
846+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -32
847+
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
848+
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi5:
849+
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI10_0)
850+
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi5)(a1)
851+
; RV64I-LARGE-ZICFILP-NEXT: sd a0, 8(sp)
852+
; RV64I-LARGE-ZICFILP-NEXT: sd a0, 0(sp)
853+
; RV64I-LARGE-ZICFILP-NEXT: mv a1, a0
854+
; RV64I-LARGE-ZICFILP-NEXT: mv a2, a0
855+
; RV64I-LARGE-ZICFILP-NEXT: mv a3, a0
856+
; RV64I-LARGE-ZICFILP-NEXT: mv a4, a0
857+
; RV64I-LARGE-ZICFILP-NEXT: mv a5, a0
858+
; RV64I-LARGE-ZICFILP-NEXT: mv a6, a0
859+
; RV64I-LARGE-ZICFILP-NEXT: mv a7, a0
860+
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
861+
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
862+
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 32
863+
; RV64I-LARGE-ZICFILP-NEXT: ret
707864
%1 = call i32 @defined_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
708865
i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
709866
ret i32 %1

0 commit comments

Comments
 (0)