diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp index 359bde1244429..04d57f0fe7457 100644 --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp @@ -282,9 +282,11 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO, break; case LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20_R: FixupKind = LoongArch::fixup_loongarch_tls_le_hi20_r; + RelaxCandidate = true; break; case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12_R: FixupKind = LoongArch::fixup_loongarch_tls_le_lo12_r; + RelaxCandidate = true; break; case LoongArchMCExpr::VK_LoongArch_PCREL20_S2: FixupKind = LoongArch::fixup_loongarch_pcrel20_s2; @@ -387,11 +389,17 @@ void LoongArchMCCodeEmitter::expandAddTPRel(const MCInst &MI, "Expected %le_add_r relocation on TP-relative symbol"); // Emit the correct %le_add_r relocation for the symbol. - // TODO: Emit R_LARCH_RELAX for %le_add_r where the relax feature is enabled. Fixups.push_back(MCFixup::create( 0, Expr, MCFixupKind(LoongArch::fixup_loongarch_tls_le_add_r), MI.getLoc())); + // Emit R_LARCH_RELAX for %le_add_r when the relax feature is enabled. + if (STI.hasFeature(LoongArch::FeatureRelax)) { + const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); + Fixups.push_back(MCFixup::create( + 0, Dummy, MCFixupKind(LoongArch::fixup_loongarch_relax), MI.getLoc())); + } + // Emit a normal ADD instruction with the given operands. unsigned ADD = MI.getOpcode() == LoongArch::PseudoAddTPRel_D ? LoongArch::ADD_D diff --git a/llvm/test/MC/LoongArch/Relocations/relax-tls-le.s b/llvm/test/MC/LoongArch/Relocations/relax-tls-le.s new file mode 100644 index 0000000000000..899f12f85654d --- /dev/null +++ b/llvm/test/MC/LoongArch/Relocations/relax-tls-le.s @@ -0,0 +1,70 @@ +# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax < %s \ +# RUN: | llvm-readobj -r - | FileCheck --check-prefix=LA32-RELAX-RELOC %s +# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=-relax < %s \ +# RUN: | llvm-readobj -r - | FileCheck --check-prefix=LA32-NORELAX-RELOC %s +# RUN: llvm-mc --triple=loongarch32 --mattr=+relax < %s --show-encoding \ +# RUN: | FileCheck --check-prefix=LA32-RELAX-FIXUP %s + +# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax --defsym=LA64=1 < %s \ +# RUN: | llvm-readobj -r - | FileCheck --check-prefix=LA64-RELAX-RELOC %s +# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax --defsym=LA64=1 < %s \ +# RUN: | llvm-readobj -r - | FileCheck --check-prefix=LA64-NORELAX-RELOC %s +# RUN: llvm-mc --triple=loongarch64 --mattr=+relax --defsym=LA64=1 < %s --show-encoding \ +# RUN: | FileCheck --check-prefix=LA64-RELAX-FIXUP %s + +.long foo + +.ifndef LA64 + +lu12i.w $a0, %le_hi20_r(foo) +# LA32-NORELAX-RELOC: R_LARCH_TLS_LE_HI20_R foo 0x0 +# LA32-NORELAX-RELOC-NOT: R_LARCH_RELAX - 0x0 +# LA32-RELAX-RELOC: R_LARCH_TLS_LE_HI20_R foo 0x0 +# LA32-RELAX-RELOC: R_LARCH_RELAX - 0x0 +# LA32-RELAX-FIXUP: fixup A - offset: 0, value: %le_hi20_r(foo), kind: FK_NONE +# LA32-RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: FK_NONE + +add.w $a0, $a0, $tp, %le_add_r(foo) +# LA32-NORELAX-RELOC: R_LARCH_TLS_LE_ADD_R foo 0x0 +# LA32-NORELAX-RELOC-NOT: R_LARCH_RELAX - 0x0 +# LA32-RELAX-RELOC: R_LARCH_TLS_LE_ADD_R foo 0x0 +# LA32-RELAX-RELOC: R_LARCH_RELAX - 0x0 +# LA32-RELAX-FIXUP: fixup A - offset: 0, value: %le_add_r(foo), kind: FK_NONE +# LA32-RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: FK_NONE + +addi.w $a0, $a0, %le_lo12_r(foo) +# LA32-NORELAX-RELOC: R_LARCH_TLS_LE_LO12_R foo 0x0 +# LA32-NORELAX-RELOC-NOT: R_LARCH_RELAX - 0x0 +# LA32-RELAX-RELOC: R_LARCH_TLS_LE_LO12_R foo 0x0 +# LA32-RELAX-RELOC: R_LARCH_RELAX - 0x0 +# LA32-RELAX-FIXUP: fixup A - offset: 0, value: %le_lo12_r(foo), kind: FK_NONE +# LA32-RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: FK_NONE + +.else + +lu12i.w $a0, %le_hi20_r(foo) +# LA64-NORELAX-RELOC: R_LARCH_TLS_LE_HI20_R foo 0x0 +# LA64-NORELAX-RELOC-NOT: R_LARCH_RELAX - 0x0 +# LA64-RELAX-RELOC: R_LARCH_TLS_LE_HI20_R foo 0x0 +# LA64-RELAX-RELOC: R_LARCH_RELAX - 0x0 +# LA64-RELAX-FIXUP: fixup A - offset: 0, value: %le_hi20_r(foo), kind: FK_NONE +# LA64-RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: FK_NONE + +add.d $a0, $a0, $tp, %le_add_r(foo) +# LA64-NORELAX-RELOC: R_LARCH_TLS_LE_ADD_R foo 0x0 +# LA64-NORELAX-RELOC-NOT: R_LARCH_RELAX - 0x0 +# LA64-RELAX-RELOC: R_LARCH_TLS_LE_ADD_R foo 0x0 +# LA64-RELAX-RELOC: R_LARCH_RELAX - 0x0 +# LA64-RELAX-FIXUP: fixup A - offset: 0, value: %le_add_r(foo), kind: FK_NONE +# LA64-RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: FK_NONE + +addi.d $a0, $a0, %le_lo12_r(foo) +# LA64-NORELAX-RELOC: R_LARCH_TLS_LE_LO12_R foo 0x0 +# LA64-NORELAX-RELOC-NOT: R_LARCH_RELAX - 0x0 +# LA64-RELAX-RELOC: R_LARCH_TLS_LE_LO12_R foo 0x0 +# LA64-RELAX-RELOC: R_LARCH_RELAX - 0x0 +# LA64-RELAX-FIXUP: fixup A - offset: 0, value: %le_lo12_r(foo), kind: FK_NONE +# LA64-RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: FK_NONE + +.endif +