Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RISCV] Software guard direct calls in large code model #109377

Merged
merged 3 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19696,11 +19696,14 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
// TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
// split it and then direct call can be matched by PseudoCALL.
bool CalleeIsLargeExternalSymbol = false;
if (getTargetMachine().getCodeModel() == CodeModel::Large) {
if (auto *S = dyn_cast<GlobalAddressSDNode>(Callee))
Callee = getLargeGlobalAddress(S, DL, PtrVT, DAG);
else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee))
else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
Callee = getLargeExternalSymbol(S, DL, PtrVT, DAG);
CalleeIsLargeExternalSymbol = true;
}
} else if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
const GlobalValue *GV = S->getGlobal();
Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, RISCVII::MO_CALL);
Expand Down Expand Up @@ -19736,16 +19739,28 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// Emit the call.
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);

// Use software guarded branch for large code model non-indirect calls
// Tail call to external symbol will have a null CLI.CB and we need another
// way to determine the callsite type
bool NeedSWGuarded = false;
if (getTargetMachine().getCodeModel() == CodeModel::Large &&
Subtarget.hasStdExtZicfilp() &&
((CLI.CB && !CLI.CB->isIndirectCall()) || CalleeIsLargeExternalSymbol))
NeedSWGuarded = true;

if (IsTailCall) {
MF.getFrameInfo().setHasTailCall();
SDValue Ret = DAG.getNode(RISCVISD::TAIL, DL, NodeTys, Ops);
unsigned CallOpc =
NeedSWGuarded ? RISCVISD::SW_GUARDED_TAIL : RISCVISD::TAIL;
SDValue Ret = DAG.getNode(CallOpc, DL, NodeTys, Ops);
if (CLI.CFIType)
Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
return Ret;
}

Chain = DAG.getNode(RISCVISD::CALL, DL, NodeTys, Ops);
unsigned CallOpc = NeedSWGuarded ? RISCVISD::SW_GUARDED_CALL : RISCVISD::CALL;
Chain = DAG.getNode(CallOpc, DL, NodeTys, Ops);
if (CLI.CFIType)
Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
Expand Down Expand Up @@ -20193,6 +20208,8 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(CZERO_EQZ)
NODE_NAME_CASE(CZERO_NEZ)
NODE_NAME_CASE(SW_GUARDED_BRIND)
NODE_NAME_CASE(SW_GUARDED_CALL)
NODE_NAME_CASE(SW_GUARDED_TAIL)
NODE_NAME_CASE(TUPLE_INSERT)
NODE_NAME_CASE(TUPLE_EXTRACT)
NODE_NAME_CASE(SF_VC_XV_SE)
Expand Down
7 changes: 5 additions & 2 deletions llvm/lib/Target/RISCV/RISCVISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,12 @@ enum NodeType : unsigned {
CZERO_EQZ, // vt.maskc for XVentanaCondOps.
CZERO_NEZ, // vt.maskcn for XVentanaCondOps.

/// Software guarded BRIND node. Operand 0 is the chain operand and
/// operand 1 is the target address.
// Software guarded BRIND node. Operand 0 is the chain operand and
// operand 1 is the target address.
SW_GUARDED_BRIND,
// Software guarded calls for large code model
SW_GUARDED_CALL,
SW_GUARDED_TAIL,

SF_VC_XV_SE,
SF_VC_IV_SE,
Expand Down
20 changes: 18 additions & 2 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
def riscv_call : SDNode<"RISCVISD::CALL", SDT_RISCVCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def riscv_sw_guarded_call : SDNode<"RISCVISD::SW_GUARDED_CALL", SDT_RISCVCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def riscv_ret_glue : SDNode<"RISCVISD::RET_GLUE", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
def riscv_sret_glue : SDNode<"RISCVISD::SRET_GLUE", SDTNone,
Expand All @@ -69,6 +72,9 @@ def riscv_brcc : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC,
def riscv_tail : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def riscv_sw_guarded_tail : SDNode<"RISCVISD::SW_GUARDED_TAIL", SDT_RISCVCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def riscv_sw_guarded_brind : SDNode<"RISCVISD::SW_GUARDED_BRIND",
SDTBrind, [SDNPHasChain]>;
def riscv_sllw : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
Expand Down Expand Up @@ -1555,10 +1561,15 @@ let Predicates = [NoStdExtZicfilp] in
def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1),
[(riscv_call GPRJALR:$rs1)]>,
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
let Predicates = [HasStdExtZicfilp] in
let Predicates = [HasStdExtZicfilp] in {
def PseudoCALLIndirectNonX7 : Pseudo<(outs), (ins GPRJALRNonX7:$rs1),
[(riscv_call GPRJALRNonX7:$rs1)]>,
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
// For large code model, non-indirect calls could be software-guarded
def PseudoCALLIndirectX7 : Pseudo<(outs), (ins GPRX7:$rs1),
[(riscv_sw_guarded_call GPRX7:$rs1)]>,
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
}
}

let isBarrier = 1, isReturn = 1, isTerminator = 1 in
Expand All @@ -1579,10 +1590,15 @@ let Predicates = [NoStdExtZicfilp] in
def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),
[(riscv_tail GPRTC:$rs1)]>,
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
let Predicates = [HasStdExtZicfilp] in
let Predicates = [HasStdExtZicfilp] in {
def PseudoTAILIndirectNonX7 : Pseudo<(outs), (ins GPRTCNonX7:$rs1),
[(riscv_tail GPRTCNonX7:$rs1)]>,
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
// For large code model, non-indirect calls could be software-guarded
def PseudoTAILIndirectX7 : Pseudo<(outs), (ins GPRX7:$rs1),
[(riscv_sw_guarded_tail GPRX7:$rs1)]>,
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
}
}

def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),
Expand Down
157 changes: 157 additions & 0 deletions llvm/test/CodeGen/RISCV/calls.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
; RUN: | FileCheck -check-prefix=RV64I-MEDIUM %s
; RUN: llc -code-model=large -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV64I-LARGE %s
; RUN: llc -code-model=large -mtriple=riscv64 -mattr=experimental-zicfilp -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV64I-LARGE-ZICFILP %s

declare i32 @external_function(i32)

Expand Down Expand Up @@ -62,6 +64,19 @@ define i32 @test_call_external(i32 %a) nounwind {
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 16
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_external:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi0:
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI0_0)
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi0)(a1)
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call i32 @external_function(i32 %a)
ret i32 %1
}
Expand Down Expand Up @@ -116,6 +131,19 @@ define i32 @test_call_dso_local(i32 %a) nounwind {
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 16
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_dso_local:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi1:
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI1_0)
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi1)(a1)
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call i32 @dso_local_function(i32 %a)
ret i32 %1
}
Expand Down Expand Up @@ -145,6 +173,12 @@ define i32 @defined_function(i32 %a) nounwind {
; RV64I-LARGE: # %bb.0:
; RV64I-LARGE-NEXT: addiw a0, a0, 1
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: defined_function:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addiw a0, a0, 1
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = add i32 %a, 1
ret i32 %1
}
Expand Down Expand Up @@ -197,6 +231,19 @@ define i32 @test_call_defined(i32 %a) nounwind {
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 16
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_defined:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi2:
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI3_0)
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi2)(a1)
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call i32 @defined_function(i32 %a)
ret i32 %1
}
Expand Down Expand Up @@ -256,6 +303,18 @@ define i32 @test_call_indirect(ptr %a, i32 %b) nounwind {
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 16
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_indirect:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: mv a2, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a0, a1
; RV64I-LARGE-ZICFILP-NEXT: jalr a2
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call i32 %a(i32 %b)
ret i32 %1
}
Expand Down Expand Up @@ -347,6 +406,24 @@ define i32 @test_call_indirect_no_t0(ptr %a, i32 %b, i32 %c, i32 %d, i32 %e, i32
; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 16
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_indirect_no_t0:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: mv t1, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a0, a1
; RV64I-LARGE-ZICFILP-NEXT: mv a1, a2
; RV64I-LARGE-ZICFILP-NEXT: mv a2, a3
; RV64I-LARGE-ZICFILP-NEXT: mv a3, a4
; RV64I-LARGE-ZICFILP-NEXT: mv a4, a5
; RV64I-LARGE-ZICFILP-NEXT: mv a5, a6
; RV64I-LARGE-ZICFILP-NEXT: mv a6, a7
; RV64I-LARGE-ZICFILP-NEXT: jalr t1
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call i32 %a(i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h)
ret i32 %1
}
Expand Down Expand Up @@ -379,6 +456,12 @@ define fastcc i32 @fastcc_function(i32 %a, i32 %b) nounwind {
; RV64I-LARGE: # %bb.0:
; RV64I-LARGE-NEXT: addw a0, a0, a1
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: fastcc_function:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addw a0, a0, a1
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = add i32 %a, %b
ret i32 %1
}
Expand Down Expand Up @@ -452,6 +535,24 @@ define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind {
; RV64I-LARGE-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 16
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_fastcc:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -16
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: mv s0, a0
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi3:
; RV64I-LARGE-ZICFILP-NEXT: auipc a0, %pcrel_hi(.LCPI7_0)
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 16
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
ret i32 %a
}
Expand Down Expand Up @@ -572,6 +673,33 @@ define i32 @test_call_external_many_args(i32 %a) nounwind {
; RV64I-LARGE-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 32
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_external_many_args:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -32
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: mv s0, a0
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi4:
; RV64I-LARGE-ZICFILP-NEXT: auipc a0, %pcrel_hi(.LCPI8_0)
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi4)(a0)
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 8(sp)
; RV64I-LARGE-ZICFILP-NEXT: sd s0, 0(sp)
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
; RV64I-LARGE-ZICFILP-NEXT: mv a1, s0
; RV64I-LARGE-ZICFILP-NEXT: mv a2, s0
; RV64I-LARGE-ZICFILP-NEXT: mv a3, s0
; RV64I-LARGE-ZICFILP-NEXT: mv a4, s0
; RV64I-LARGE-ZICFILP-NEXT: mv a5, s0
; RV64I-LARGE-ZICFILP-NEXT: mv a6, s0
; RV64I-LARGE-ZICFILP-NEXT: mv a7, s0
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
; RV64I-LARGE-ZICFILP-NEXT: mv a0, s0
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 32
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call i32 @external_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
ret i32 %a
Expand Down Expand Up @@ -607,6 +735,13 @@ define i32 @defined_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 %
; RV64I-LARGE-NEXT: lw a0, 8(sp)
; RV64I-LARGE-NEXT: addiw a0, a0, 1
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: defined_many_args:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: lw a0, 8(sp)
; RV64I-LARGE-ZICFILP-NEXT: addiw a0, a0, 1
; RV64I-LARGE-ZICFILP-NEXT: ret
%added = add i32 %j, 1
ret i32 %added
}
Expand Down Expand Up @@ -704,6 +839,28 @@ define i32 @test_call_defined_many_args(i32 %a) nounwind {
; RV64I-LARGE-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-LARGE-NEXT: addi sp, sp, 32
; RV64I-LARGE-NEXT: ret
;
; RV64I-LARGE-ZICFILP-LABEL: test_call_defined_many_args:
; RV64I-LARGE-ZICFILP: # %bb.0:
; RV64I-LARGE-ZICFILP-NEXT: lpad 0
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, -32
; RV64I-LARGE-ZICFILP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-LARGE-ZICFILP-NEXT: .Lpcrel_hi5:
; RV64I-LARGE-ZICFILP-NEXT: auipc a1, %pcrel_hi(.LCPI10_0)
; RV64I-LARGE-ZICFILP-NEXT: ld t2, %pcrel_lo(.Lpcrel_hi5)(a1)
; RV64I-LARGE-ZICFILP-NEXT: sd a0, 8(sp)
; RV64I-LARGE-ZICFILP-NEXT: sd a0, 0(sp)
; RV64I-LARGE-ZICFILP-NEXT: mv a1, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a2, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a3, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a4, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a5, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a6, a0
; RV64I-LARGE-ZICFILP-NEXT: mv a7, a0
; RV64I-LARGE-ZICFILP-NEXT: jalr t2
; RV64I-LARGE-ZICFILP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-LARGE-ZICFILP-NEXT: addi sp, sp, 32
; RV64I-LARGE-ZICFILP-NEXT: ret
%1 = call i32 @defined_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
ret i32 %1
Expand Down
Loading
Loading