Skip to content

Commit

Permalink
[RISCV] Software guard direct calls in large code model (#109377)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
jaidTw authored Sep 27, 2024
1 parent 24bc324 commit 9bdcf7a
Show file tree
Hide file tree
Showing 5 changed files with 470 additions and 9 deletions.
23 changes: 20 additions & 3 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19752,11 +19752,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 @@ -19792,16 +19795,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 @@ -20249,6 +20264,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

0 comments on commit 9bdcf7a

Please sign in to comment.