Index: lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -48,6 +48,10 @@ // during relaxation. bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override { + // Always preserve relocation type for function call. + if ((unsigned)Fixup.getKind() == RISCV::fixup_riscv_call) + return true; + return STI.getFeatureBits()[RISCV::FeatureRelax]; } @@ -68,7 +72,7 @@ } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { - const static MCFixupKindInfo Infos[RISCV::NumTargetFixupKinds] = { + const static MCFixupKindInfo Infos[] = { // This table *must* be in the order that the fixup_* kinds are defined in // RISCVFixupKinds.h. // @@ -82,8 +86,12 @@ { "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel } + { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_riscv_call", 0, 32, MCFixupKindInfo::FKF_IsPCRel } }; + static_assert((sizeof(Infos) / sizeof(MCFixupKindInfo)) == + RISCV::NumTargetFixupKinds, + "the MCFixupKind numbers in Infos should equal to RISCV::NumTargetFixupKinds"); if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); Index: test/CodeGen/RISCV/function-call.ll =================================================================== --- /dev/null +++ test/CodeGen/RISCV/function-call.ll @@ -0,0 +1,14 @@ +; RUN: llc -mtriple=riscv32 -filetype=obj < %s\ +; RUN: | llvm-readobj -r | FileCheck -check-prefix=RELOC %s + +define i32 @foo(i32 %a, i32 %b) nounwind { + %1 = add i32 %a, %b + ret i32 %1 +} + +define i32 @bar(i32 %a) nounwind { + %1 = add i32 %a, 5 + %2 = call i32 @foo(i32 %1, i32 %a) +; RELOC: R_RISCV_CALL foo 0x0 + ret i32 %2 +} Index: test/MC/RISCV/function-call.s =================================================================== --- test/MC/RISCV/function-call.s +++ test/MC/RISCV/function-call.s @@ -11,12 +11,12 @@ # RELOC: R_RISCV_CALL foo 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: foo, kind: +# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_call call bar # RELOC: R_RISCV_CALL bar 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: bar, kind: +# FIXUP: fixup A - offset: 0, value: bar, kind: fixup_riscv_call # Ensure that calls to functions whose names coincide with register names work. @@ -24,16 +24,16 @@ # RELOC: R_RISCV_CALL zero 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: zero, kind: +# FIXUP: fixup A - offset: 0, value: zero, kind: fixup_riscv_call call f1 # RELOC: R_RISCV_CALL f1 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: f1, kind: +# FIXUP: fixup A - offset: 0, value: f1, kind: fixup_riscv_call call ra # RELOC: R_RISCV_CALL ra 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: ra, kind: +# FIXUP: fixup A - offset: 0, value: ra, kind: fixup_riscv_call