diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -118,6 +118,11 @@ 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. + // NOTE: Should we use X7 without Zicfilp after Zicfilp ratified? + 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 --- 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 @@ # 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@plt, kind: