[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:58:39 PST 2026


https://github.com/heiher created https://github.com/llvm/llvm-project/pull/175358

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

>From c335a5a874992927d09aaedc1adb7aa024df3f0e Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Sun, 4 Jan 2026 10:14:49 +0800
Subject: [PATCH] [llvm][LoongArch] Add PC-relative address materialization
 using pcadd instructions

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
---
 .../AsmParser/LoongArchAsmParser.cpp          | 160 ++++++++++--
 .../LoongArch/LoongArchExpandPseudoInsts.cpp  | 207 +++++++++++----
 .../LoongArch/LoongArchISelLowering.cpp       |  18 +-
 .../Target/LoongArch/LoongArchInstrInfo.cpp   |  56 ++--
 .../Target/LoongArch/LoongArchInstrInfo.td    |   6 +-
 .../Target/LoongArch/LoongArchMCInstLower.cpp |  39 +++
 .../LoongArch/LoongArchMergeBaseOffset.cpp    |  55 ++--
 .../MCTargetDesc/LoongArchBaseInfo.h          |  12 +
 .../MCTargetDesc/LoongArchMCAsmInfo.cpp       |  36 +++
 llvm/test/CodeGen/LoongArch/block-address.ll  |  12 +-
 .../LoongArch/branch-relaxation-spill-32.ll   |   9 +-
 .../CodeGen/LoongArch/branch-relaxation.ll    |   5 +-
 .../CodeGen/LoongArch/calling-conv-ilp32d.ll  |  40 +--
 llvm/test/CodeGen/LoongArch/code-models.ll    | 239 +++++++++++-------
 .../test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll |  20 +-
 llvm/test/CodeGen/LoongArch/double-imm.ll     |  70 +++--
 llvm/test/CodeGen/LoongArch/float-imm.ll      |  15 +-
 llvm/test/CodeGen/LoongArch/global-address.ll |  20 +-
 .../LoongArch/inline-asm-constraint-f.ll      |   5 +-
 .../LoongArch/inline-asm-constraint-m.ll      |  18 +-
 .../LoongArch/ir-instruction/load-store.ll    |  24 +-
 .../LoongArch/machinelicm-address-pseudos.ll  |  25 +-
 .../CodeGen/LoongArch/merge-base-offset.ll    | 221 +++++++++-------
 .../CodeGen/LoongArch/numeric-reg-names.ll    |   5 +-
 .../LoongArch/stack-protector-target.ll       |  19 +-
 llvm/test/CodeGen/LoongArch/tls-models.ll     |  45 ++--
 .../LoongArch/unaligned-memcpy-inline.ll      |   5 +-
 llvm/test/CodeGen/LoongArch/vector-fp-imm.ll  |  10 +-
 .../JITLink/LoongArch/ELF_reloc_addsub.s      |   7 +-
 .../test/MC/LoongArch/Basic/Integer/invalid.s |   4 +-
 ...arch_generated_funcs.ll.generated.expected |   5 +-
 ...ch_generated_funcs.ll.nogenerated.expected |   5 +-
 32 files changed, 972 insertions(+), 445 deletions(-)

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 : LoongArchII::MO_GOT_PCADD_LO;
+  return expandPcaxxu12iInstPair(MBB, MBBI, NextMBBI, OpcodeHi, OpcodeLo,
+                                 FlagsHi, FlagsLo);
 }
 
 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
@@ -424,13 +461,26 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE(
                                   LoongArchII::MO_IE_PC_LO);
 
   // Code Sequence:
-  // pcalau12i $rd, %ie_pc_hi20(sym)
-  // ld.w/d $rd, $rd, %ie_pc_lo12(sym)
+  //
+  // 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)
   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_IE_PC_HI,
-                                 SecondOpcode, LoongArchII::MO_IE_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_IE_PC_HI : LoongArchII::MO_IE_PCADD_HI;
+  unsigned FlagsLo =
+      Has32S ? LoongArchII::MO_IE_PC_LO : LoongArchII::MO_IE_PCADD_LO;
+  return expandPcaxxu12iInstPair(MBB, MBBI, NextMBBI, OpcodeHi, OpcodeLo,
+                                 FlagsHi, FlagsLo);
 }
 
 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD(
@@ -443,13 +493,26 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD(
                                   LoongArchII::MO_LD_PC_HI);
 
   // Code Sequence:
-  // pcalau12i $rd, %ld_pc_hi20(sym)
-  // addi.w/d $rd, $rd, %got_pc_lo12(sym)
+  //
+  // 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)
   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_LD_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::ADDI_D : LoongArch::ADDI_W;
+  unsigned FlagsHi =
+      Has32S ? LoongArchII::MO_LD_PC_HI : LoongArchII::MO_LD_PCADD_HI;
+  unsigned FlagsLo =
+      Has32S ? LoongArchII::MO_GOT_PC_LO : LoongArchII::MO_LD_PCADD_LO;
+  return expandPcaxxu12iInstPair(MBB, MBBI, NextMBBI, OpcodeHi, OpcodeLo,
+                                 FlagsHi, FlagsLo);
 }
 
 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
@@ -462,13 +525,26 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
                                   LoongArchII::MO_GD_PC_HI);
 
   // Code Sequence:
-  // pcalau12i $rd, %gd_pc_hi20(sym)
-  // addi.w/d $rd, $rd, %got_pc_lo12(sym)
+  //
+  // 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)
   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_GD_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::ADDI_D : LoongArch::ADDI_W;
+  unsigned FlagsHi =
+      Has32S ? LoongArchII::MO_GD_PC_HI : LoongArchII::MO_GD_PCADD_HI;
+  unsigned FlagsLo =
+      Has32S ? LoongArchII::MO_GOT_PC_LO : LoongArchII::MO_GD_PCADD_LO;
+  return expandPcaxxu12iInstPair(MBB, MBBI, NextMBBI, OpcodeHi, OpcodeLo,
+                                 FlagsHi, FlagsLo);
 }
 
 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
@@ -479,20 +555,24 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
   DebugLoc DL = MI.getDebugLoc();
 
   const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
+  bool Has32S = STI.hasFeature(LoongArch::Feature32S);
+  bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
+  unsigned PCA = Has32S ? LoongArch::PCALAU12I : LoongArch::PCADDU12I;
   unsigned ADD = STI.is64Bit() ? LoongArch::ADD_D : LoongArch::ADD_W;
   unsigned ADDI = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
   unsigned LD = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
-  bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
+  unsigned MO =
+      Has32S ? LoongArchII::MO_DESC_PC_HI : LoongArchII::MO_DESC_PCADD_HI;
 
   Register DestReg = MI.getOperand(0).getReg();
   Register Tmp1Reg =
       MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
   MachineOperand &Symbol = MI.getOperand(Large ? 2 : 1);
 
-  BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), Tmp1Reg)
-      .addDisp(Symbol, 0,
-               LoongArchII::encodeFlags(LoongArchII::MO_DESC_PC_HI,
-                                        EnableRelax && !Large));
+  MachineInstr *PCAMI =
+      BuildMI(MBB, MBBI, DL, TII->get(PCA), Tmp1Reg)
+          .addDisp(Symbol, 0,
+                   LoongArchII::encodeFlags(MO, EnableRelax && !Large));
 
   if (Large) {
     // Code Sequence:
@@ -527,16 +607,35 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
         .addReg(Tmp4Reg);
   } else {
     // Code Sequence:
-    // pcalau12i $a0, %desc_pc_hi20(sym)
-    // addi.w/d  $a0, $a0, %desc_pc_lo12(sym)
-    // ld.w/d    $ra, $a0, %desc_ld(sym)
-    // jirl      $ra, $ra, %desc_call(sym)
-    // add.w/d   $dst, $a0, $tp
-    BuildMI(MBB, MBBI, DL, TII->get(ADDI), LoongArch::R4)
-        .addReg(Tmp1Reg)
-        .addDisp(
-            Symbol, 0,
-            LoongArchII::encodeFlags(LoongArchII::MO_DESC_PC_LO, EnableRelax));
+    //
+    // for la32r expands to:
+    // .Lpcadd_hi:
+    //   pcaddu12i $a0, %desc_pcadd_hi20(sym)
+    //   addi.w    $a0, $a0, %desc_pcadd_lo12(.Lpcadd_hi)
+    //   ld.w      $ra, $a0, %desc_ld(sym)
+    //   jirl      $ra, $ra, %desc_call(sym)
+    //   add.w     $dst, $a0, $tp
+    //
+    // for la32s and la64 expands to:
+    //   pcalau12i $a0, %desc_pc_hi20(sym)
+    //   addi.w/d  $a0, $a0, %desc_pc_lo12(sym)
+    //   ld.w/d    $ra, $a0, %desc_ld(sym)
+    //   jirl      $ra, $ra, %desc_call(sym)
+    //   add.w/d   $dst, $a0, $tp
+    if (Has32S) {
+      BuildMI(MBB, MBBI, DL, TII->get(ADDI), LoongArch::R4)
+          .addReg(Tmp1Reg)
+          .addDisp(Symbol, 0,
+                   LoongArchII::encodeFlags(LoongArchII::MO_DESC_PC_LO,
+                                            EnableRelax));
+    } else {
+      MCSymbol *PCASymbol = MF->getContext().createNamedTempSymbol("pcadd_hi");
+      PCAMI->setPreInstrSymbol(*MF, PCASymbol);
+      BuildMI(MBB, MBBI, DL, TII->get(ADDI), LoongArch::R4)
+          .addReg(Tmp1Reg)
+          .addSym(PCASymbol, LoongArchII::encodeFlags(
+                                 LoongArchII::MO_DESC_PCADD_LO, EnableRelax));
+    }
   }
 
   BuildMI(MBB, MBBI, DL, TII->get(LD), LoongArch::R1)
@@ -646,8 +745,8 @@ void LoongArchPreRAExpandPseudo::annotateTableJump(
     }
   };
 
-  // FindDepth = 3, probably sufficient.
-  FindJTIMI(&*MBBI, /*FindDepth=*/3);
+  // FindDepth = 4, probably sufficient.
+  FindJTIMI(&*MBBI, /*FindDepth=*/4);
 }
 
 class LoongArchExpandPseudo : public MachineFunctionPass {
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 6cc2f9175c6b7..f598e1cf2b57e 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -3681,13 +3681,23 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
   case CodeModel::Small:
   case CodeModel::Medium:
     if (IsLocal) {
-      // This generates the pattern (PseudoLA_PCREL sym), which expands to
-      // (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)).
+      // This generates the pattern (PseudoLA_PCREL sym), which
+      //
+      // for la32r expands to:
+      //   (addi.w (pcaddu12i %pcadd_hi20(sym)) %pcadd_lo12(.Lpcadd_hi)).
+      //
+      // for la32s and la64 expands to:
+      //   (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)).
       Load = SDValue(
           DAG.getMachineNode(LoongArch::PseudoLA_PCREL, DL, Ty, Addr), 0);
     } else {
-      // This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d
-      // (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
+      // This generates the pattern (PseudoLA_GOT sym), which
+      //
+      // for la32r expands to:
+      //   (ld.w (pcaddu12i %got_pcadd_hi20(sym)) %pcadd_lo12(.Lpcadd_hi)).
+      //
+      // for la32s and la64 expands to:
+      //   (ld.w/d (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
       Load =
           SDValue(DAG.getMachineNode(LoongArch::PseudoLA_GOT, DL, Ty, Addr), 0);
     }
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
index 39e105b5db4ce..04234e6f5ad58 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/LoongArchMatInt.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/CodeGen/StackMaps.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInstBuilder.h"
 
 using namespace llvm;
@@ -630,30 +631,40 @@ void LoongArchInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
   const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
   LoongArchMachineFunctionInfo *LAFI =
       MF->getInfo<LoongArchMachineFunctionInfo>();
+  bool Has32S = STI.hasFeature(LoongArch::Feature32S);
 
   if (!isInt<32>(BrOffset))
     report_fatal_error(
         "Branch offsets outside of the signed 32-bit range not supported");
 
   Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
+  MachineInstr *PCAI = nullptr;
+  MachineInstr *ADDI = nullptr;
   auto II = MBB.end();
-
-  MachineInstr &PCALAU12I =
-      *BuildMI(MBB, II, DL, get(LoongArch::PCALAU12I), ScratchReg)
-           .addMBB(&DestBB, LoongArchII::MO_PCREL_HI);
-  MachineInstr &ADDI =
-      *BuildMI(MBB, II, DL,
-               get(STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W),
-               ScratchReg)
-           .addReg(ScratchReg)
-           .addMBB(&DestBB, LoongArchII::MO_PCREL_LO);
+  unsigned ADDIOp = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+
+  if (Has32S) {
+    PCAI = BuildMI(MBB, II, DL, get(LoongArch::PCALAU12I), ScratchReg)
+               .addMBB(&DestBB, LoongArchII::MO_PCREL_HI);
+    ADDI = BuildMI(MBB, II, DL, get(ADDIOp), ScratchReg)
+               .addReg(ScratchReg)
+               .addMBB(&DestBB, LoongArchII::MO_PCREL_LO);
+  } else {
+    MCSymbol *PCAddSymbol = MF->getContext().createNamedTempSymbol("pcadd_hi");
+    PCAI = BuildMI(MBB, II, DL, get(LoongArch::PCADDU12I), ScratchReg)
+               .addMBB(&DestBB, LoongArchII::MO_PCADD_HI);
+    PCAI->setPreInstrSymbol(*MF, PCAddSymbol);
+    ADDI = BuildMI(MBB, II, DL, get(ADDIOp), ScratchReg)
+               .addReg(ScratchReg)
+               .addSym(PCAddSymbol, LoongArchII::MO_PCADD_LO);
+  }
   BuildMI(MBB, II, DL, get(LoongArch::PseudoBRIND))
       .addReg(ScratchReg, RegState::Kill)
       .addImm(0);
 
   RS->enterBasicBlockEnd(MBB);
   Register Scav = RS->scavengeRegisterBackwards(
-      LoongArch::GPRRegClass, PCALAU12I.getIterator(), /*RestoreAfter=*/false,
+      LoongArch::GPRRegClass, PCAI->getIterator(), /*RestoreAfter=*/false,
       /*SPAdj=*/0, /*AllowSpill=*/false);
   if (Scav != LoongArch::NoRegister)
     RS->setRegUsed(Scav);
@@ -664,12 +675,13 @@ void LoongArchInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
     int FrameIndex = LAFI->getBranchRelaxationSpillFrameIndex();
     if (FrameIndex == -1)
       report_fatal_error("The function size is incorrectly estimated.");
-    storeRegToStackSlot(MBB, PCALAU12I, Scav, /*IsKill=*/true, FrameIndex,
+    storeRegToStackSlot(MBB, PCAI, Scav, /*IsKill=*/true, FrameIndex,
                         &LoongArch::GPRRegClass, Register());
-    TRI->eliminateFrameIndex(std::prev(PCALAU12I.getIterator()),
+    TRI->eliminateFrameIndex(std::prev(PCAI->getIterator()),
                              /*SpAdj=*/0, /*FIOperandNum=*/1);
-    PCALAU12I.getOperand(1).setMBB(&RestoreBB);
-    ADDI.getOperand(2).setMBB(&RestoreBB);
+    PCAI->getOperand(1).setMBB(&RestoreBB);
+    if (Has32S)
+      ADDI->getOperand(2).setMBB(&RestoreBB);
     loadRegFromStackSlot(RestoreBB, RestoreBB.end(), Scav, FrameIndex,
                          &LoongArch::GPRRegClass, Register());
     TRI->eliminateFrameIndex(RestoreBB.back(),
@@ -754,7 +766,19 @@ LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
       {MO_DESC_CALL, "loongarch-desc-call"},
       {MO_LE_HI_R, "loongarch-le-hi-r"},
       {MO_LE_ADD_R, "loongarch-le-add-r"},
-      {MO_LE_LO_R, "loongarch-le-lo-r"}};
+      {MO_LE_LO_R, "loongarch-le-lo-r"},
+      {MO_PCADD_HI, "loongarch-pcadd-hi"},
+      {MO_PCADD_LO, "loongarch-pcadd-lo"},
+      {MO_GOT_PCADD_HI, "loongarch-got-pcadd-hi"},
+      {MO_GOT_PCADD_LO, "loongarch-got-pcadd-lo"},
+      {MO_IE_PCADD_HI, "loongarch-ie-pcadd-hi"},
+      {MO_IE_PCADD_LO, "loongarch-ie-pcadd-lo"},
+      {MO_LD_PCADD_HI, "loongarch-ld-pcadd-hi"},
+      {MO_LD_PCADD_LO, "loongarch-ld-pcadd-lo"},
+      {MO_GD_PCADD_HI, "loongarch-gd-pcadd-hi"},
+      {MO_GD_PCADD_LO, "loongarch-gd-pcadd-lo"},
+      {MO_DESC_PCADD_HI, "loongarch-pcadd-desc-hi"},
+      {MO_DESC_PCADD_LO, "loongarch-pcadd-desc-lo"}};
   return ArrayRef(TargetFlags);
 }
 
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 0923cfd87050f..555dc31e77755 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -474,6 +474,10 @@ def simm20_lu32id : SImm20Operand {
   let ParserMatchClass = SImmAsmOperand<20, "lu32id">;
 }
 
+def simm20_pcaddu12i : SImm20Operand {
+  let ParserMatchClass = SImmAsmOperand<20, "pcaddu12i">;
+}
+
 def simm20_pcaddu18i : SImm20Operand {
   let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">;
 }
@@ -855,7 +859,7 @@ def SLT  : ALU_3R<0x00120000>;
 def SLTU : ALU_3R<0x00128000>;
 def SLTI  : ALU_2RI12<0x02000000, simm12>;
 def SLTUI : ALU_2RI12<0x02400000, simm12>;
-def PCADDU12I : ALU_1RI20<0x1c000000, simm20>;
+def PCADDU12I : ALU_1RI20<0x1c000000, simm20_pcaddu12i>;
 def AND  : ALU_3R<0x00148000>;
 def OR   : ALU_3R<0x00150000>;
 def NOR  : ALU_3R<0x00140000>;
diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
index ae4090784a9f2..6f9c5070f1768 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
@@ -125,6 +125,42 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
   case LoongArchII::MO_LE_LO_R:
     Kind = ELF::R_LARCH_TLS_LE_LO12_R;
     break;
+  case LoongArchII::MO_PCADD_HI:
+    Kind = ELF::R_LARCH_PCADD_HI20;
+    break;
+  case LoongArchII::MO_PCADD_LO:
+    Kind = ELF::R_LARCH_PCADD_LO12;
+    break;
+  case LoongArchII::MO_GOT_PCADD_HI:
+    Kind = ELF::R_LARCH_GOT_PCADD_HI20;
+    break;
+  case LoongArchII::MO_GOT_PCADD_LO:
+    Kind = ELF::R_LARCH_GOT_PCADD_LO12;
+    break;
+  case LoongArchII::MO_IE_PCADD_HI:
+    Kind = ELF::R_LARCH_TLS_IE_PCADD_HI20;
+    break;
+  case LoongArchII::MO_IE_PCADD_LO:
+    Kind = ELF::R_LARCH_TLS_IE_PCADD_LO12;
+    break;
+  case LoongArchII::MO_LD_PCADD_HI:
+    Kind = ELF::R_LARCH_TLS_LD_PCADD_HI20;
+    break;
+  case LoongArchII::MO_LD_PCADD_LO:
+    Kind = ELF::R_LARCH_TLS_LD_PCADD_LO12;
+    break;
+  case LoongArchII::MO_GD_PCADD_HI:
+    Kind = ELF::R_LARCH_TLS_GD_PCADD_HI20;
+    break;
+  case LoongArchII::MO_GD_PCADD_LO:
+    Kind = ELF::R_LARCH_TLS_GD_PCADD_LO12;
+    break;
+  case LoongArchII::MO_DESC_PCADD_HI:
+    Kind = ELF::R_LARCH_TLS_DESC_PCADD_HI20;
+    break;
+  case LoongArchII::MO_DESC_PCADD_LO:
+    Kind = ELF::R_LARCH_TLS_DESC_PCADD_LO12;
+    break;
     // TODO: Handle more target-flags.
   }
 
@@ -178,6 +214,9 @@ bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
   case MachineOperand::MO_JumpTableIndex:
     MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP);
     break;
+  case MachineOperand::MO_MCSymbol:
+    MCOp = lowerSymbolOperand(MO, MO.getMCSymbol(), AP);
+    break;
   }
   return true;
 }
diff --git a/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
index a2292d016efa1..3b111d29316d6 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
@@ -76,10 +76,23 @@ char LoongArchMergeBaseOffsetOpt::ID = 0;
 INITIALIZE_PASS(LoongArchMergeBaseOffsetOpt, DEBUG_TYPE,
                 LoongArch_MERGE_BASE_OFFSET_NAME, false, false)
 
+static inline bool isPCAddLo(unsigned Flags) {
+  switch (Flags) {
+  case LoongArchII::MO_PCADD_LO:
+  case LoongArchII::MO_GOT_PCADD_LO:
+  case LoongArchII::MO_IE_PCADD_LO:
+  case LoongArchII::MO_LD_PCADD_LO:
+  case LoongArchII::MO_GD_PCADD_LO:
+  case LoongArchII::MO_DESC_PCADD_LO:
+    return true;
+  }
+  return false;
+}
+
 // Detect either of the patterns:
 //
 // 1. (small/medium):
-//   pcalau12i vreg1, %pc_hi20(s)
+//   pcaxxu12i vreg1, %pc_hi20(s)
 //   addi.d    vreg2, vreg1, %pc_lo12(s)
 //
 // 2. (large):
@@ -102,11 +115,13 @@ bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
                                                  MachineInstr *&Lo20,
                                                  MachineInstr *&Hi12,
                                                  MachineInstr *&Last) {
-  if (Hi20.getOpcode() != LoongArch::PCALAU12I)
+  if (Hi20.getOpcode() != LoongArch::PCALAU12I &&
+      Hi20.getOpcode() != LoongArch::PCADDU12I)
     return false;
 
   const MachineOperand &Hi20Op1 = Hi20.getOperand(1);
-  if (LoongArchII::getDirectFlags(Hi20Op1) != LoongArchII::MO_PCREL_HI)
+  if (LoongArchII::getDirectFlags(Hi20Op1) != LoongArchII::MO_PCREL_HI &&
+      LoongArchII::getDirectFlags(Hi20Op1) != LoongArchII::MO_PCADD_HI)
     return false;
 
   auto isGlobalOrCPIOrBlockAddress = [](const MachineOperand &Op) {
@@ -157,8 +172,10 @@ bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
   }
 
   const MachineOperand &Lo12Op2 = Lo12->getOperand(2);
-  assert(Hi20.getOpcode() == LoongArch::PCALAU12I);
-  if (LoongArchII::getDirectFlags(Lo12Op2) != LoongArchII::MO_PCREL_LO ||
+  assert(Hi20.getOpcode() == LoongArch::PCALAU12I ||
+         Hi20.getOpcode() == LoongArch::PCADDU12I);
+  if ((LoongArchII::getDirectFlags(Lo12Op2) != LoongArchII::MO_PCREL_LO &&
+       !isPCAddLo(LoongArchII::getDirectFlags(Lo12Op2))) ||
       !(isGlobalOrCPIOrBlockAddress(Lo12Op2) || Lo12Op2.isMCSymbol()) ||
       Lo12Op2.getOffset() != 0)
     return false;
@@ -258,8 +275,10 @@ void LoongArchMergeBaseOffsetOpt::foldOffset(
     MachineInstr *&Hi12, MachineInstr *&Last, MachineInstr &Tail,
     int64_t Offset) {
   // Put the offset back in Hi and the Lo
+  MachineOperand &Lo12Op2 = Lo12.getOperand(2);
   Hi20.getOperand(1).setOffset(Offset);
-  Lo12.getOperand(2).setOffset(Offset);
+  if (!isPCAddLo(LoongArchII::getDirectFlags(Lo12Op2)))
+    Lo12Op2.setOffset(Offset);
   if (Lo20 && Hi12) {
     Lo20->getOperand(2).setOffset(Offset);
     Hi12->getOperand(2).setOffset(Offset);
@@ -298,7 +317,7 @@ void LoongArchMergeBaseOffsetOpt::foldOffset(
 //
 //        Base address lowering is of the form:
 //           1) pcala:
-//             Hi20:  pcalau12i vreg1, %pc_hi20(s)
+//             Hi20:  pcaxxu12i vreg1, %pc_hi20(s)
 //        +--- Lo12:  addi.d vreg2, vreg1, %pc_lo12(s)
 //        |    Lo20:  lu32i.d vreg2, %pc64_lo20(s) !
 //        +--- Hi12:  lu52i.d vreg2, vreg2, %pc64_hi12(s) !
@@ -426,7 +445,7 @@ bool LoongArchMergeBaseOffsetOpt::detectAndFoldOffset(MachineInstr &Hi20,
 
   // Look for arithmetic instructions we can get an offset from.
   // We might be able to remove the arithmetic instructions by folding the
-  // offset into the PCALAU12I+(ADDI/ADDI+LU32I+LU52I) or
+  // offset into the PCAXXU12I+(ADDI/ADDI+LU32I+LU52I) or
   // LU12I_W+PseudoAddTPRel+ADDI.
   if (!MRI->hasOneUse(DestReg))
     return false;
@@ -548,13 +567,13 @@ bool LoongArchMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi20,
   //
   // 1. (small/medium):
   //  1.1. pcala
-  //   pcalau12i vreg1, %pc_hi20(s)
+  //   pcaxxu12i vreg1, %pc_hi20(s)
   //   addi.d    vreg2, vreg1, %pc_lo12(s)
   //   ld.w      vreg3, 8(vreg2)
   //
   //   =>
   //
-  //   pcalau12i vreg1, %pc_hi20(s+8)
+  //   pcalxx12i vreg1, %pc_hi20(s+8)
   //   ld.w      vreg3, vreg1, %pc_lo12(s+8)(vreg1)
   //
   //  1.2. tls-le
@@ -708,13 +727,13 @@ bool LoongArchMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi20,
   // be relaxed after being optimized.
   //
   // For example:
-  //   pcalau12i $a0, %pc_hi20(symbol)
+  //   pcaxxu12i $a0, %pc_hi20(symbol)
   //   addi.d $a0, $a0, %pc_lo12(symbol)
   //   ld.w $a0, $a0, 0
   //
   //   =>
   //
-  //   pcalau12i $a0, %pc_hi20(symbol)
+  //   pcaxxu12i $a0, %pc_hi20(symbol)
   //   ld.w $a0, $a0, %pc_lo12(symbol)
   //
   // Code sequence optimized before can be relax by linker. But after being
@@ -722,12 +741,14 @@ bool LoongArchMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi20,
   // carried by them.
   Hi20.getOperand(1).setOffset(NewOffset);
   MachineOperand &ImmOp = Lo12.getOperand(2);
-  ImmOp.setOffset(NewOffset);
+  if (!isPCAddLo(LoongArchII::getDirectFlags(ImmOp)))
+    ImmOp.setOffset(NewOffset);
   if (Lo20 && Hi12) {
     Lo20->getOperand(2).setOffset(NewOffset);
     Hi12->getOperand(2).setOffset(NewOffset);
   }
-  if (Hi20.getOpcode() == LoongArch::PCALAU12I) {
+  if (Hi20.getOpcode() == LoongArch::PCADDU12I ||
+      Hi20.getOpcode() == LoongArch::PCALAU12I) {
     Hi20.getOperand(1).setTargetFlags(
         LoongArchII::getDirectFlags(Hi20.getOperand(1)));
     ImmOp.setTargetFlags(LoongArchII::getDirectFlags(ImmOp));
@@ -789,7 +810,8 @@ bool LoongArchMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi20,
     return true;
   }
 
-  if (Hi20.getOpcode() == LoongArch::PCALAU12I) {
+  if (Hi20.getOpcode() == LoongArch::PCADDU12I ||
+      Hi20.getOpcode() == LoongArch::PCALAU12I) {
     MRI->replaceRegWith(Lo12.getOperand(0).getReg(),
                         Hi20.getOperand(0).getReg());
   } else if (Hi20.getOpcode() == LoongArch::LU12I_W) {
@@ -816,7 +838,8 @@ bool LoongArchMergeBaseOffsetOpt::runOnMachineFunction(MachineFunction &Fn) {
       MachineInstr *Lo20 = nullptr;
       MachineInstr *Hi12 = nullptr;
       MachineInstr *Last = nullptr;
-      if (Hi20.getOpcode() == LoongArch::PCALAU12I) {
+      if (Hi20.getOpcode() == LoongArch::PCADDU12I ||
+          Hi20.getOpcode() == LoongArch::PCALAU12I) {
         // Detect foldable pcala code sequence in small/medium/large code model.
         if (!detectFoldable(Hi20, Lo12, Lo20, Hi12, Last))
           continue;
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
index 99d7df63fce04..e73b49efc5895 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
@@ -59,6 +59,18 @@ enum {
   MO_LE_HI_R,
   MO_LE_ADD_R,
   MO_LE_LO_R,
+  MO_PCADD_HI,
+  MO_PCADD_LO,
+  MO_GOT_PCADD_HI,
+  MO_GOT_PCADD_LO,
+  MO_IE_PCADD_HI,
+  MO_IE_PCADD_LO,
+  MO_LD_PCADD_HI,
+  MO_LD_PCADD_LO,
+  MO_GD_PCADD_HI,
+  MO_GD_PCADD_LO,
+  MO_DESC_PCADD_HI,
+  MO_DESC_PCADD_LO,
   // TODO: Add more flags.
 
   // Used to differentiate between target-specific "direct" flags and "bitmask"
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
index 3f9bea5d69bf9..25e91ac2a2dad 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
@@ -135,6 +135,30 @@ static StringRef getLoongArchSpecifierName(uint16_t S) {
     return "gd_pcrel_20";
   case ELF::R_LARCH_TLS_DESC_PCREL20_S2:
     return "desc_pcrel_20";
+  case ELF::R_LARCH_PCADD_HI20:
+    return "pcadd_hi20";
+  case ELF::R_LARCH_PCADD_LO12:
+    return "pcadd_lo12";
+  case ELF::R_LARCH_GOT_PCADD_HI20:
+    return "got_pcadd_hi20";
+  case ELF::R_LARCH_GOT_PCADD_LO12:
+    return "got_pcadd_lo12";
+  case ELF::R_LARCH_TLS_IE_PCADD_HI20:
+    return "ie_pcadd_hi20";
+  case ELF::R_LARCH_TLS_IE_PCADD_LO12:
+    return "ie_pcadd_lo12";
+  case ELF::R_LARCH_TLS_LD_PCADD_HI20:
+    return "ld_pcadd_hi20";
+  case ELF::R_LARCH_TLS_LD_PCADD_LO12:
+    return "ld_pcadd_lo12";
+  case ELF::R_LARCH_TLS_GD_PCADD_HI20:
+    return "gd_pcadd_hi20";
+  case ELF::R_LARCH_TLS_GD_PCADD_LO12:
+    return "gd_pcadd_lo12";
+  case ELF::R_LARCH_TLS_DESC_PCADD_HI20:
+    return "desc_pcadd_hi20";
+  case ELF::R_LARCH_TLS_DESC_PCADD_LO12:
+    return "desc_pcadd_lo12";
   }
 }
 
@@ -195,6 +219,18 @@ LoongArchMCExpr::Specifier LoongArch::parseSpecifier(StringRef name) {
       .Case("ld_pcrel_20", ELF::R_LARCH_TLS_LD_PCREL20_S2)
       .Case("gd_pcrel_20", ELF::R_LARCH_TLS_GD_PCREL20_S2)
       .Case("desc_pcrel_20", ELF::R_LARCH_TLS_DESC_PCREL20_S2)
+      .Case("pcadd_hi20", ELF::R_LARCH_PCADD_HI20)
+      .Case("pcadd_lo12", ELF::R_LARCH_PCADD_LO12)
+      .Case("got_pcadd_hi20", ELF::R_LARCH_GOT_PCADD_HI20)
+      .Case("got_pcadd_lo12", ELF::R_LARCH_GOT_PCADD_LO12)
+      .Case("ie_pcadd_hi20", ELF::R_LARCH_TLS_IE_PCADD_HI20)
+      .Case("ie_pcadd_lo12", ELF::R_LARCH_TLS_IE_PCADD_LO12)
+      .Case("ld_pcadd_hi20", ELF::R_LARCH_TLS_LD_PCADD_HI20)
+      .Case("ld_pcadd_lo12", ELF::R_LARCH_TLS_LD_PCADD_LO12)
+      .Case("gd_pcadd_hi20", ELF::R_LARCH_TLS_GD_PCADD_HI20)
+      .Case("gd_pcadd_lo12", ELF::R_LARCH_TLS_GD_PCADD_LO12)
+      .Case("desc_pcadd_hi20", ELF::R_LARCH_TLS_DESC_PCADD_HI20)
+      .Case("desc_pcadd_lo12", ELF::R_LARCH_TLS_DESC_PCADD_LO12)
       .Default(0);
 }
 
diff --git a/llvm/test/CodeGen/LoongArch/block-address.ll b/llvm/test/CodeGen/LoongArch/block-address.ll
index 114cbb73a5125..6b8c8ce93f944 100644
--- a/llvm/test/CodeGen/LoongArch/block-address.ll
+++ b/llvm/test/CodeGen/LoongArch/block-address.ll
@@ -7,11 +7,13 @@
 define void @test_blockaddress() nounwind {
 ; LA32-LABEL: test_blockaddress:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(addr)
-; LA32-NEXT:    pcalau12i $a1, %pc_hi20(.Ltmp0)
-; LA32-NEXT:    addi.w $a1, $a1, %pc_lo12(.Ltmp0)
-; LA32-NEXT:    st.w $a1, $a0, %pc_lo12(addr)
-; LA32-NEXT:    ld.w $a0, $a0, %pc_lo12(addr)
+; LA32-NEXT:  .Lpcadd_hi0:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(addr)
+; LA32-NEXT:  .Lpcadd_hi1:
+; LA32-NEXT:    pcaddu12i $a1, %pcadd_hi20(.Ltmp0)
+; LA32-NEXT:    addi.w $a1, $a1, %pcadd_lo12(.Lpcadd_hi1)
+; LA32-NEXT:    st.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi0)
+; LA32-NEXT:    ld.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-NEXT:    jr $a0
 ; LA32-NEXT:  .Ltmp0: # Block address taken
 ; LA32-NEXT:  .LBB0_1: # %block
diff --git a/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll b/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll
index 5c96d5c416b9c..e37863efdf5f3 100644
--- a/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll
+++ b/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll
@@ -122,9 +122,10 @@ define void @relax_b28_spill() {
 ; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:    beq $s7, $s8, .LBB0_1
 ; CHECK-NEXT:  # %bb.4:
-; CHECK-NEXT:    st.w $t8, $sp, 0
-; CHECK-NEXT:    pcalau12i $t8, %pc_hi20(.LBB0_5)
-; CHECK-NEXT:    addi.w $t8, $t8, %pc_lo12(.LBB0_5)
+; CHECK-NEXT:    st.w $t8, $sp, 0 # 4-byte Folded Spill
+; CHECK-NEXT:  .Lpcadd_hi0:
+; CHECK-NEXT:    pcaddu12i $t8, %pcadd_hi20(.LBB0_5)
+; CHECK-NEXT:    addi.w $t8, $t8, %pcadd_lo12(.Lpcadd_hi0)
 ; CHECK-NEXT:    jr $t8
 ; CHECK-NEXT:  .LBB0_1: # %iftrue
 ; CHECK-NEXT:    #APP
@@ -132,7 +133,7 @@ define void @relax_b28_spill() {
 ; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:    b .LBB0_3
 ; CHECK-NEXT:  .LBB0_5: # %iffalse
-; CHECK-NEXT:    ld.w $t8, $sp, 0
+; CHECK-NEXT:    ld.w $t8, $sp, 0 # 4-byte Folded Reload
 ; CHECK-NEXT:  # %bb.2: # %iffalse
 ; CHECK-NEXT:    #APP
 ; CHECK-NEXT:    # reg use $zero
diff --git a/llvm/test/CodeGen/LoongArch/branch-relaxation.ll b/llvm/test/CodeGen/LoongArch/branch-relaxation.ll
index f88603b6c79db..ffeaa5283ada8 100644
--- a/llvm/test/CodeGen/LoongArch/branch-relaxation.ll
+++ b/llvm/test/CodeGen/LoongArch/branch-relaxation.ll
@@ -119,8 +119,9 @@ define i32 @relax_b28(i1 %a) {
 ; LA32R-NEXT:    andi $a0, $a0, 1
 ; LA32R-NEXT:    bne $a0, $zero, .LBB2_1
 ; LA32R-NEXT:  # %bb.3:
-; LA32R-NEXT:    pcalau12i $a0, %pc_hi20(.LBB2_2)
-; LA32R-NEXT:    addi.w $a0, $a0, %pc_lo12(.LBB2_2)
+; LA32R-NEXT:  .Lpcadd_hi0:
+; LA32R-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LBB2_2)
+; LA32R-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32R-NEXT:    jr $a0
 ; LA32R-NEXT:  .LBB2_1: # %iftrue
 ; LA32R-NEXT:    ori $a0, $zero, 1
diff --git a/llvm/test/CodeGen/LoongArch/calling-conv-ilp32d.ll b/llvm/test/CodeGen/LoongArch/calling-conv-ilp32d.ll
index 95f9aa514b340..f8b6dd3fd038f 100644
--- a/llvm/test/CodeGen/LoongArch/calling-conv-ilp32d.ll
+++ b/llvm/test/CodeGen/LoongArch/calling-conv-ilp32d.ll
@@ -75,14 +75,18 @@ define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
 ; CHECK-NEXT:    lu12i.w $a0, 262400
 ; CHECK-NEXT:    fmov.d $fa3, $fa7
 ; CHECK-NEXT:    movgr2frh.w $fa3, $a0
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_0)
-; CHECK-NEXT:    fld.d $fa2, $a0, %pc_lo12(.LCPI3_0)
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_1)
-; CHECK-NEXT:    fld.d $fa4, $a0, %pc_lo12(.LCPI3_1)
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_2)
-; CHECK-NEXT:    fld.d $fa5, $a0, %pc_lo12(.LCPI3_2)
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_3)
-; CHECK-NEXT:    fld.d $fa6, $a0, %pc_lo12(.LCPI3_3)
+; CHECK-NEXT:  .Lpcadd_hi0:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_0)
+; CHECK-NEXT:    fld.d $fa2, $a0, %pcadd_lo12(.Lpcadd_hi0)
+; CHECK-NEXT:  .Lpcadd_hi1:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_1)
+; CHECK-NEXT:    fld.d $fa4, $a0, %pcadd_lo12(.Lpcadd_hi1)
+; CHECK-NEXT:  .Lpcadd_hi2:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_2)
+; CHECK-NEXT:    fld.d $fa5, $a0, %pcadd_lo12(.Lpcadd_hi2)
+; CHECK-NEXT:  .Lpcadd_hi3:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_3)
+; CHECK-NEXT:    fld.d $fa6, $a0, %pcadd_lo12(.Lpcadd_hi3)
 ; CHECK-NEXT:    lu12i.w $a0, 262656
 ; CHECK-NEXT:    movgr2frh.w $fa7, $a0
 ; CHECK-NEXT:    lu12i.w $a1, 262688
@@ -139,14 +143,18 @@ define i32 @caller_double_on_stack_exhausted_fprs_gprs() nounwind {
 ; CHECK-NEXT:    movgr2frh.w $fa3, $a0
 ; CHECK-NEXT:    lu12i.w $a0, 262656
 ; CHECK-NEXT:    movgr2frh.w $fa7, $a0
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; CHECK-NEXT:    fld.d $fa2, $a0, %pc_lo12(.LCPI5_0)
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_1)
-; CHECK-NEXT:    fld.d $fa4, $a0, %pc_lo12(.LCPI5_1)
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_2)
-; CHECK-NEXT:    fld.d $fa5, $a0, %pc_lo12(.LCPI5_2)
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_3)
-; CHECK-NEXT:    fld.d $fa6, $a0, %pc_lo12(.LCPI5_3)
+; CHECK-NEXT:  .Lpcadd_hi4:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_0)
+; CHECK-NEXT:    fld.d $fa2, $a0, %pcadd_lo12(.Lpcadd_hi4)
+; CHECK-NEXT:  .Lpcadd_hi5:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_1)
+; CHECK-NEXT:    fld.d $fa4, $a0, %pcadd_lo12(.Lpcadd_hi5)
+; CHECK-NEXT:  .Lpcadd_hi6:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_2)
+; CHECK-NEXT:    fld.d $fa5, $a0, %pcadd_lo12(.Lpcadd_hi6)
+; CHECK-NEXT:  .Lpcadd_hi7:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_3)
+; CHECK-NEXT:    fld.d $fa6, $a0, %pcadd_lo12(.Lpcadd_hi7)
 ; CHECK-NEXT:    lu12i.w $a1, 262688
 ; CHECK-NEXT:    lu12i.w $a3, 262720
 ; CHECK-NEXT:    lu12i.w $a5, 262752
diff --git a/llvm/test/CodeGen/LoongArch/code-models.ll b/llvm/test/CodeGen/LoongArch/code-models.ll
index f4459655e6138..907961d449f38 100644
--- a/llvm/test/CodeGen/LoongArch/code-models.ll
+++ b/llvm/test/CodeGen/LoongArch/code-models.ll
@@ -1,96 +1,146 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 -mattr=+d --code-model=small < %s | \
+; RUN:    FileCheck --check-prefix=LA32-SMALL %s
+; RUN: llc --mtriple=loongarch32 -mattr=+d --code-model=medium < %s | \
+; RUN:    FileCheck --check-prefix=LA32-MEDIUM %s
 ; RUN: llc --mtriple=loongarch64 -mattr=+d --code-model=small < %s | \
-; RUN:    FileCheck --check-prefix=SMALL %s
+; RUN:    FileCheck --check-prefix=LA64-SMALL %s
 ; RUN: llc --mtriple=loongarch64 -mattr=+d --code-model=medium < %s | \
-; RUN:    FileCheck --check-prefix=MEDIUM %s
+; RUN:    FileCheck --check-prefix=LA64-MEDIUM %s
 ; RUN: llc --mtriple=loongarch64 -mattr=+d --code-model=large < %s | \
-; RUN:    FileCheck --check-prefix=LARGE %s
+; RUN:    FileCheck --check-prefix=LA64-LARGE %s
 
 declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
 declare i32 @callee(i32)
 
 define i32 @call_globaladdress(i32 %a) nounwind {
-; SMALL-LABEL: call_globaladdress:
-; SMALL:       # %bb.0:
-; SMALL-NEXT:    addi.d $sp, $sp, -16
-; SMALL-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
-; SMALL-NEXT:    bl callee
-; SMALL-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
-; SMALL-NEXT:    addi.d $sp, $sp, 16
-; SMALL-NEXT:    ret
+; LA32-SMALL-LABEL: call_globaladdress:
+; LA32-SMALL:       # %bb.0:
+; LA32-SMALL-NEXT:    addi.w $sp, $sp, -16
+; LA32-SMALL-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32-SMALL-NEXT:    bl callee
+; LA32-SMALL-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32-SMALL-NEXT:    addi.w $sp, $sp, 16
+; LA32-SMALL-NEXT:    ret
 ;
-; MEDIUM-LABEL: call_globaladdress:
-; MEDIUM:       # %bb.0:
-; MEDIUM-NEXT:    addi.d $sp, $sp, -16
-; MEDIUM-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
-; MEDIUM-NEXT:    pcaddu18i $ra, %call36(callee)
-; MEDIUM-NEXT:    jirl $ra, $ra, 0
-; MEDIUM-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
-; MEDIUM-NEXT:    addi.d $sp, $sp, 16
-; MEDIUM-NEXT:    ret
+; LA32-MEDIUM-LABEL: call_globaladdress:
+; LA32-MEDIUM:       # %bb.0:
+; LA32-MEDIUM-NEXT:    addi.w $sp, $sp, -16
+; LA32-MEDIUM-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32-MEDIUM-NEXT:    pcaddu12i $ra, %call30(callee)
+; LA32-MEDIUM-NEXT:    jirl $ra, $ra, 0
+; LA32-MEDIUM-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32-MEDIUM-NEXT:    addi.w $sp, $sp, 16
+; LA32-MEDIUM-NEXT:    ret
 ;
-; LARGE-LABEL: call_globaladdress:
-; LARGE:       # %bb.0:
-; LARGE-NEXT:    addi.d $sp, $sp, -16
-; LARGE-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
-; LARGE-NEXT:    pcalau12i $a1, %got_pc_hi20(callee)
-; LARGE-NEXT:    addi.d $ra, $zero, %got_pc_lo12(callee)
-; LARGE-NEXT:    lu32i.d $ra, %got64_pc_lo20(callee)
-; LARGE-NEXT:    lu52i.d $ra, $ra, %got64_pc_hi12(callee)
-; LARGE-NEXT:    ldx.d $ra, $ra, $a1
-; LARGE-NEXT:    jirl $ra, $ra, 0
-; LARGE-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
-; LARGE-NEXT:    addi.d $sp, $sp, 16
-; LARGE-NEXT:    ret
+; LA64-SMALL-LABEL: call_globaladdress:
+; LA64-SMALL:       # %bb.0:
+; LA64-SMALL-NEXT:    addi.d $sp, $sp, -16
+; LA64-SMALL-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64-SMALL-NEXT:    bl callee
+; LA64-SMALL-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64-SMALL-NEXT:    addi.d $sp, $sp, 16
+; LA64-SMALL-NEXT:    ret
+;
+; LA64-MEDIUM-LABEL: call_globaladdress:
+; LA64-MEDIUM:       # %bb.0:
+; LA64-MEDIUM-NEXT:    addi.d $sp, $sp, -16
+; LA64-MEDIUM-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64-MEDIUM-NEXT:    pcaddu18i $ra, %call36(callee)
+; LA64-MEDIUM-NEXT:    jirl $ra, $ra, 0
+; LA64-MEDIUM-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64-MEDIUM-NEXT:    addi.d $sp, $sp, 16
+; LA64-MEDIUM-NEXT:    ret
+;
+; LA64-LARGE-LABEL: call_globaladdress:
+; LA64-LARGE:       # %bb.0:
+; LA64-LARGE-NEXT:    addi.d $sp, $sp, -16
+; LA64-LARGE-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64-LARGE-NEXT:    pcalau12i $a1, %got_pc_hi20(callee)
+; LA64-LARGE-NEXT:    addi.d $ra, $zero, %got_pc_lo12(callee)
+; LA64-LARGE-NEXT:    lu32i.d $ra, %got64_pc_lo20(callee)
+; LA64-LARGE-NEXT:    lu52i.d $ra, $ra, %got64_pc_hi12(callee)
+; LA64-LARGE-NEXT:    ldx.d $ra, $ra, $a1
+; LA64-LARGE-NEXT:    jirl $ra, $ra, 0
+; LA64-LARGE-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64-LARGE-NEXT:    addi.d $sp, $sp, 16
+; LA64-LARGE-NEXT:    ret
   %1 = call i32 @callee(i32 %a)
   ret i32 %1
 }
 
 define void @call_external_sym(ptr %dst) {
-; SMALL-LABEL: call_external_sym:
-; SMALL:       # %bb.0: # %entry
-; SMALL-NEXT:    addi.d $sp, $sp, -16
-; SMALL-NEXT:    .cfi_def_cfa_offset 16
-; SMALL-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
-; SMALL-NEXT:    .cfi_offset 1, -8
-; SMALL-NEXT:    ori $a2, $zero, 1000
-; SMALL-NEXT:    move $a1, $zero
-; SMALL-NEXT:    bl memset
-; SMALL-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
-; SMALL-NEXT:    addi.d $sp, $sp, 16
-; SMALL-NEXT:    ret
+; LA32-SMALL-LABEL: call_external_sym:
+; LA32-SMALL:       # %bb.0: # %entry
+; LA32-SMALL-NEXT:    addi.w $sp, $sp, -16
+; LA32-SMALL-NEXT:    .cfi_def_cfa_offset 16
+; LA32-SMALL-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32-SMALL-NEXT:    .cfi_offset 1, -4
+; LA32-SMALL-NEXT:    ori $a2, $zero, 1000
+; LA32-SMALL-NEXT:    move $a1, $zero
+; LA32-SMALL-NEXT:    bl memset
+; LA32-SMALL-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32-SMALL-NEXT:    addi.w $sp, $sp, 16
+; LA32-SMALL-NEXT:    ret
+;
+; LA32-MEDIUM-LABEL: call_external_sym:
+; LA32-MEDIUM:       # %bb.0: # %entry
+; LA32-MEDIUM-NEXT:    addi.w $sp, $sp, -16
+; LA32-MEDIUM-NEXT:    .cfi_def_cfa_offset 16
+; LA32-MEDIUM-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32-MEDIUM-NEXT:    .cfi_offset 1, -4
+; LA32-MEDIUM-NEXT:    ori $a2, $zero, 1000
+; LA32-MEDIUM-NEXT:    move $a1, $zero
+; LA32-MEDIUM-NEXT:    pcaddu12i $ra, %call30(memset)
+; LA32-MEDIUM-NEXT:    jirl $ra, $ra, 0
+; LA32-MEDIUM-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32-MEDIUM-NEXT:    addi.w $sp, $sp, 16
+; LA32-MEDIUM-NEXT:    ret
 ;
-; MEDIUM-LABEL: call_external_sym:
-; MEDIUM:       # %bb.0: # %entry
-; MEDIUM-NEXT:    addi.d $sp, $sp, -16
-; MEDIUM-NEXT:    .cfi_def_cfa_offset 16
-; MEDIUM-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
-; MEDIUM-NEXT:    .cfi_offset 1, -8
-; MEDIUM-NEXT:    ori $a2, $zero, 1000
-; MEDIUM-NEXT:    move $a1, $zero
-; MEDIUM-NEXT:    pcaddu18i $ra, %call36(memset)
-; MEDIUM-NEXT:    jirl $ra, $ra, 0
-; MEDIUM-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
-; MEDIUM-NEXT:    addi.d $sp, $sp, 16
-; MEDIUM-NEXT:    ret
+; LA64-SMALL-LABEL: call_external_sym:
+; LA64-SMALL:       # %bb.0: # %entry
+; LA64-SMALL-NEXT:    addi.d $sp, $sp, -16
+; LA64-SMALL-NEXT:    .cfi_def_cfa_offset 16
+; LA64-SMALL-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64-SMALL-NEXT:    .cfi_offset 1, -8
+; LA64-SMALL-NEXT:    ori $a2, $zero, 1000
+; LA64-SMALL-NEXT:    move $a1, $zero
+; LA64-SMALL-NEXT:    bl memset
+; LA64-SMALL-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64-SMALL-NEXT:    addi.d $sp, $sp, 16
+; LA64-SMALL-NEXT:    ret
 ;
-; LARGE-LABEL: call_external_sym:
-; LARGE:       # %bb.0: # %entry
-; LARGE-NEXT:    addi.d $sp, $sp, -16
-; LARGE-NEXT:    .cfi_def_cfa_offset 16
-; LARGE-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
-; LARGE-NEXT:    .cfi_offset 1, -8
-; LARGE-NEXT:    ori $a2, $zero, 1000
-; LARGE-NEXT:    move $a1, $zero
-; LARGE-NEXT:    pcalau12i $a3, %got_pc_hi20(memset)
-; LARGE-NEXT:    addi.d $ra, $zero, %got_pc_lo12(memset)
-; LARGE-NEXT:    lu32i.d $ra, %got64_pc_lo20(memset)
-; LARGE-NEXT:    lu52i.d $ra, $ra, %got64_pc_hi12(memset)
-; LARGE-NEXT:    ldx.d $ra, $ra, $a3
-; LARGE-NEXT:    jirl $ra, $ra, 0
-; LARGE-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
-; LARGE-NEXT:    addi.d $sp, $sp, 16
-; LARGE-NEXT:    ret
+; LA64-MEDIUM-LABEL: call_external_sym:
+; LA64-MEDIUM:       # %bb.0: # %entry
+; LA64-MEDIUM-NEXT:    addi.d $sp, $sp, -16
+; LA64-MEDIUM-NEXT:    .cfi_def_cfa_offset 16
+; LA64-MEDIUM-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64-MEDIUM-NEXT:    .cfi_offset 1, -8
+; LA64-MEDIUM-NEXT:    ori $a2, $zero, 1000
+; LA64-MEDIUM-NEXT:    move $a1, $zero
+; LA64-MEDIUM-NEXT:    pcaddu18i $ra, %call36(memset)
+; LA64-MEDIUM-NEXT:    jirl $ra, $ra, 0
+; LA64-MEDIUM-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64-MEDIUM-NEXT:    addi.d $sp, $sp, 16
+; LA64-MEDIUM-NEXT:    ret
+;
+; LA64-LARGE-LABEL: call_external_sym:
+; LA64-LARGE:       # %bb.0: # %entry
+; LA64-LARGE-NEXT:    addi.d $sp, $sp, -16
+; LA64-LARGE-NEXT:    .cfi_def_cfa_offset 16
+; LA64-LARGE-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64-LARGE-NEXT:    .cfi_offset 1, -8
+; LA64-LARGE-NEXT:    ori $a2, $zero, 1000
+; LA64-LARGE-NEXT:    move $a1, $zero
+; LA64-LARGE-NEXT:    pcalau12i $a3, %got_pc_hi20(memset)
+; LA64-LARGE-NEXT:    addi.d $ra, $zero, %got_pc_lo12(memset)
+; LA64-LARGE-NEXT:    lu32i.d $ra, %got64_pc_lo20(memset)
+; LA64-LARGE-NEXT:    lu52i.d $ra, $ra, %got64_pc_hi12(memset)
+; LA64-LARGE-NEXT:    ldx.d $ra, $ra, $a3
+; LA64-LARGE-NEXT:    jirl $ra, $ra, 0
+; LA64-LARGE-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64-LARGE-NEXT:    addi.d $sp, $sp, 16
+; LA64-LARGE-NEXT:    ret
 entry:
   call void @llvm.memset.p0.i64(ptr %dst, i8 0, i64 1000, i1 false)
   ret void
@@ -99,23 +149,32 @@ entry:
 ;; Tail call with different codemodel.
 declare i32 @callee_tail(i32 %i)
 define i32 @caller_tail(i32 %i) nounwind {
-; SMALL-LABEL: caller_tail:
-; SMALL:       # %bb.0: # %entry
-; SMALL-NEXT:    b callee_tail
+; LA32-SMALL-LABEL: caller_tail:
+; LA32-SMALL:       # %bb.0: # %entry
+; LA32-SMALL-NEXT:    b callee_tail
+;
+; LA32-MEDIUM-LABEL: caller_tail:
+; LA32-MEDIUM:       # %bb.0: # %entry
+; LA32-MEDIUM-NEXT:    pcaddu12i $t8, %call30(callee_tail)
+; LA32-MEDIUM-NEXT:    jr $t8
+;
+; LA64-SMALL-LABEL: caller_tail:
+; LA64-SMALL:       # %bb.0: # %entry
+; LA64-SMALL-NEXT:    b callee_tail
 ;
-; MEDIUM-LABEL: caller_tail:
-; MEDIUM:       # %bb.0: # %entry
-; MEDIUM-NEXT:    pcaddu18i $t8, %call36(callee_tail)
-; MEDIUM-NEXT:    jr $t8
+; LA64-MEDIUM-LABEL: caller_tail:
+; LA64-MEDIUM:       # %bb.0: # %entry
+; LA64-MEDIUM-NEXT:    pcaddu18i $t8, %call36(callee_tail)
+; LA64-MEDIUM-NEXT:    jr $t8
 ;
-; LARGE-LABEL: caller_tail:
-; LARGE:       # %bb.0: # %entry
-; LARGE-NEXT:    pcalau12i $a1, %got_pc_hi20(callee_tail)
-; LARGE-NEXT:    addi.d $a2, $zero, %got_pc_lo12(callee_tail)
-; LARGE-NEXT:    lu32i.d $a2, %got64_pc_lo20(callee_tail)
-; LARGE-NEXT:    lu52i.d $a2, $a2, %got64_pc_hi12(callee_tail)
-; LARGE-NEXT:    ldx.d $a1, $a2, $a1
-; LARGE-NEXT:    jr $a1
+; LA64-LARGE-LABEL: caller_tail:
+; LA64-LARGE:       # %bb.0: # %entry
+; LA64-LARGE-NEXT:    pcalau12i $a1, %got_pc_hi20(callee_tail)
+; LA64-LARGE-NEXT:    addi.d $a2, $zero, %got_pc_lo12(callee_tail)
+; LA64-LARGE-NEXT:    lu32i.d $a2, %got64_pc_lo20(callee_tail)
+; LA64-LARGE-NEXT:    lu52i.d $a2, $a2, %got64_pc_hi12(callee_tail)
+; LA64-LARGE-NEXT:    ldx.d $a1, $a2, $a1
+; LA64-LARGE-NEXT:    jr $a1
 entry:
   %r = tail call i32 @callee_tail(i32 %i)
   ret i32 %r
diff --git a/llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll
index 27be02c50f1c7..384c2d25135ea 100644
--- a/llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll
+++ b/llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll
@@ -810,8 +810,9 @@ define i32 @test_cttz_i32(i32 %a) nounwind {
 ; LA32R-NEXT:    ori $a1, $a1, 1329
 ; LA32R-NEXT:    mul.w $a0, $a0, $a1
 ; LA32R-NEXT:    srli.w $a0, $a0, 27
-; LA32R-NEXT:    pcalau12i $a1, %pc_hi20(.LCPI14_0)
-; LA32R-NEXT:    addi.w $a1, $a1, %pc_lo12(.LCPI14_0)
+; LA32R-NEXT:  .Lpcadd_hi0:
+; LA32R-NEXT:    pcaddu12i $a1, %pcadd_hi20(.LCPI14_0)
+; LA32R-NEXT:    addi.w $a1, $a1, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32R-NEXT:    add.w $a0, $a1, $a0
 ; LA32R-NEXT:    ld.bu $a0, $a0, 0
 ; LA32R-NEXT:    ret
@@ -834,8 +835,9 @@ define i64 @test_cttz_i64(i64 %a) nounwind {
 ; LA32R:       # %bb.0:
 ; LA32R-NEXT:    lu12i.w $a2, 30667
 ; LA32R-NEXT:    ori $a2, $a2, 1329
-; LA32R-NEXT:    pcalau12i $a3, %pc_hi20(.LCPI15_0)
-; LA32R-NEXT:    addi.w $a3, $a3, %pc_lo12(.LCPI15_0)
+; LA32R-NEXT:  .Lpcadd_hi1:
+; LA32R-NEXT:    pcaddu12i $a3, %pcadd_hi20(.LCPI15_0)
+; LA32R-NEXT:    addi.w $a3, $a3, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32R-NEXT:    bne $a1, $zero, .LBB15_3
 ; LA32R-NEXT:  # %bb.1:
 ; LA32R-NEXT:    ori $a1, $zero, 32
@@ -974,8 +976,9 @@ define i32 @test_not_cttz_i32(i32 %a) nounwind {
 ; LA32R-NEXT:    ori $a1, $a1, 1329
 ; LA32R-NEXT:    mul.w $a0, $a0, $a1
 ; LA32R-NEXT:    srli.w $a0, $a0, 27
-; LA32R-NEXT:    pcalau12i $a1, %pc_hi20(.LCPI18_0)
-; LA32R-NEXT:    addi.w $a1, $a1, %pc_lo12(.LCPI18_0)
+; LA32R-NEXT:  .Lpcadd_hi2:
+; LA32R-NEXT:    pcaddu12i $a1, %pcadd_hi20(.LCPI18_0)
+; LA32R-NEXT:    addi.w $a1, $a1, %pcadd_lo12(.Lpcadd_hi2)
 ; LA32R-NEXT:    add.w $a0, $a1, $a0
 ; LA32R-NEXT:    ld.bu $a0, $a0, 0
 ; LA32R-NEXT:    ret
@@ -1001,8 +1004,9 @@ define i64 @test_not_cttz_i64(i64 %a) nounwind {
 ; LA32R-NEXT:    nor $a2, $a0, $zero
 ; LA32R-NEXT:    lu12i.w $a3, 30667
 ; LA32R-NEXT:    ori $a3, $a3, 1329
-; LA32R-NEXT:    pcalau12i $a4, %pc_hi20(.LCPI19_0)
-; LA32R-NEXT:    addi.w $a4, $a4, %pc_lo12(.LCPI19_0)
+; LA32R-NEXT:  .Lpcadd_hi3:
+; LA32R-NEXT:    pcaddu12i $a4, %pcadd_hi20(.LCPI19_0)
+; LA32R-NEXT:    addi.w $a4, $a4, %pcadd_lo12(.Lpcadd_hi3)
 ; LA32R-NEXT:    bne $a5, $zero, .LBB19_3
 ; LA32R-NEXT:  # %bb.1:
 ; LA32R-NEXT:    ori $a1, $zero, 32
diff --git a/llvm/test/CodeGen/LoongArch/double-imm.ll b/llvm/test/CodeGen/LoongArch/double-imm.ll
index 0b715cb18f8ad..577d7bd5be241 100644
--- a/llvm/test/CodeGen/LoongArch/double-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/double-imm.ll
@@ -45,14 +45,16 @@ define double @f64_negative_zero() nounwind {
 define double @f64_constant_ins1() nounwind {
 ; LA32-0-LABEL: f64_constant_ins1:
 ; LA32-0:       # %bb.0:
-; LA32-0-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32-0-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI2_0)
+; LA32-0-NEXT:  .Lpcadd_hi0:
+; LA32-0-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI2_0)
+; LA32-0-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-0-NEXT:    ret
 ;
 ; LA32-2-LABEL: f64_constant_ins1:
 ; LA32-2:       # %bb.0:
-; LA32-2-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32-2-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI2_0)
+; LA32-2-NEXT:  .Lpcadd_hi0:
+; LA32-2-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI2_0)
+; LA32-2-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-2-NEXT:    ret
 ;
 ; LA32-3-LABEL: f64_constant_ins1:
@@ -118,20 +120,23 @@ define double @f64_constant_ins1() nounwind {
 define double @f64_constant_ins2() nounwind {
 ; LA32-0-LABEL: f64_constant_ins2:
 ; LA32-0:       # %bb.0:
-; LA32-0-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_0)
-; LA32-0-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI3_0)
+; LA32-0-NEXT:  .Lpcadd_hi1:
+; LA32-0-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_0)
+; LA32-0-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32-0-NEXT:    ret
 ;
 ; LA32-2-LABEL: f64_constant_ins2:
 ; LA32-2:       # %bb.0:
-; LA32-2-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_0)
-; LA32-2-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI3_0)
+; LA32-2-NEXT:  .Lpcadd_hi1:
+; LA32-2-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_0)
+; LA32-2-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32-2-NEXT:    ret
 ;
 ; LA32-3-LABEL: f64_constant_ins2:
 ; LA32-3:       # %bb.0:
-; LA32-3-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_0)
-; LA32-3-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI3_0)
+; LA32-3-NEXT:  .Lpcadd_hi0:
+; LA32-3-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_0)
+; LA32-3-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-3-NEXT:    ret
 ;
 ; LA32-4-LABEL: f64_constant_ins2:
@@ -196,26 +201,30 @@ define double @f64_constant_ins2() nounwind {
 define double @f64_constant_ins3() nounwind {
 ; LA32-0-LABEL: f64_constant_ins3:
 ; LA32-0:       # %bb.0:
-; LA32-0-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI4_0)
-; LA32-0-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI4_0)
+; LA32-0-NEXT:  .Lpcadd_hi2:
+; LA32-0-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI4_0)
+; LA32-0-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi2)
 ; LA32-0-NEXT:    ret
 ;
 ; LA32-2-LABEL: f64_constant_ins3:
 ; LA32-2:       # %bb.0:
-; LA32-2-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI4_0)
-; LA32-2-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI4_0)
+; LA32-2-NEXT:  .Lpcadd_hi2:
+; LA32-2-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI4_0)
+; LA32-2-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi2)
 ; LA32-2-NEXT:    ret
 ;
 ; LA32-3-LABEL: f64_constant_ins3:
 ; LA32-3:       # %bb.0:
-; LA32-3-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI4_0)
-; LA32-3-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI4_0)
+; LA32-3-NEXT:  .Lpcadd_hi1:
+; LA32-3-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI4_0)
+; LA32-3-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32-3-NEXT:    ret
 ;
 ; LA32-4-LABEL: f64_constant_ins3:
 ; LA32-4:       # %bb.0:
-; LA32-4-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI4_0)
-; LA32-4-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI4_0)
+; LA32-4-NEXT:  .Lpcadd_hi0:
+; LA32-4-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI4_0)
+; LA32-4-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-4-NEXT:    ret
 ;
 ; LA32-5-LABEL: f64_constant_ins3:
@@ -275,32 +284,37 @@ define double @f64_constant_ins3() nounwind {
 define double @f64_constant_pi() nounwind {
 ; LA32-0-LABEL: f64_constant_pi:
 ; LA32-0:       # %bb.0:
-; LA32-0-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA32-0-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI5_0)
+; LA32-0-NEXT:  .Lpcadd_hi3:
+; LA32-0-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_0)
+; LA32-0-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi3)
 ; LA32-0-NEXT:    ret
 ;
 ; LA32-2-LABEL: f64_constant_pi:
 ; LA32-2:       # %bb.0:
-; LA32-2-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA32-2-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI5_0)
+; LA32-2-NEXT:  .Lpcadd_hi3:
+; LA32-2-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_0)
+; LA32-2-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi3)
 ; LA32-2-NEXT:    ret
 ;
 ; LA32-3-LABEL: f64_constant_pi:
 ; LA32-3:       # %bb.0:
-; LA32-3-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA32-3-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI5_0)
+; LA32-3-NEXT:  .Lpcadd_hi2:
+; LA32-3-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_0)
+; LA32-3-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi2)
 ; LA32-3-NEXT:    ret
 ;
 ; LA32-4-LABEL: f64_constant_pi:
 ; LA32-4:       # %bb.0:
-; LA32-4-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA32-4-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI5_0)
+; LA32-4-NEXT:  .Lpcadd_hi1:
+; LA32-4-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_0)
+; LA32-4-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32-4-NEXT:    ret
 ;
 ; LA32-5-LABEL: f64_constant_pi:
 ; LA32-5:       # %bb.0:
-; LA32-5-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA32-5-NEXT:    fld.d $fa0, $a0, %pc_lo12(.LCPI5_0)
+; LA32-5-NEXT:  .Lpcadd_hi0:
+; LA32-5-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_0)
+; LA32-5-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-5-NEXT:    ret
 ;
 ; LA32-6-LABEL: f64_constant_pi:
diff --git a/llvm/test/CodeGen/LoongArch/float-imm.ll b/llvm/test/CodeGen/LoongArch/float-imm.ll
index 4611d8801cf2f..b6352b66fafb8 100644
--- a/llvm/test/CodeGen/LoongArch/float-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/float-imm.ll
@@ -43,8 +43,9 @@ define float @f32_negative_zero() nounwind {
 define float @f32_constant_ins1() nounwind {
 ; LA32-0-LABEL: f32_constant_ins1:
 ; LA32-0:       # %bb.0:
-; LA32-0-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32-0-NEXT:    fld.s $fa0, $a0, %pc_lo12(.LCPI2_0)
+; LA32-0-NEXT:  .Lpcadd_hi0:
+; LA32-0-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI2_0)
+; LA32-0-NEXT:    fld.s $fa0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-0-NEXT:    ret
 ;
 ; LA32-2-LABEL: f32_constant_ins1:
@@ -82,14 +83,16 @@ define float @f32_constant_ins1() nounwind {
 define float @f32_constant_pi() nounwind {
 ; LA32-0-LABEL: f32_constant_pi:
 ; LA32-0:       # %bb.0:
-; LA32-0-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_0)
-; LA32-0-NEXT:    fld.s $fa0, $a0, %pc_lo12(.LCPI3_0)
+; LA32-0-NEXT:  .Lpcadd_hi1:
+; LA32-0-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_0)
+; LA32-0-NEXT:    fld.s $fa0, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32-0-NEXT:    ret
 ;
 ; LA32-2-LABEL: f32_constant_pi:
 ; LA32-2:       # %bb.0:
-; LA32-2-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI3_0)
-; LA32-2-NEXT:    fld.s $fa0, $a0, %pc_lo12(.LCPI3_0)
+; LA32-2-NEXT:  .Lpcadd_hi0:
+; LA32-2-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI3_0)
+; LA32-2-NEXT:    fld.s $fa0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-2-NEXT:    ret
 ;
 ; LA32-3-LABEL: f32_constant_pi:
diff --git a/llvm/test/CodeGen/LoongArch/global-address.ll b/llvm/test/CodeGen/LoongArch/global-address.ll
index 89ea48c3b1cbf..750246104b4fa 100644
--- a/llvm/test/CodeGen/LoongArch/global-address.ll
+++ b/llvm/test/CodeGen/LoongArch/global-address.ll
@@ -12,20 +12,24 @@
 define void @foo() nounwind {
 ; LA32NOPIC-LABEL: foo:
 ; LA32NOPIC:       # %bb.0:
-; LA32NOPIC-NEXT:    pcalau12i $a0, %got_pc_hi20(G)
-; LA32NOPIC-NEXT:    ld.w $a0, $a0, %got_pc_lo12(G)
+; LA32NOPIC-NEXT:  .Lpcadd_hi0:
+; LA32NOPIC-NEXT:    pcaddu12i $a0, %got_pcadd_hi20(G)
+; LA32NOPIC-NEXT:    ld.w $a0, $a0, %got_pcadd_lo12(.Lpcadd_hi0)
 ; LA32NOPIC-NEXT:    ld.w $zero, $a0, 0
-; LA32NOPIC-NEXT:    pcalau12i $a0, %pc_hi20(g)
-; LA32NOPIC-NEXT:    ld.w $zero, $a0, %pc_lo12(g)
+; LA32NOPIC-NEXT:  .Lpcadd_hi1:
+; LA32NOPIC-NEXT:    pcaddu12i $a0, %pcadd_hi20(g)
+; LA32NOPIC-NEXT:    ld.w $zero, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32NOPIC-NEXT:    ret
 ;
 ; LA32PIC-LABEL: foo:
 ; LA32PIC:       # %bb.0:
-; LA32PIC-NEXT:    pcalau12i $a0, %got_pc_hi20(G)
-; LA32PIC-NEXT:    ld.w $a0, $a0, %got_pc_lo12(G)
+; LA32PIC-NEXT:  .Lpcadd_hi0:
+; LA32PIC-NEXT:    pcaddu12i $a0, %got_pcadd_hi20(G)
+; LA32PIC-NEXT:    ld.w $a0, $a0, %got_pcadd_lo12(.Lpcadd_hi0)
 ; LA32PIC-NEXT:    ld.w $zero, $a0, 0
-; LA32PIC-NEXT:    pcalau12i $a0, %pc_hi20(.Lg$local)
-; LA32PIC-NEXT:    ld.w $zero, $a0, %pc_lo12(.Lg$local)
+; LA32PIC-NEXT:  .Lpcadd_hi1:
+; LA32PIC-NEXT:    pcaddu12i $a0, %pcadd_hi20(.Lg$local)
+; LA32PIC-NEXT:    ld.w $zero, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32PIC-NEXT:    ret
 ;
 ; LA64NOPIC-LABEL: foo:
diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll
index c1d75ddd32803..b5f1c23a95207 100644
--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll
+++ b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll
@@ -9,8 +9,9 @@
 define double @constraint_f_double(double %a) nounwind {
 ; LA32-LABEL: constraint_f_double:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(gd)
-; LA32-NEXT:    fld.d $fa1, $a0, %pc_lo12(gd)
+; LA32-NEXT:  .Lpcadd_hi0:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(gd)
+; LA32-NEXT:    fld.d $fa1, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-NEXT:    #APP
 ; LA32-NEXT:    fadd.d $fa0, $fa0, $fa1
 ; LA32-NEXT:    #NO_APP
diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
index 38e06d15670a8..9255ad3010cff 100644
--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
+++ b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
@@ -145,7 +145,8 @@ define i32 @m_offset_2048(ptr %p) nounwind {
 define i32 @m_constant_0() nounwind {
 ; LA32-LABEL: m_constant_0:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI7_0)
+; LA32-NEXT:  .Lpcadd_hi0:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI7_0)
 ; LA32-NEXT:    #APP
 ; LA32-NEXT:    #NO_APP
 ; LA32-NEXT:    ret
@@ -163,9 +164,10 @@ define i32 @m_constant_0() nounwind {
 define i32 @m_constant_1() nounwind {
 ; LA32-LABEL: m_constant_1:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI8_0)
+; LA32-NEXT:  .Lpcadd_hi1:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI8_0)
 ; LA32-NEXT:    #APP
-; LA32-NEXT:    ld.w $a0, $a0, %pc_lo12(.LCPI8_0)
+; LA32-NEXT:    ld.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi10)
 ; LA32-NEXT:    #NO_APP
 ; LA32-NEXT:    ret
 ;
@@ -185,9 +187,10 @@ define i32 @m_constant_1() nounwind {
 define i32 @m_addr_pcrel() nounwind {
 ; LA32-LABEL: m_addr_pcrel:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    pcalau12i $a1, %pc_hi20(g_i32)
+; LA32-NEXT:  .Lpcadd_hi2:
+; LA32-NEXT:    pcaddu12i $a1, %pcadd_hi20(g_i32)
 ; LA32-NEXT:    #APP
-; LA32-NEXT:    ld.w $a0, $a1, %pc_lo12(g_i32)
+; LA32-NEXT:    ld.w $a0, $a1, %pcadd_lo12(.Lpcadd_hi20)
 ; LA32-NEXT:    #NO_APP
 ; LA32-NEXT:    ret
 ;
@@ -205,8 +208,9 @@ define i32 @m_addr_pcrel() nounwind {
 define i32 @m_addr_should_not_fold() nounwind {
 ; LA32-LABEL: m_addr_should_not_fold:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32)
-; LA32-NEXT:    addi.w $a1, $a0, %pc_lo12(g_i32)
+; LA32-NEXT:  .Lpcadd_hi3:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32)
+; LA32-NEXT:    addi.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi3)
 ; LA32-NEXT:    #APP
 ; LA32-NEXT:    ld.w $a0, $a1, 0
 ; LA32-NEXT:    #NO_APP
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
index 18ba4810cfb72..1679659a8823b 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
@@ -13,10 +13,11 @@
 define i32 @load_store_global() nounwind {
 ; LA32RNOPIC-LABEL: load_store_global:
 ; LA32RNOPIC:       # %bb.0:
-; LA32RNOPIC-NEXT:    pcalau12i $a1, %pc_hi20(G)
-; LA32RNOPIC-NEXT:    ld.w $a0, $a1, %pc_lo12(G)
+; LA32RNOPIC-NEXT:  .Lpcadd_hi0:
+; LA32RNOPIC-NEXT:    pcaddu12i $a1, %pcadd_hi20(G)
+; LA32RNOPIC-NEXT:    ld.w $a0, $a1, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32RNOPIC-NEXT:    addi.w $a0, $a0, 1
-; LA32RNOPIC-NEXT:    st.w $a0, $a1, %pc_lo12(G)
+; LA32RNOPIC-NEXT:    st.w $a0, $a1, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32RNOPIC-NEXT:    ret
 ;
 ; LA32SNOPIC-LABEL: load_store_global:
@@ -29,10 +30,11 @@ define i32 @load_store_global() nounwind {
 ;
 ; LA32RPIC-LABEL: load_store_global:
 ; LA32RPIC:       # %bb.0:
-; LA32RPIC-NEXT:    pcalau12i $a1, %pc_hi20(.LG$local)
-; LA32RPIC-NEXT:    ld.w $a0, $a1, %pc_lo12(.LG$local)
+; LA32RPIC-NEXT:  .Lpcadd_hi0:
+; LA32RPIC-NEXT:    pcaddu12i $a1, %pcadd_hi20(.LG$local)
+; LA32RPIC-NEXT:    ld.w $a0, $a1, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32RPIC-NEXT:    addi.w $a0, $a0, 1
-; LA32RPIC-NEXT:    st.w $a0, $a1, %pc_lo12(.LG$local)
+; LA32RPIC-NEXT:    st.w $a0, $a1, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32RPIC-NEXT:    ret
 ;
 ; LA32SPIC-LABEL: load_store_global:
@@ -67,8 +69,9 @@ define i32 @load_store_global() nounwind {
 define i32 @load_store_global_array(i32 %a) nounwind {
 ; LA32RNOPIC-LABEL: load_store_global_array:
 ; LA32RNOPIC:       # %bb.0:
-; LA32RNOPIC-NEXT:    pcalau12i $a1, %pc_hi20(arr)
-; LA32RNOPIC-NEXT:    addi.w $a2, $a1, %pc_lo12(arr)
+; LA32RNOPIC-NEXT:  .Lpcadd_hi1:
+; LA32RNOPIC-NEXT:    pcaddu12i $a1, %pcadd_hi20(arr)
+; LA32RNOPIC-NEXT:    addi.w $a2, $a1, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32RNOPIC-NEXT:    ld.w $a1, $a2, 0
 ; LA32RNOPIC-NEXT:    st.w $a0, $a2, 0
 ; LA32RNOPIC-NEXT:    ld.w $zero, $a2, 36
@@ -89,8 +92,9 @@ define i32 @load_store_global_array(i32 %a) nounwind {
 ;
 ; LA32RPIC-LABEL: load_store_global_array:
 ; LA32RPIC:       # %bb.0:
-; LA32RPIC-NEXT:    pcalau12i $a1, %pc_hi20(.Larr$local)
-; LA32RPIC-NEXT:    addi.w $a2, $a1, %pc_lo12(.Larr$local)
+; LA32RPIC-NEXT:  .Lpcadd_hi1:
+; LA32RPIC-NEXT:    pcaddu12i $a1, %pcadd_hi20(.Larr$local)
+; LA32RPIC-NEXT:    addi.w $a2, $a1, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32RPIC-NEXT:    ld.w $a1, $a2, 0
 ; LA32RPIC-NEXT:    st.w $a0, $a2, 0
 ; LA32RPIC-NEXT:    ld.w $zero, $a2, 36
diff --git a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
index 9142e718e8adc..e76bf417ec8f6 100644
--- a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
+++ b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
@@ -14,11 +14,12 @@ define void @test_la_pcrel(i32 signext %n) {
 ; LA32-LABEL: test_la_pcrel:
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    move $a1, $zero
-; LA32-NEXT:    pcalau12i $a2, %pc_hi20(l)
+; LA32-NEXT:  .Lpcadd_hi0:
+; LA32-NEXT:    pcaddu12i $a2, %pcadd_hi20(l)
 ; LA32-NEXT:    .p2align 4, , 16
 ; LA32-NEXT:  .LBB0_1: # %loop
 ; LA32-NEXT:    # =>This Inner Loop Header: Depth=1
-; LA32-NEXT:    ld.w $zero, $a2, %pc_lo12(l)
+; LA32-NEXT:    ld.w $zero, $a2, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-NEXT:    addi.w $a1, $a1, 1
 ; LA32-NEXT:    blt $a1, $a0, .LBB0_1
 ; LA32-NEXT:  # %bb.2: # %ret
@@ -71,8 +72,9 @@ ret:
 define void @test_la_got(i32 signext %n) {
 ; LA32-LABEL: test_la_got:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a1, %got_pc_hi20(g)
-; LA32-NEXT:    ld.w $a1, $a1, %got_pc_lo12(g)
+; LA32-NEXT:  .Lpcadd_hi1:
+; LA32-NEXT:    pcaddu12i $a1, %got_pcadd_hi20(g)
+; LA32-NEXT:    ld.w $a1, $a1, %got_pcadd_lo12(.Lpcadd_hi1)
 ; LA32-NEXT:    move $a2, $zero
 ; LA32-NEXT:    .p2align 4, , 16
 ; LA32-NEXT:  .LBB1_1: # %loop
@@ -132,8 +134,9 @@ ret:
 define void @test_la_tls_ie(i32 signext %n) {
 ; LA32-LABEL: test_la_tls_ie:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a1, %ie_pc_hi20(ie)
-; LA32-NEXT:    ld.w $a2, $a1, %ie_pc_lo12(ie)
+; LA32-NEXT:  .Lpcadd_hi2:
+; LA32-NEXT:    pcaddu12i $a1, %ie_pcadd_hi20(ie)
+; LA32-NEXT:    ld.w $a2, $a1, %ie_pcadd_lo12(.Lpcadd_hi2)
 ; LA32-NEXT:    move $a1, $zero
 ; LA32-NEXT:    add.w $a2, $a2, $tp
 ; LA32-NEXT:    .p2align 4, , 16
@@ -206,8 +209,9 @@ define void @test_la_tls_ld(i32 signext %n) {
 ; LA32-NEXT:    .cfi_offset 24, -16
 ; LA32-NEXT:    move $fp, $a0
 ; LA32-NEXT:    move $s1, $zero
-; LA32-NEXT:    pcalau12i $a0, %ld_pc_hi20(ld)
-; LA32-NEXT:    addi.w $s0, $a0, %got_pc_lo12(ld)
+; LA32-NEXT:  .Lpcadd_hi3:
+; LA32-NEXT:    pcaddu12i $a0, %ld_pcadd_hi20(ld)
+; LA32-NEXT:    addi.w $s0, $a0, %ld_pcadd_lo12(.Lpcadd_hi3)
 ; LA32-NEXT:    .p2align 4, , 16
 ; LA32-NEXT:  .LBB3_1: # %loop
 ; LA32-NEXT:    # =>This Inner Loop Header: Depth=1
@@ -382,8 +386,9 @@ define void @test_la_tls_gd(i32 signext %n) nounwind {
 ; LA32-NEXT:    st.w $s1, $sp, 0 # 4-byte Folded Spill
 ; LA32-NEXT:    move $fp, $a0
 ; LA32-NEXT:    move $s1, $zero
-; LA32-NEXT:    pcalau12i $a0, %gd_pc_hi20(gd)
-; LA32-NEXT:    addi.w $s0, $a0, %got_pc_lo12(gd)
+; LA32-NEXT:  .Lpcadd_hi4:
+; LA32-NEXT:    pcaddu12i $a0, %gd_pcadd_hi20(gd)
+; LA32-NEXT:    addi.w $s0, $a0, %gd_pcadd_lo12(.Lpcadd_hi4)
 ; LA32-NEXT:    .p2align 4, , 16
 ; LA32-NEXT:  .LBB5_1: # %loop
 ; LA32-NEXT:    # =>This Inner Loop Header: Depth=1
diff --git a/llvm/test/CodeGen/LoongArch/merge-base-offset.ll b/llvm/test/CodeGen/LoongArch/merge-base-offset.ll
index 1151c77c9af76..ea0fe3d0b0178 100644
--- a/llvm/test/CodeGen/LoongArch/merge-base-offset.ll
+++ b/llvm/test/CodeGen/LoongArch/merge-base-offset.ll
@@ -11,8 +11,9 @@
 define dso_local signext i8 @load_s8() nounwind {
 ; LA32-LABEL: load_s8:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i8)
-; LA32-NEXT:    ld.b $a0, $a0, %pc_lo12(g_i8)
+; LA32-NEXT:  .Lpcadd_hi0:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i8)
+; LA32-NEXT:    ld.b $a0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_s8:
@@ -37,8 +38,9 @@ entry:
 define dso_local zeroext i8 @load_u8() nounwind {
 ; LA32-LABEL: load_u8:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i8)
-; LA32-NEXT:    ld.bu $a0, $a0, %pc_lo12(g_i8)
+; LA32-NEXT:  .Lpcadd_hi1:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i8)
+; LA32-NEXT:    ld.bu $a0, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_u8:
@@ -63,9 +65,10 @@ entry:
 define dso_local void @store_i8() nounwind {
 ; LA32-LABEL: store_i8:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i8)
+; LA32-NEXT:  .Lpcadd_hi2:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i8)
 ; LA32-NEXT:    ori $a1, $zero, 1
-; LA32-NEXT:    st.b $a1, $a0, %pc_lo12(g_i8)
+; LA32-NEXT:    st.b $a1, $a0, %pcadd_lo12(.Lpcadd_hi2)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_i8:
@@ -94,8 +97,9 @@ entry:
 define dso_local signext i16 @load_s16() nounwind {
 ; LA32-LABEL: load_s16:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i16)
-; LA32-NEXT:    ld.h $a0, $a0, %pc_lo12(g_i16)
+; LA32-NEXT:  .Lpcadd_hi3:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i16)
+; LA32-NEXT:    ld.h $a0, $a0, %pcadd_lo12(.Lpcadd_hi3)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_s16:
@@ -120,8 +124,9 @@ entry:
 define dso_local zeroext i16 @load_u16() nounwind {
 ; LA32-LABEL: load_u16:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i16)
-; LA32-NEXT:    ld.hu $a0, $a0, %pc_lo12(g_i16)
+; LA32-NEXT:  .Lpcadd_hi4:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i16)
+; LA32-NEXT:    ld.hu $a0, $a0, %pcadd_lo12(.Lpcadd_hi4)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_u16:
@@ -146,9 +151,10 @@ entry:
 define dso_local void @store_i16() nounwind {
 ; LA32-LABEL: store_i16:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i16)
+; LA32-NEXT:  .Lpcadd_hi5:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i16)
 ; LA32-NEXT:    ori $a1, $zero, 1
-; LA32-NEXT:    st.h $a1, $a0, %pc_lo12(g_i16)
+; LA32-NEXT:    st.h $a1, $a0, %pcadd_lo12(.Lpcadd_hi5)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_i16:
@@ -177,8 +183,9 @@ entry:
 define dso_local signext i32 @load_s32() nounwind {
 ; LA32-LABEL: load_s32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32)
-; LA32-NEXT:    ld.w $a0, $a0, %pc_lo12(g_i32)
+; LA32-NEXT:  .Lpcadd_hi6:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32)
+; LA32-NEXT:    ld.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi6)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_s32:
@@ -203,8 +210,9 @@ entry:
 define dso_local zeroext i32 @load_u32() nounwind {
 ; LA32-LABEL: load_u32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32)
-; LA32-NEXT:    ld.w $a0, $a0, %pc_lo12(g_i32)
+; LA32-NEXT:  .Lpcadd_hi7:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32)
+; LA32-NEXT:    ld.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi7)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_u32:
@@ -229,9 +237,10 @@ entry:
 define dso_local void @store_i32() nounwind {
 ; LA32-LABEL: store_i32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32)
+; LA32-NEXT:  .Lpcadd_hi8:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32)
 ; LA32-NEXT:    ori $a1, $zero, 1
-; LA32-NEXT:    st.w $a1, $a0, %pc_lo12(g_i32)
+; LA32-NEXT:    st.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi8)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_i32:
@@ -260,8 +269,9 @@ entry:
 define dso_local i64 @load_i64() nounwind {
 ; LA32-LABEL: load_i64:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i64)
-; LA32-NEXT:    addi.w $a1, $a0, %pc_lo12(g_i64)
+; LA32-NEXT:  .Lpcadd_hi9:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i64)
+; LA32-NEXT:    addi.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi9)
 ; LA32-NEXT:    ld.w $a0, $a1, 0
 ; LA32-NEXT:    ld.w $a1, $a1, 4
 ; LA32-NEXT:    ret
@@ -288,8 +298,9 @@ entry:
 define dso_local void @store_i64() nounwind {
 ; LA32-LABEL: store_i64:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i64)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_i64)
+; LA32-NEXT:  .Lpcadd_hi10:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i64)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi10)
 ; LA32-NEXT:    st.w $zero, $a0, 4
 ; LA32-NEXT:    ori $a1, $zero, 1
 ; LA32-NEXT:    st.w $a1, $a0, 0
@@ -321,8 +332,9 @@ entry:
 define dso_local float @load_f32() nounwind {
 ; LA32-LABEL: load_f32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_f32)
-; LA32-NEXT:    fld.s $fa0, $a0, %pc_lo12(g_f32)
+; LA32-NEXT:  .Lpcadd_hi11:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_f32)
+; LA32-NEXT:    fld.s $fa0, $a0, %pcadd_lo12(.Lpcadd_hi11)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_f32:
@@ -347,9 +359,10 @@ entry:
 define dso_local void @store_f32() nounwind {
 ; LA32-LABEL: store_f32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_f32)
+; LA32-NEXT:  .Lpcadd_hi12:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_f32)
 ; LA32-NEXT:    lu12i.w $a1, 260096
-; LA32-NEXT:    st.w $a1, $a0, %pc_lo12(g_f32)
+; LA32-NEXT:    st.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi12)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_f32:
@@ -378,8 +391,9 @@ entry:
 define dso_local double @load_f64() nounwind {
 ; LA32-LABEL: load_f64:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_f64)
-; LA32-NEXT:    fld.d $fa0, $a0, %pc_lo12(g_f64)
+; LA32-NEXT:  .Lpcadd_hi13:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_f64)
+; LA32-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi13)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_f64:
@@ -404,9 +418,10 @@ entry:
 define dso_local void @store_f64() nounwind {
 ; LA32-LABEL: store_f64:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_f64)
+; LA32-NEXT:  .Lpcadd_hi14:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_f64)
 ; LA32-NEXT:    vldi $vr0, -912
-; LA32-NEXT:    fst.d $fa0, $a0, %pc_lo12(g_f64)
+; LA32-NEXT:    fst.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi14)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_f64:
@@ -435,8 +450,9 @@ entry:
 define dso_local void @store_multi() nounwind {
 ; LA32-LABEL: store_multi:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_m64)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_m64)
+; LA32-NEXT:  .Lpcadd_hi15:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_m64)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi15)
 ; LA32-NEXT:    st.w $zero, $a0, 4
 ; LA32-NEXT:    ori $a1, $zero, 1
 ; LA32-NEXT:    st.w $a1, $a0, 0
@@ -476,9 +492,10 @@ entry:
 define dso_local void @store_sf32() nounwind {
 ; LA32-LABEL: store_sf32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_sf32)
-; LA32-NEXT:    fld.s $fa0, $a0, %pc_lo12(g_sf32)
-; LA32-NEXT:    fst.s $fa0, $a0, %pc_lo12(g_sf32)
+; LA32-NEXT:  .Lpcadd_hi16:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_sf32)
+; LA32-NEXT:    fld.s $fa0, $a0, %pcadd_lo12(.Lpcadd_hi16)
+; LA32-NEXT:    fst.s $fa0, $a0, %pcadd_lo12(.Lpcadd_hi16)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_sf32:
@@ -508,9 +525,10 @@ entry:
 define dso_local void @store_sf64() nounwind {
 ; LA32-LABEL: store_sf64:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_sf64)
-; LA32-NEXT:    fld.d $fa0, $a0, %pc_lo12(g_sf64)
-; LA32-NEXT:    fst.d $fa0, $a0, %pc_lo12(g_sf64)
+; LA32-NEXT:  .Lpcadd_hi17:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_sf64)
+; LA32-NEXT:    fld.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi17)
+; LA32-NEXT:    fst.d $fa0, $a0, %pcadd_lo12(.Lpcadd_hi17)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_sf64:
@@ -541,10 +559,12 @@ entry:
 define dso_local void @copy_i32x4() nounwind {
 ; LA32-LABEL: copy_i32x4:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32x4_src)
-; LA32-NEXT:    vld $vr0, $a0, %pc_lo12(g_i32x4_src)
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32x4_dst)
-; LA32-NEXT:    vst $vr0, $a0, %pc_lo12(g_i32x4_dst)
+; LA32-NEXT:  .Lpcadd_hi18:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32x4_src)
+; LA32-NEXT:    vld $vr0, $a0, %pcadd_lo12(.Lpcadd_hi18)
+; LA32-NEXT:  .Lpcadd_hi19:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32x4_dst)
+; LA32-NEXT:    vst $vr0, $a0, %pcadd_lo12(.Lpcadd_hi19)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: copy_i32x4:
@@ -580,10 +600,12 @@ entry:
 define dso_local void @copy_i32x8() nounwind {
 ; LA32-LABEL: copy_i32x8:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32x8_src)
-; LA32-NEXT:    xvld $xr0, $a0, %pc_lo12(g_i32x8_src)
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i32x8_dst)
-; LA32-NEXT:    xvst $xr0, $a0, %pc_lo12(g_i32x8_dst)
+; LA32-NEXT:  .Lpcadd_hi20:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32x8_src)
+; LA32-NEXT:    xvld $xr0, $a0, %pcadd_lo12(.Lpcadd_hi20)
+; LA32-NEXT:  .Lpcadd_hi21:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i32x8_dst)
+; LA32-NEXT:    xvst $xr0, $a0, %pcadd_lo12(.Lpcadd_hi21)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: copy_i32x8:
@@ -618,10 +640,12 @@ entry:
 define void @copy_i8_to_i8x16() {
 ; LA32-LABEL: copy_i8_to_i8x16:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i8)
-; LA32-NEXT:    vldrepl.b $vr0, $a0, %pc_lo12(g_i8)
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i8x16)
-; LA32-NEXT:    vst $vr0, $a0, %pc_lo12(g_i8x16)
+; LA32-NEXT:  .Lpcadd_hi22:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i8)
+; LA32-NEXT:    vldrepl.b $vr0, $a0, %pcadd_lo12(.Lpcadd_hi22)
+; LA32-NEXT:  .Lpcadd_hi23:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i8x16)
+; LA32-NEXT:    vst $vr0, $a0, %pcadd_lo12(.Lpcadd_hi23)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: copy_i8_to_i8x16:
@@ -657,10 +681,12 @@ entry:
 define void @copy_i8_to_i8x32() {
 ; LA32-LABEL: copy_i8_to_i8x32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i8)
-; LA32-NEXT:    xvldrepl.b $xr0, $a0, %pc_lo12(g_i8)
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_i8x32)
-; LA32-NEXT:    xvst $xr0, $a0, %pc_lo12(g_i8x32)
+; LA32-NEXT:  .Lpcadd_hi24:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i8)
+; LA32-NEXT:    xvldrepl.b $xr0, $a0, %pcadd_lo12(.Lpcadd_hi24)
+; LA32-NEXT:  .Lpcadd_hi25:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_i8x32)
+; LA32-NEXT:    xvst $xr0, $a0, %pcadd_lo12(.Lpcadd_hi25)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: copy_i8_to_i8x32:
@@ -696,8 +722,9 @@ entry:
 define dso_local void @rmw() nounwind {
 ; LA32-LABEL: rmw:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_rmw)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_rmw)
+; LA32-NEXT:  .Lpcadd_hi26:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_rmw)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi26)
 ; LA32-NEXT:    ld.w $a1, $a0, 0
 ; LA32-NEXT:    ld.w $a2, $a0, 4
 ; LA32-NEXT:    addi.w $a1, $a1, 1
@@ -737,9 +764,10 @@ entry:
 define dso_local void @store_a32() nounwind {
 ; LA32-LABEL: store_a32:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a32+4096)
+; LA32-NEXT:  .Lpcadd_hi27:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a32+4096)
 ; LA32-NEXT:    ori $a1, $zero, 1
-; LA32-NEXT:    st.w $a1, $a0, %pc_lo12(g_a32+4096)
+; LA32-NEXT:    st.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi27)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: store_a32:
@@ -766,8 +794,9 @@ entry:
 define dso_local void @store_a32_2() nounwind {
 ; LA32-LABEL: store_a32_2:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a32)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a32)
+; LA32-NEXT:  .Lpcadd_hi28:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a32)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi28)
 ; LA32-NEXT:    lu12i.w $a1, 1
 ; LA32-NEXT:    add.w $a2, $a0, $a1
 ; LA32-NEXT:    ori $a3, $zero, 1
@@ -809,12 +838,13 @@ entry:
 define dso_local void @control_flow_with_mem_access() nounwind {
 ; LA32-LABEL: control_flow_with_mem_access:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a32+4)
-; LA32-NEXT:    ld.w $a1, $a0, %pc_lo12(g_a32+4)
+; LA32-NEXT:  .Lpcadd_hi29:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a32+4)
+; LA32-NEXT:    ld.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi29)
 ; LA32-NEXT:    blez $a1, .LBB25_2
 ; LA32-NEXT:  # %bb.1: # %if.then
 ; LA32-NEXT:    ori $a1, $zero, 10
-; LA32-NEXT:    st.w $a1, $a0, %pc_lo12(g_a32+4)
+; LA32-NEXT:    st.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi29)
 ; LA32-NEXT:  .LBB25_2: # %if.end
 ; LA32-NEXT:    ret
 ;
@@ -864,8 +894,9 @@ define dso_local ptr @load_ba_1() nounwind {
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:  .Ltmp0: # Block address taken
 ; LA32-NEXT:  # %bb.1: # %label
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.Ltmp0)
-; LA32-NEXT:    ld.w $a0, $a0, %pc_lo12(.Ltmp0)
+; LA32-NEXT:  .Lpcadd_hi30:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(.Ltmp0)
+; LA32-NEXT:    ld.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi30)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_ba_1:
@@ -898,8 +929,9 @@ define dso_local ptr @load_ba_2() nounwind {
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:  .Ltmp1: # Block address taken
 ; LA32-NEXT:  # %bb.1: # %label
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.Ltmp1+8)
-; LA32-NEXT:    ld.w $a0, $a0, %pc_lo12(.Ltmp1+8)
+; LA32-NEXT:  .Lpcadd_hi31:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(.Ltmp1+8)
+; LA32-NEXT:    ld.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi31)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_ba_2:
@@ -932,8 +964,9 @@ label:
 define dso_local ptr @load_addr_offset_1() nounwind {
 ; LA32-LABEL: load_addr_offset_1:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+8)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+8)
+; LA32-NEXT:  .Lpcadd_hi32:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+8)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi32)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_1:
@@ -957,8 +990,9 @@ entry:
 define dso_local ptr @load_addr_offset_257() nounwind {
 ; LA32-LABEL: load_addr_offset_257:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+2056)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+2056)
+; LA32-NEXT:  .Lpcadd_hi33:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+2056)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi33)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_257:
@@ -982,8 +1016,9 @@ entry:
 define dso_local ptr @load_addr_offset_1048576() nounwind {
 ; LA32-LABEL: load_addr_offset_1048576:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+8388608)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+8388608)
+; LA32-NEXT:  .Lpcadd_hi34:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+8388608)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi34)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_1048576:
@@ -1007,8 +1042,9 @@ entry:
 define dso_local ptr @load_addr_offset_1048577() nounwind {
 ; LA32-LABEL: load_addr_offset_1048577:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+8388616)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+8388616)
+; LA32-NEXT:  .Lpcadd_hi35:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+8388616)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi35)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_1048577:
@@ -1032,8 +1068,9 @@ entry:
 define dso_local ptr @load_addr_offset_268432896() nounwind {
 ; LA32-LABEL: load_addr_offset_268432896:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+2147463168)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+2147463168)
+; LA32-NEXT:  .Lpcadd_hi36:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+2147463168)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi36)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_268432896:
@@ -1057,8 +1094,9 @@ entry:
 define dso_local ptr @load_addr_offset_268432897() nounwind {
 ; LA32-LABEL: load_addr_offset_268432897:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+2147463176)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+2147463176)
+; LA32-NEXT:  .Lpcadd_hi37:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+2147463176)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi37)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_268432897:
@@ -1082,8 +1120,9 @@ entry:
 define dso_local ptr @load_addr_offset_281474439839744() nounwind {
 ; LA32-LABEL: load_addr_offset_281474439839744:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64)
+; LA32-NEXT:  .Lpcadd_hi38:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi38)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_281474439839744:
@@ -1110,8 +1149,9 @@ entry:
 define dso_local ptr @load_addr_offset_248792680471040() nounwind {
 ; LA32-LABEL: load_addr_offset_248792680471040:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+2059194368)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+2059194368)
+; LA32-NEXT:  .Lpcadd_hi39:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+2059194368)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi39)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_248792680471040:
@@ -1138,8 +1178,9 @@ entry:
 define dso_local ptr @load_addr_offset_9380351707272() nounwind {
 ; LA32-LABEL: load_addr_offset_9380351707272:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+1145062464)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+1145062464)
+; LA32-NEXT:  .Lpcadd_hi40:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+1145062464)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi40)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_9380351707272:
@@ -1167,8 +1208,9 @@ entry:
 define dso_local ptr @load_addr_offset_562949953421312() nounwind {
 ; LA32-LABEL: load_addr_offset_562949953421312:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64)
+; LA32-NEXT:  .Lpcadd_hi41:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi41)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_562949953421312:
@@ -1194,8 +1236,9 @@ entry:
 define dso_local ptr @load_addr_offset_614749556925924693() nounwind {
 ; LA32-LABEL: load_addr_offset_614749556925924693:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(g_a64+858794664)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(g_a64+858794664)
+; LA32-NEXT:  .Lpcadd_hi42:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(g_a64+858794664)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi42)
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_addr_offset_614749556925924693:
diff --git a/llvm/test/CodeGen/LoongArch/numeric-reg-names.ll b/llvm/test/CodeGen/LoongArch/numeric-reg-names.ll
index 73f4dbbbdd026..38de4564c3d3f 100644
--- a/llvm/test/CodeGen/LoongArch/numeric-reg-names.ll
+++ b/llvm/test/CodeGen/LoongArch/numeric-reg-names.ll
@@ -15,8 +15,9 @@ define i32 @main() {
 ; LA32-NEXT:    .cfi_def_cfa_offset 16
 ; LA32-NEXT:    st.w $r1, $r3, 12 # 4-byte Folded Spill
 ; LA32-NEXT:    .cfi_offset 1, -4
-; LA32-NEXT:    pcalau12i $r4, %pc_hi20(.str_1)
-; LA32-NEXT:    addi.w $r4, $r4, %pc_lo12(.str_1)
+; LA32-NEXT:  .Lpcadd_hi0:
+; LA32-NEXT:    pcaddu12i $r4, %pcadd_hi20(.str_1)
+; LA32-NEXT:    addi.w $r4, $r4, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-NEXT:    bl printf
 ; LA32-NEXT:    move $r4, $r0
 ; LA32-NEXT:    ld.w $r1, $r3, 12 # 4-byte Folded Reload
diff --git a/llvm/test/CodeGen/LoongArch/stack-protector-target.ll b/llvm/test/CodeGen/LoongArch/stack-protector-target.ll
index ea4569e198d02..d24d59be32ba7 100644
--- a/llvm/test/CodeGen/LoongArch/stack-protector-target.ll
+++ b/llvm/test/CodeGen/LoongArch/stack-protector-target.ll
@@ -10,12 +10,13 @@ define void @func() sspreq nounwind {
 ; LINUX32-NEXT:    addi.w $sp, $sp, -16
 ; LINUX32-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
 ; LINUX32-NEXT:    st.w $fp, $sp, 8 # 4-byte Folded Spill
-; LINUX32-NEXT:    pcalau12i $fp, %pc_hi20(__stack_chk_guard)
-; LINUX32-NEXT:    ld.w $a0, $fp, %pc_lo12(__stack_chk_guard)
+; LINUX32-NEXT:  .Lpcadd_hi0:
+; LINUX32-NEXT:    pcaddu12i $fp, %pcadd_hi20(__stack_chk_guard)
+; LINUX32-NEXT:    ld.w $a0, $fp, %pcadd_lo12(.Lpcadd_hi0)
 ; LINUX32-NEXT:    st.w $a0, $sp, 4
 ; LINUX32-NEXT:    addi.w $a0, $sp, 0
 ; LINUX32-NEXT:    bl capture
-; LINUX32-NEXT:    ld.w $a0, $fp, %pc_lo12(__stack_chk_guard)
+; LINUX32-NEXT:    ld.w $a0, $fp, %pcadd_lo12(.Lpcadd_hi0)
 ; LINUX32-NEXT:    ld.w $a1, $sp, 4
 ; LINUX32-NEXT:    bne $a0, $a1, .LBB0_2
 ; LINUX32-NEXT:  # %bb.1:
@@ -54,12 +55,13 @@ define void @func() sspreq nounwind {
 ; OPENBSD32-NEXT:    addi.w $sp, $sp, -16
 ; OPENBSD32-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
 ; OPENBSD32-NEXT:    st.w $fp, $sp, 8 # 4-byte Folded Spill
-; OPENBSD32-NEXT:    pcalau12i $fp, %pc_hi20(__guard_local)
-; OPENBSD32-NEXT:    ld.w $a0, $fp, %pc_lo12(__guard_local)
+; OPENBSD32-NEXT:  .Lpcadd_hi0:
+; OPENBSD32-NEXT:    pcaddu12i $fp, %pcadd_hi20(__guard_local)
+; OPENBSD32-NEXT:    ld.w $a0, $fp, %pcadd_lo12(.Lpcadd_hi0)
 ; OPENBSD32-NEXT:    st.w $a0, $sp, 4
 ; OPENBSD32-NEXT:    addi.w $a0, $sp, 0
 ; OPENBSD32-NEXT:    bl capture
-; OPENBSD32-NEXT:    ld.w $a0, $fp, %pc_lo12(__guard_local)
+; OPENBSD32-NEXT:    ld.w $a0, $fp, %pcadd_lo12(.Lpcadd_hi0)
 ; OPENBSD32-NEXT:    ld.w $a1, $sp, 4
 ; OPENBSD32-NEXT:    bne $a0, $a1, .LBB0_2
 ; OPENBSD32-NEXT:  # %bb.1: # %SP_return
@@ -68,8 +70,9 @@ define void @func() sspreq nounwind {
 ; OPENBSD32-NEXT:    addi.w $sp, $sp, 16
 ; OPENBSD32-NEXT:    ret
 ; OPENBSD32-NEXT:  .LBB0_2: # %CallStackCheckFailBlk
-; OPENBSD32-NEXT:    pcalau12i $a0, %pc_hi20(.LSSH)
-; OPENBSD32-NEXT:    addi.w $a0, $a0, %pc_lo12(.LSSH)
+; OPENBSD32-NEXT:  .Lpcadd_hi1:
+; OPENBSD32-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LSSH)
+; OPENBSD32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; OPENBSD32-NEXT:    bl __stack_smash_handler
 ;
 ; OPENBSD64-LABEL: func:
diff --git a/llvm/test/CodeGen/LoongArch/tls-models.ll b/llvm/test/CodeGen/LoongArch/tls-models.ll
index 50d994fb85327..b4e4c4ac420d8 100644
--- a/llvm/test/CodeGen/LoongArch/tls-models.ll
+++ b/llvm/test/CodeGen/LoongArch/tls-models.ll
@@ -28,8 +28,9 @@ define ptr @f1() nounwind {
 ; LA32PIC:       # %bb.0: # %entry
 ; LA32PIC-NEXT:    addi.w $sp, $sp, -16
 ; LA32PIC-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
-; LA32PIC-NEXT:    pcalau12i $a0, %gd_pc_hi20(unspecified)
-; LA32PIC-NEXT:    addi.w $a0, $a0, %got_pc_lo12(unspecified)
+; LA32PIC-NEXT:  .Lpcadd_hi0:
+; LA32PIC-NEXT:    pcaddu12i $a0, %gd_pcadd_hi20(unspecified)
+; LA32PIC-NEXT:    addi.w $a0, $a0, %gd_pcadd_lo12(.Lpcadd_hi0)
 ; LA32PIC-NEXT:    bl __tls_get_addr
 ; LA32PIC-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
 ; LA32PIC-NEXT:    addi.w $sp, $sp, 16
@@ -68,8 +69,9 @@ define ptr @f1() nounwind {
 ;
 ; LA32NOPIC-LABEL: f1:
 ; LA32NOPIC:       # %bb.0: # %entry
-; LA32NOPIC-NEXT:    pcalau12i $a0, %ie_pc_hi20(unspecified)
-; LA32NOPIC-NEXT:    ld.w $a0, $a0, %ie_pc_lo12(unspecified)
+; LA32NOPIC-NEXT:  .Lpcadd_hi0:
+; LA32NOPIC-NEXT:    pcaddu12i $a0, %ie_pcadd_hi20(unspecified)
+; LA32NOPIC-NEXT:    ld.w $a0, $a0, %ie_pcadd_lo12(.Lpcadd_hi0)
 ; LA32NOPIC-NEXT:    add.w $a0, $a0, $tp
 ; LA32NOPIC-NEXT:    ret
 ;
@@ -94,8 +96,9 @@ define ptr @f1() nounwind {
 ; LA32DESC:       # %bb.0: # %entry
 ; LA32DESC-NEXT:    addi.w $sp, $sp, -16
 ; LA32DESC-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
-; LA32DESC-NEXT:    pcalau12i $a0, %desc_pc_hi20(unspecified)
-; LA32DESC-NEXT:    addi.w $a0, $a0, %desc_pc_lo12(unspecified)
+; LA32DESC-NEXT:  .Lpcadd_hi0:
+; LA32DESC-NEXT:    pcaddu12i $a0, %desc_pcadd_hi20(unspecified)
+; LA32DESC-NEXT:    addi.w $a0, $a0, %desc_pcadd_lo12(.Lpcadd_hi0)
 ; LA32DESC-NEXT:    ld.w $ra, $a0, %desc_ld(unspecified)
 ; LA32DESC-NEXT:    jirl $ra, $ra, %desc_call(unspecified)
 ; LA32DESC-NEXT:    add.w $a0, $a0, $tp
@@ -142,8 +145,9 @@ define ptr @f2() nounwind {
 ; LA32PIC:       # %bb.0: # %entry
 ; LA32PIC-NEXT:    addi.w $sp, $sp, -16
 ; LA32PIC-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
-; LA32PIC-NEXT:    pcalau12i $a0, %ld_pc_hi20(ld)
-; LA32PIC-NEXT:    addi.w $a0, $a0, %got_pc_lo12(ld)
+; LA32PIC-NEXT:  .Lpcadd_hi1:
+; LA32PIC-NEXT:    pcaddu12i $a0, %ld_pcadd_hi20(ld)
+; LA32PIC-NEXT:    addi.w $a0, $a0, %ld_pcadd_lo12(.Lpcadd_hi1)
 ; LA32PIC-NEXT:    bl __tls_get_addr
 ; LA32PIC-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
 ; LA32PIC-NEXT:    addi.w $sp, $sp, 16
@@ -182,8 +186,9 @@ define ptr @f2() nounwind {
 ;
 ; LA32NOPIC-LABEL: f2:
 ; LA32NOPIC:       # %bb.0: # %entry
-; LA32NOPIC-NEXT:    pcalau12i $a0, %ie_pc_hi20(ld)
-; LA32NOPIC-NEXT:    ld.w $a0, $a0, %ie_pc_lo12(ld)
+; LA32NOPIC-NEXT:  .Lpcadd_hi1:
+; LA32NOPIC-NEXT:    pcaddu12i $a0, %ie_pcadd_hi20(ld)
+; LA32NOPIC-NEXT:    ld.w $a0, $a0, %ie_pcadd_lo12(.Lpcadd_hi1)
 ; LA32NOPIC-NEXT:    add.w $a0, $a0, $tp
 ; LA32NOPIC-NEXT:    ret
 ;
@@ -208,8 +213,9 @@ define ptr @f2() nounwind {
 ; LA32DESC:       # %bb.0: # %entry
 ; LA32DESC-NEXT:    addi.w $sp, $sp, -16
 ; LA32DESC-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
-; LA32DESC-NEXT:    pcalau12i $a0, %desc_pc_hi20(ld)
-; LA32DESC-NEXT:    addi.w $a0, $a0, %desc_pc_lo12(ld)
+; LA32DESC-NEXT:  .Lpcadd_hi1:
+; LA32DESC-NEXT:    pcaddu12i $a0, %desc_pcadd_hi20(ld)
+; LA32DESC-NEXT:    addi.w $a0, $a0, %desc_pcadd_lo12(.Lpcadd_hi1)
 ; LA32DESC-NEXT:    ld.w $ra, $a0, %desc_ld(ld)
 ; LA32DESC-NEXT:    jirl $ra, $ra, %desc_call(ld)
 ; LA32DESC-NEXT:    add.w $a0, $a0, $tp
@@ -254,8 +260,9 @@ entry:
 define ptr @f3() nounwind {
 ; LA32PIC-LABEL: f3:
 ; LA32PIC:       # %bb.0: # %entry
-; LA32PIC-NEXT:    pcalau12i $a0, %ie_pc_hi20(ie)
-; LA32PIC-NEXT:    ld.w $a0, $a0, %ie_pc_lo12(ie)
+; LA32PIC-NEXT:  .Lpcadd_hi2:
+; LA32PIC-NEXT:    pcaddu12i $a0, %ie_pcadd_hi20(ie)
+; LA32PIC-NEXT:    ld.w $a0, $a0, %ie_pcadd_lo12(.Lpcadd_hi2)
 ; LA32PIC-NEXT:    add.w $a0, $a0, $tp
 ; LA32PIC-NEXT:    ret
 ;
@@ -278,8 +285,9 @@ define ptr @f3() nounwind {
 ;
 ; LA32NOPIC-LABEL: f3:
 ; LA32NOPIC:       # %bb.0: # %entry
-; LA32NOPIC-NEXT:    pcalau12i $a0, %ie_pc_hi20(ie)
-; LA32NOPIC-NEXT:    ld.w $a0, $a0, %ie_pc_lo12(ie)
+; LA32NOPIC-NEXT:  .Lpcadd_hi2:
+; LA32NOPIC-NEXT:    pcaddu12i $a0, %ie_pcadd_hi20(ie)
+; LA32NOPIC-NEXT:    ld.w $a0, $a0, %ie_pcadd_lo12(.Lpcadd_hi2)
 ; LA32NOPIC-NEXT:    add.w $a0, $a0, $tp
 ; LA32NOPIC-NEXT:    ret
 ;
@@ -302,8 +310,9 @@ define ptr @f3() nounwind {
 ;
 ; LA32DESC-LABEL: f3:
 ; LA32DESC:       # %bb.0: # %entry
-; LA32DESC-NEXT:    pcalau12i $a0, %ie_pc_hi20(ie)
-; LA32DESC-NEXT:    ld.w $a0, $a0, %ie_pc_lo12(ie)
+; LA32DESC-NEXT:  .Lpcadd_hi2:
+; LA32DESC-NEXT:    pcaddu12i $a0, %ie_pcadd_hi20(ie)
+; LA32DESC-NEXT:    ld.w $a0, $a0, %ie_pcadd_lo12(.Lpcadd_hi2)
 ; LA32DESC-NEXT:    add.w $a0, $a0, $tp
 ; LA32DESC-NEXT:    ret
 ;
diff --git a/llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll b/llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll
index 0d441e66a0c84..7a5b04b387def 100644
--- a/llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll
+++ b/llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll
@@ -102,8 +102,9 @@ define void @t3() {
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    addi.w $sp, $sp, -64
 ; LA32-NEXT:    .cfi_def_cfa_offset 64
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.L.str)
-; LA32-NEXT:    addi.w $a0, $a0, %pc_lo12(.L.str)
+; LA32-NEXT:  .Lpcadd_hi0:
+; LA32-NEXT:    pcaddu12i $a0, %pcadd_hi20(.L.str)
+; LA32-NEXT:    addi.w $a0, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32-NEXT:    ld.h $a1, $a0, 20
 ; LA32-NEXT:    ld.w $a2, $a0, 16
 ; LA32-NEXT:    st.h $a1, $sp, 20
diff --git a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
index 16c9e754fb94d..de6c3abf4ab45 100644
--- a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
@@ -532,8 +532,9 @@ define void @test_d4(ptr %P, ptr %S) nounwind {
 ; LA32D-NEXT:    fmov.d $fa5, $fa4
 ; LA32D-NEXT:    movgr2frh.w $fa5, $a0
 ; LA32D-NEXT:    fadd.d $fa2, $fa2, $fa5
-; LA32D-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA32D-NEXT:    fld.d $fa5, $a0, %pc_lo12(.LCPI5_0)
+; LA32D-NEXT:  .Lpcadd_hi0:
+; LA32D-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI5_0)
+; LA32D-NEXT:    fld.d $fa5, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; LA32D-NEXT:    lu12i.w $a0, 262400
 ; LA32D-NEXT:    movgr2frh.w $fa4, $a0
 ; LA32D-NEXT:    fadd.d $fa1, $fa1, $fa4
@@ -760,8 +761,9 @@ define void @test_d8(ptr %P, ptr %S) nounwind {
 ; LA32D-NEXT:    lu12i.w $a0, 262400
 ; LA32D-NEXT:    movgr2frh.w $ft0, $a0
 ; LA32D-NEXT:    fadd.d $fa4, $fa4, $ft1
-; LA32D-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI6_0)
-; LA32D-NEXT:    fld.d $ft1, $a0, %pc_lo12(.LCPI6_0)
+; LA32D-NEXT:  .Lpcadd_hi1:
+; LA32D-NEXT:    pcaddu12i $a0, %pcadd_hi20(.LCPI6_0)
+; LA32D-NEXT:    fld.d $ft1, $a0, %pcadd_lo12(.Lpcadd_hi1)
 ; LA32D-NEXT:    fadd.d $fa5, $fa5, $ft0
 ; LA32D-NEXT:    fadd.d $fa3, $fa3, $ft2
 ; LA32D-NEXT:    fadd.d $fa2, $fa2, $ft0
diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s
index 86e3008ef4094..d9d03efab30d3 100644
--- a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s
+++ b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s
@@ -1,5 +1,5 @@
 # RUN: rm -rf %t && mkdir -p %t
-# RUN: llvm-mc --triple=loongarch32 -mattr=+relax --filetype=obj \
+# RUN: llvm-mc --triple=loongarch32 -mattr=+32s,+relax --filetype=obj \
 # RUN:     -o %t/la32_reloc_addsub.o %s
 # RUN: llvm-jitlink --noexec --check %s %t/la32_reloc_addsub.o \
 # RUN:     --slab-allocate=1Mb --slab-address=0x1000 --slab-page-size=0x4000
@@ -27,7 +27,10 @@ main:
 .L0:
 # Referencing named_data symbol to avoid the following relocations be
 # skipped. This macro instruction will be expand to two instructions
-# (pcalau12i + ld.w/d).
+# 32bit:
+#   (pcaddu12i + ld.w)
+# 64bit:
+#   (pcalau12i + ld.d)
   la.global $t0, named_data
 .L1:
 
diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
index 08a131d4d43f9..edc9352cd3949 100644
--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
+++ b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
@@ -98,9 +98,9 @@ bgeu $a0, $a0, 0x1FFFF
 jirl $a0, $a0, 0x20000
 # CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068]
 
-## simm20
+## simm20_pcaddu12i
 pcaddu12i $a0, 0x80000
-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-524288, 524287]
+# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pcadd_hi20) or an integer in the range [-524288, 524287]
 
 ## simm20_pcaddi
 pcaddi $a0, -0x80001
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected
index eda7e771c128b..c2f5f345624bc 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected
@@ -121,7 +121,8 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ; CHECK-NEXT:    addi.w $fp, $sp, 32
 ; CHECK-NEXT:    .cfi_def_cfa 22, 0
 ; CHECK-NEXT:    st.w $zero, $fp, -12
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(x)
+; CHECK-NEXT:  .Lpcadd_hi0:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(x)
 ; CHECK-NEXT:    ori $a1, $zero, 1
 ; CHECK-NEXT:    st.w $a1, $fp, -16
 ; CHECK-NEXT:    ori $a2, $zero, 2
@@ -130,7 +131,7 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ; CHECK-NEXT:    st.w $a3, $fp, -24
 ; CHECK-NEXT:    ori $a4, $zero, 4
 ; CHECK-NEXT:    st.w $a4, $fp, -28
-; CHECK-NEXT:    st.w $a1, $a0, %pc_lo12(x)
+; CHECK-NEXT:    st.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; CHECK-NEXT:    #APP
 ; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:    st.w $a1, $fp, -16
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected
index aab63fa7176c1..1ab256f6fa268 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected
@@ -98,7 +98,8 @@ define dso_local i32 @main() #0 {
 ; CHECK-NEXT:    addi.w $fp, $sp, 32
 ; CHECK-NEXT:    .cfi_def_cfa 22, 0
 ; CHECK-NEXT:    st.w $zero, $fp, -12
-; CHECK-NEXT:    pcalau12i $a0, %pc_hi20(x)
+; CHECK-NEXT:  .Lpcadd_hi0:
+; CHECK-NEXT:    pcaddu12i $a0, %pcadd_hi20(x)
 ; CHECK-NEXT:    ori $a1, $zero, 1
 ; CHECK-NEXT:    st.w $a1, $fp, -16
 ; CHECK-NEXT:    ori $a2, $zero, 2
@@ -107,7 +108,7 @@ define dso_local i32 @main() #0 {
 ; CHECK-NEXT:    st.w $a3, $fp, -24
 ; CHECK-NEXT:    ori $a4, $zero, 4
 ; CHECK-NEXT:    st.w $a4, $fp, -28
-; CHECK-NEXT:    st.w $a1, $a0, %pc_lo12(x)
+; CHECK-NEXT:    st.w $a1, $a0, %pcadd_lo12(.Lpcadd_hi0)
 ; CHECK-NEXT:    #APP
 ; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:    st.w $a1, $fp, -16



More information about the llvm-branch-commits mailing list