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 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
