[llvm-branch-commits] [llvm] [llvm][LoongArch] Add PC-relative address materialization using pcadd instructions (PR #175358)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Jan 10 08:59:14 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: hev (heiher)
<details>
<summary>Changes</summary>
This patch adds support for PC-relative address materialization using pcadd-class relocations, covering the HI20/LO12 pair and their GOT and TLS variants (IE, LD, GD, and DESC).
Link: https://gcc.gnu.org/pipermail/gcc-patches/2025-December/703312.html
---
Patch is 115.87 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/175358.diff
32 Files Affected:
- (modified) llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp (+133-27)
- (modified) llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp (+153-54)
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+14-4)
- (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp (+40-16)
- (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.td (+5-1)
- (modified) llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp (+39)
- (modified) llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp (+39-16)
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h (+12)
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp (+36)
- (modified) llvm/test/CodeGen/LoongArch/block-address.ll (+7-5)
- (modified) llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll (+5-4)
- (modified) llvm/test/CodeGen/LoongArch/branch-relaxation.ll (+3-2)
- (modified) llvm/test/CodeGen/LoongArch/calling-conv-ilp32d.ll (+24-16)
- (modified) llvm/test/CodeGen/LoongArch/code-models.ll (+149-90)
- (modified) llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll (+12-8)
- (modified) llvm/test/CodeGen/LoongArch/double-imm.ll (+42-28)
- (modified) llvm/test/CodeGen/LoongArch/float-imm.ll (+9-6)
- (modified) llvm/test/CodeGen/LoongArch/global-address.ll (+12-8)
- (modified) llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll (+3-2)
- (modified) llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll (+11-7)
- (modified) llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll (+14-10)
- (modified) llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll (+15-10)
- (modified) llvm/test/CodeGen/LoongArch/merge-base-offset.ll (+132-89)
- (modified) llvm/test/CodeGen/LoongArch/numeric-reg-names.ll (+3-2)
- (modified) llvm/test/CodeGen/LoongArch/stack-protector-target.ll (+11-8)
- (modified) llvm/test/CodeGen/LoongArch/tls-models.ll (+27-18)
- (modified) llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll (+3-2)
- (modified) llvm/test/CodeGen/LoongArch/vector-fp-imm.ll (+6-4)
- (modified) llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s (+5-2)
- (modified) llvm/test/MC/LoongArch/Basic/Integer/invalid.s (+2-2)
- (modified) llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected (+3-2)
- (modified) llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected (+3-2)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
index fa545f740b529..965d2e24919c6 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -38,6 +38,7 @@ class LoongArchAsmParser : public MCTargetAsmParser {
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
bool is64Bit() const { return getSTI().hasFeature(LoongArch::Feature64Bit); }
+ bool has32S() const { return getSTI().hasFeature(LoongArch::Feature32S); }
LoongArchTargetStreamer &getTargetStreamer() {
assert(getParser().getStreamer().getTargetStreamer() &&
"do not have a target streamer");
@@ -328,8 +329,13 @@ class LoongArchOperand : public MCParsedAsmOperand {
bool IsValidKind =
VK == LoongArchMCExpr::VK_None || VK == ELF::R_LARCH_PCALA_LO12 ||
VK == ELF::R_LARCH_GOT_PC_LO12 || VK == ELF::R_LARCH_TLS_IE_PC_LO12 ||
- VK == ELF::R_LARCH_TLS_LE_LO12_R ||
- VK == ELF::R_LARCH_TLS_DESC_PC_LO12 || VK == ELF::R_LARCH_TLS_DESC_LD;
+ VK == ELF::R_LARCH_TLS_LE_LO12_R || VK == ELF::R_LARCH_TLS_DESC_LD ||
+ VK == ELF::R_LARCH_TLS_DESC_PC_LO12 || VK == ELF::R_LARCH_PCADD_LO12 ||
+ VK == ELF::R_LARCH_GOT_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_IE_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_LD_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_GD_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_DESC_PCADD_LO12;
return IsConstantImm
? isInt<12>(Imm) && IsValidKind
: LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
@@ -463,6 +469,27 @@ class LoongArchOperand : public MCParsedAsmOperand {
IsValidKind;
}
+ bool isSImm20pcaddu12i() const {
+ if (!isImm())
+ return false;
+
+ int64_t Imm;
+ LoongArchMCExpr::Specifier VK = LoongArchMCExpr::VK_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ bool IsValidKind =
+ VK == LoongArchMCExpr::VK_None || VK == ELF::R_LARCH_CALL30 ||
+ VK == ELF::R_LARCH_PCADD_HI20 || VK == ELF::R_LARCH_GOT_PCADD_HI20 ||
+ VK == ELF::R_LARCH_TLS_IE_PCADD_HI20 ||
+ VK == ELF::R_LARCH_TLS_LD_PCADD_HI20 ||
+ VK == ELF::R_LARCH_TLS_GD_PCADD_HI20 ||
+ VK == ELF::R_LARCH_TLS_DESC_PCADD_HI20;
+
+ return IsConstantImm
+ ? isInt<20>(Imm) && IsValidKind
+ : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
+ IsValidKind;
+ }
+
bool isSImm20pcaddu18i() const {
if (!isImm())
return false;
@@ -869,6 +896,7 @@ void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
SMLoc IDLoc, MCStreamer &Out,
bool RelaxHint) {
MCContext &Ctx = getContext();
+ MCSymbol *PCALabel = nullptr;
for (LoongArchAsmParser::Inst &Inst : Insts) {
unsigned Opc = Inst.Opc;
auto VK = LoongArchMCExpr::Specifier(Inst.Specifier);
@@ -877,6 +905,10 @@ void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
switch (Opc) {
default:
llvm_unreachable("unexpected opcode");
+ case LoongArch::PCADDU12I:
+ PCALabel = Ctx.createNamedTempSymbol("pcadd_hi");
+ Out.emitLabel(PCALabel);
+ LLVM_FALLTHROUGH;
case LoongArch::PCALAU12I:
case LoongArch::LU12I_W:
Out.emitInstruction(MCInstBuilder(Opc).addReg(DestReg).addExpr(LE),
@@ -898,6 +930,18 @@ void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
.addExpr(LE),
getSTI());
continue;
+ } else if (VK == ELF::R_LARCH_PCADD_LO12 ||
+ VK == ELF::R_LARCH_GOT_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_IE_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_LD_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_GD_PCADD_LO12 ||
+ VK == ELF::R_LARCH_TLS_DESC_PCADD_LO12) {
+ Out.emitInstruction(
+ MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(
+ LoongArchMCExpr::create(MCSymbolRefExpr::create(PCALabel, Ctx),
+ VK, Ctx, RelaxHint)),
+ getSTI());
+ continue;
}
Out.emitInstruction(
MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE),
@@ -977,17 +1021,27 @@ void LoongArchAsmParser::emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc,
void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,
MCStreamer &Out) {
// la.pcrel $rd, sym
- // expands to:
+ //
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %pcadd_hi20(sym)
+ // addi.w $rd, rd, %pcadd_lo12(.Lpcadd_hi)
+ //
+ // for la32s and la64 expands to:
// pcalau12i $rd, %pc_hi20(sym)
// addi.w/d $rd, rd, %pc_lo12(sym)
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
InstSeq Insts;
+ unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+ unsigned PCAIRel =
+ has32S() ? ELF::R_LARCH_PCALA_HI20 : ELF::R_LARCH_PCADD_HI20;
+ unsigned ADDIRel =
+ has32S() ? ELF::R_LARCH_PCALA_LO12 : ELF::R_LARCH_PCADD_LO12;
- Insts.push_back(
- LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_PCALA_HI20));
- Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_PCALA_LO12));
+ Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
+ Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
/*RelaxHint=*/true);
@@ -1026,7 +1080,12 @@ void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
InstSeq Insts;
+ unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
+ unsigned PCAIRel =
+ has32S() ? ELF::R_LARCH_GOT_PC_HI20 : ELF::R_LARCH_GOT_PCADD_HI20;
+ unsigned LDRel =
+ has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_GOT_PCADD_LO12;
if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
// with feature: +la-glabal-with-abs
@@ -1056,12 +1115,16 @@ void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
return;
}
- // expands to:
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %got_pcadd_hi20(sym)
+ // ld.w $rd, $rd, %got_pcadd_lo12(.Lpcadd_hi)
+ //
+ // for la32s and la64 expands to:
// pcalau12i $rd, %got_pc_hi20(sym)
// ld.w/d $rd, $rd, %got_pc_lo12(sym)
- Insts.push_back(
- LoongArchAsmParser::Inst(LoongArch::PCALAU12I, ELF::R_LARCH_GOT_PC_HI20));
- Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_GOT_PC_LO12));
+ Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
+ Insts.push_back(LoongArchAsmParser::Inst(LD, LDRel));
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
/*RelaxHint=*/true);
@@ -1118,7 +1181,12 @@ void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc,
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
InstSeq Insts;
+ unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
+ unsigned PCAIRel =
+ has32S() ? ELF::R_LARCH_TLS_IE_PC_HI20 : ELF::R_LARCH_TLS_IE_PCADD_HI20;
+ unsigned LDRel =
+ has32S() ? ELF::R_LARCH_TLS_IE_PC_LO12 : ELF::R_LARCH_TLS_IE_PCADD_LO12;
if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
// with feature: +la-glabal-with-abs
@@ -1149,12 +1217,16 @@ void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc,
return;
}
- // expands to:
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %ie_pcadd_hi20(sym)
+ // ld.w $rd, $rd, %ie_pcadd_lo12(.Lpcadd_hi)
+ //
+ // for la32s and la64 expands to:
// pcalau12i $rd, %ie_pc_hi20(sym)
// ld.w/d $rd, $rd, %ie_pc_lo12(sym)
- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
- ELF::R_LARCH_TLS_IE_PC_HI20));
- Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_IE_PC_LO12));
+ Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
+ Insts.push_back(LoongArchAsmParser::Inst(LD, LDRel));
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
/*RelaxHint=*/true);
@@ -1193,7 +1265,12 @@ void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc,
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
InstSeq Insts;
+ unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+ unsigned PCAIRel =
+ has32S() ? ELF::R_LARCH_TLS_LD_PC_HI20 : ELF::R_LARCH_TLS_LD_PCADD_HI20;
+ unsigned ADDIRel =
+ has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_TLS_LD_PCADD_LO12;
if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
// with feature: +la-glabal-with-abs
@@ -1221,12 +1298,16 @@ void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc,
return;
}
- // expands to:
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %ld_pcadd_hi20(sym)
+ // addi.w $rd, $rd, %ld_pcadd_lo12(.Lpcadd_hi)
+ //
+ // for la32s and la64 expands to:
// pcalau12i $rd, %ld_pc_hi20(sym)
// addi.w/d $rd, $rd, %got_pc_lo12(sym)
- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
- ELF::R_LARCH_TLS_LD_PC_HI20));
- Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_GOT_PC_LO12));
+ Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
+ Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
/*RelaxHint=*/true);
@@ -1265,7 +1346,12 @@ void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc,
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
InstSeq Insts;
+ unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+ unsigned PCAIRel =
+ has32S() ? ELF::R_LARCH_TLS_GD_PC_HI20 : ELF::R_LARCH_TLS_GD_PCADD_HI20;
+ unsigned ADDIRel =
+ has32S() ? ELF::R_LARCH_GOT_PC_LO12 : ELF::R_LARCH_TLS_GD_PCADD_LO12;
if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
// with feature: +la-glabal-with-abs
@@ -1293,12 +1379,16 @@ void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc,
return;
}
- // expands to:
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %gd_pcadd_hi20(sym)
+ // addi.w $rd, $rd, %gd_pcadd_lo12(.Lpcadd_hi)
+ //
+ // for la32s and la64 expands to:
// pcalau12i $rd, %gd_pc_hi20(sym)
// addi.w/d $rd, $rd, %got_pc_lo12(sym)
- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
- ELF::R_LARCH_TLS_GD_PC_HI20));
- Insts.push_back(LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_GOT_PC_LO12));
+ Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
+ Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out,
/*RelaxHint=*/true);
@@ -1336,8 +1426,13 @@ void LoongArchAsmParser::emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc,
// la.tls.desc $rd, sym
MCRegister DestReg = Inst.getOperand(0).getReg();
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
+ unsigned PCAI = has32S() ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
+ unsigned PCAIRel = has32S() ? ELF::R_LARCH_TLS_DESC_PC_HI20
+ : ELF::R_LARCH_TLS_DESC_PCADD_HI20;
+ unsigned ADDIRel = has32S() ? ELF::R_LARCH_TLS_DESC_PC_LO12
+ : ELF::R_LARCH_TLS_DESC_PCADD_LO12;
InstSeq Insts;
if (getSTI().hasFeature(LoongArch::LaGlobalWithAbs)) {
@@ -1375,15 +1470,20 @@ void LoongArchAsmParser::emitLoadAddressTLSDesc(MCInst &Inst, SMLoc IDLoc,
return;
}
- // expands to:
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %desc_pcadd_hi20(sym)
+ // addi.w $rd, $rd, %desc_pcadd_lo12(.Lpcadd_hi)
+ // ld.w $ra, $rd, %desc_ld(sym)
+ // jirl $ra, $ra, %desc_call(sym)
+ //
+ // for la32s and la64 expands to:
// pcalau12i $rd, %desc_pc_hi20(sym)
// addi.w/d $rd, $rd, %desc_pc_lo12(sym)
// ld.w/d $ra, $rd, %desc_ld(sym)
// jirl $ra, $ra, %desc_call(sym)
- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::PCALAU12I,
- ELF::R_LARCH_TLS_DESC_PC_HI20));
- Insts.push_back(
- LoongArchAsmParser::Inst(ADDI, ELF::R_LARCH_TLS_DESC_PC_LO12));
+ Insts.push_back(LoongArchAsmParser::Inst(PCAI, PCAIRel));
+ Insts.push_back(LoongArchAsmParser::Inst(ADDI, ADDIRel));
Insts.push_back(LoongArchAsmParser::Inst(LD, ELF::R_LARCH_TLS_DESC_LD));
Insts.push_back(
LoongArchAsmParser::Inst(LoongArch::JIRL, ELF::R_LARCH_TLS_DESC_CALL));
@@ -1874,6 +1974,12 @@ bool LoongArchAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
/*Upper=*/(1 << 19) - 1,
"operand must be a symbol with modifier (e.g. %pc_hi20) or an integer "
"in the range");
+ case Match_InvalidSImm20pcaddu12i:
+ return generateImmOutOfRangeError(
+ Operands, ErrorInfo, /*Lower=*/-(1 << 19),
+ /*Upper=*/(1 << 19) - 1,
+ "operand must be a symbol with modifier (e.g. %pcadd_hi20) or an "
+ "integer in the range");
case Match_InvalidSImm20pcaddu18i:
return generateImmOutOfRangeError(
Operands, ErrorInfo, /*Lower=*/-(1 << 19),
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
index 6cef279c6131c..b3167174454a3 100644
--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -57,11 +57,11 @@ class LoongArchPreRAExpandPseudo : public MachineFunctionPass {
bool expandMBB(MachineBasicBlock &MBB);
bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI);
- bool expandPcalau12iInstPair(MachineBasicBlock &MBB,
+ bool expandPcaxxu12iInstPair(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI,
- unsigned FlagsHi, unsigned SecondOpcode,
- unsigned FlagsLo);
+ unsigned OpcodeHi, unsigned OpcodeLo,
+ unsigned FlagsHi, unsigned FlagsLo);
bool expandLargeAddressLoad(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI,
@@ -177,10 +177,10 @@ bool LoongArchPreRAExpandPseudo::expandMI(
return false;
}
-bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair(
+bool LoongArchPreRAExpandPseudo::expandPcaxxu12iInstPair(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
- MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
- unsigned SecondOpcode, unsigned FlagsLo) {
+ MachineBasicBlock::iterator &NextMBBI, unsigned OpcodeHi, unsigned OpcodeLo,
+ unsigned FlagsHi, unsigned FlagsLo) {
MachineFunction *MF = MBB.getParent();
MachineInstr &MI = *MBBI;
DebugLoc DL = MI.getDebugLoc();
@@ -193,13 +193,24 @@ bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair(
MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
MachineOperand &Symbol = MI.getOperand(1);
- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), ScratchReg)
- .addDisp(Symbol, 0, LoongArchII::encodeFlags(FlagsHi, EnableRelax));
+ MachineInstr *FirstMI =
+ BuildMI(MBB, MBBI, DL, TII->get(OpcodeHi), ScratchReg)
+ .addDisp(Symbol, 0, LoongArchII::encodeFlags(FlagsHi, EnableRelax));
- MachineInstr *SecondMI =
- BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg)
- .addReg(ScratchReg)
- .addDisp(Symbol, 0, LoongArchII::encodeFlags(FlagsLo, EnableRelax));
+ MachineInstr *SecondMI = nullptr;
+ FlagsLo = LoongArchII::encodeFlags(FlagsLo, EnableRelax);
+
+ if (OpcodeHi == LoongArch::PCALAU12I) {
+ SecondMI = BuildMI(MBB, MBBI, DL, TII->get(OpcodeLo), DestReg)
+ .addReg(ScratchReg)
+ .addDisp(Symbol, 0, FlagsLo);
+ } else {
+ MCSymbol *PCAddSymbol = MF->getContext().createNamedTempSymbol("pcadd_hi");
+ FirstMI->setPreInstrSymbol(*MF, PCAddSymbol);
+ SecondMI = BuildMI(MBB, MBBI, DL, TII->get(OpcodeLo), DestReg)
+ .addReg(ScratchReg)
+ .addSym(PCAddSymbol, FlagsLo);
+ }
if (MI.hasOneMemOperand())
SecondMI->addMemOperand(*MF, *MI.memoperands_begin());
@@ -321,13 +332,26 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel(
LoongArchII::MO_PCREL_LO);
// Code Sequence:
- // pcalau12i $rd, %pc_hi20(sym)
- // addi.w/d $rd, $rd, %pc_lo12(sym)
+ //
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %pcadd_hi20(sym)
+ // addi.w $rd, $rd, %pcadd_lo12(.Lpcadd_hi)
+ //
+ // for la32s and la64 expands to:
+ // pcalau12i $rd, %pc_hi20(sym)
+ // addi.w/d $rd, $rd, %pc_lo12(sym)
MachineFunction *MF = MBB.getParent();
const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
- unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
- return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_PCREL_HI,
- SecondOpcode, LoongArchII::MO_PCREL_LO);
+ bool Has32S = STI.hasFeature(LoongArch::Feature32S);
+ unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
+ unsigned OpcodeLo = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+ unsigned FlagsHi =
+ Has32S ? LoongArchII::MO_PCREL_HI : LoongArchII::MO_PCADD_HI;
+ unsigned FlagsLo =
+ Has32S ? LoongArchII::MO_PCREL_LO : LoongArchII::MO_PCADD_LO;
+ return expandPcaxxu12iInstPair(MBB, MBBI, NextMBBI, OpcodeHi, OpcodeLo,
+ FlagsHi, FlagsLo);
}
bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
@@ -340,13 +364,26 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
LoongArchII::MO_GOT_PC_HI);
// Code Sequence:
- // pcalau12i $rd, %got_pc_hi20(sym)
- // ld.w/d $rd, $rd, %got_pc_lo12(sym)
+ //
+ // for la32r expands to:
+ // .Lpcadd_hi:
+ // pcaddu12i $rd, %got_pcadd_hi20(sym)
+ // ld.w $rd, $rd, %got_pcadd_lo12(.Lpcadd_hi)
+ //
+ // for la32s and la64 expands to:
+ // pcalau12i $rd, %got_pc_hi20(sym)
+ // ld.w/d $rd, $rd, %got_pc_lo12(sym)
MachineFunction *MF = MBB.getParent();
const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
- unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
- return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GOT_PC_HI,
- SecondOpcode, LoongArchII::MO_GOT_PC_LO);
+ bool Has32S = STI.hasFeature(LoongArch::Feature32S);
+ unsigned OpcodeHi = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
+ unsigned OpcodeLo = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
+ unsigned FlagsHi =
+ Has32S ? LoongArchII::MO_GOT_PC_HI : LoongArchII::MO_GOT_PCADD_HI;
+ unsigned FlagsLo =
+ Has32S ? LoongArchII::MO_GOT_PC_LO ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/175358
More information about the llvm-branch-commits
mailing list