diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 5ea386c3c32a3d..0863345b0c6dc6 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -126,6 +126,10 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, if (MI.getOpcode() == RISCV::PseudoTAIL) { Func = MI.getOperand(0); Ra = RISCV::X6; + // For Zicfilp, PseudoTAIL should be expanded to a software guarded branch. + // It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL. + if (STI.hasFeature(RISCV::FeatureStdExtZicfilp)) + Ra = RISCV::X7; } else if (MI.getOpcode() == RISCV::PseudoCALLReg) { Func = MI.getOperand(1); Ra = MI.getOperand(0).getReg(); diff --git a/llvm/test/MC/RISCV/tail-call.s b/llvm/test/MC/RISCV/tail-call.s index c94af672edda2a..7c9f28bdfacda4 100644 --- a/llvm/test/MC/RISCV/tail-call.s +++ b/llvm/test/MC/RISCV/tail-call.s @@ -12,17 +12,36 @@ # RUN: llvm-mc -triple riscv64 < %s -show-encoding \ # RUN: | FileCheck -check-prefix=FIXUP %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zicfilp < %s \ +# RUN: | llvm-objdump -d - | FileCheck --check-prefix=INSTR-ZICFILP %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zicfilp < %s \ +# RUN: | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s +# RUN: llvm-mc -triple riscv32 -mattr=+experimental-zicfilp < %s -show-encoding \ +# RUN: | FileCheck -check-prefix=FIXUP %s + +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zicfilp < %s \ +# RUN: | llvm-objdump -d - | FileCheck --check-prefix=INSTR-ZICFILP %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zicfilp < %s \ +# RUN: | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s +# RUN: llvm-mc -triple riscv64 -mattr=+experimental-zicfilp < %s -show-encoding \ +# RUN: | FileCheck -check-prefix=FIXUP %s + .long foo tail foo # RELOC: R_RISCV_CALL_PLT foo 0x0 # INSTR: auipc t1, 0 # INSTR: jr t1 +# INSTR-ZICFILP: auipc t2, 0 +# INSTR-ZICFILP: jr t2 # FIXUP: fixup A - offset: 0, value: foo, kind: + tail bar # RELOC: R_RISCV_CALL_PLT bar 0x0 # INSTR: auipc t1, 0 # INSTR: jr t1 +# INSTR-ZICFILP: auipc t2, 0 +# INSTR-ZICFILP: jr t2 # FIXUP: fixup A - offset: 0, value: bar, kind: # Ensure that tail calls to functions whose names coincide with register names @@ -32,22 +51,30 @@ tail zero # RELOC: R_RISCV_CALL_PLT zero 0x0 # INSTR: auipc t1, 0 # INSTR: jr t1 +# INSTR-ZICFILP: auipc t2, 0 +# INSTR-ZICFILP: jr t2 # FIXUP: fixup A - offset: 0, value: zero, kind: tail f1 # RELOC: R_RISCV_CALL_PLT f1 0x0 # INSTR: auipc t1, 0 # INSTR: jr t1 +# INSTR-ZICFILP: auipc t2, 0 +# INSTR-ZICFILP: jr t2 # FIXUP: fixup A - offset: 0, value: f1, kind: tail ra # RELOC: R_RISCV_CALL_PLT ra 0x0 # INSTR: auipc t1, 0 # INSTR: jr t1 +# INSTR-ZICFILP: auipc t2, 0 +# INSTR-ZICFILP: jr t2 # FIXUP: fixup A - offset: 0, value: ra, kind: tail foo@plt # RELOC: R_RISCV_CALL_PLT foo 0x0 # INSTR: auipc t1, 0 # INSTR: jr t1 +# INSTR-ZICFILP: auipc t2, 0 +# INSTR-ZICFILP: jr t2 # FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_call_plt