[llvm] [LoongArch] Emit R_LARCH_RELAX when expanding some LoadAddress (PR #72961)

Jinyang He via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 21 01:49:24 PST 2023


https://github.com/MQ-mengqing updated https://github.com/llvm/llvm-project/pull/72961

>From fba84976470f23b6b8a136518f159b9744d393e3 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang at loongson.cn>
Date: Thu, 16 Nov 2023 15:22:44 +0800
Subject: [PATCH 1/3] Emit relax relocs when expand some LoadAddress

Emit relax relocs when expand non-large la.pcrel and non-large la.got
on llvm-mc stage, which like what does on GAS.
1, la.pcrel -> PCALA_HI20 + RELAX + PCALA_LO12 + RELAX
2, la.got -> GOT_PC_HI20 + RELAX + GOT_PC_LO12 + RELAX
---
 .../AsmParser/LoongArchAsmParser.cpp          | 12 +++++++-----
 .../MCTargetDesc/LoongArchMCCodeEmitter.cpp   | 13 +++++++++++++
 .../MCTargetDesc/LoongArchMCExpr.cpp          |  7 ++++---
 .../LoongArch/MCTargetDesc/LoongArchMCExpr.h  |  8 +++++---
 llvm/test/MC/LoongArch/Relocations/relax-la.s | 19 +++++++++++++++++++
 5 files changed, 48 insertions(+), 11 deletions(-)
 create mode 100644 llvm/test/MC/LoongArch/Relocations/relax-la.s

diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
index 276374afee3808..66a37fce5dda11 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -85,7 +85,7 @@ class LoongArchAsmParser : public MCTargetAsmParser {
   // "emitLoadAddress*" functions.
   void emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
                      const MCExpr *Symbol, SmallVectorImpl<Inst> &Insts,
-                     SMLoc IDLoc, MCStreamer &Out);
+                     SMLoc IDLoc, MCStreamer &Out, bool RelaxHint = false);
 
   // Helper to emit pseudo instruction "la.abs $rd, sym".
   void emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
@@ -748,12 +748,14 @@ bool LoongArchAsmParser::ParseInstruction(ParseInstructionInfo &Info,
 void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
                                        const MCExpr *Symbol,
                                        SmallVectorImpl<Inst> &Insts,
-                                       SMLoc IDLoc, MCStreamer &Out) {
+                                       SMLoc IDLoc, MCStreamer &Out,
+                                       bool RelaxHint) {
   MCContext &Ctx = getContext();
   for (LoongArchAsmParser::Inst &Inst : Insts) {
     unsigned Opc = Inst.Opc;
     LoongArchMCExpr::VariantKind VK = Inst.VK;
-    const LoongArchMCExpr *LE = LoongArchMCExpr::create(Symbol, VK, Ctx);
+    const LoongArchMCExpr *LE =
+        LoongArchMCExpr::create(Symbol, VK, Ctx, RelaxHint);
     switch (Opc) {
     default:
       llvm_unreachable("unexpected opcode");
@@ -854,7 +856,7 @@ void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,
   Insts.push_back(
       LoongArchAsmParser::Inst(ADDI, LoongArchMCExpr::VK_LoongArch_PCALA_LO12));
 
-  emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
+  emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out, true);
 }
 
 void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc,
@@ -900,7 +902,7 @@ void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
   Insts.push_back(
       LoongArchAsmParser::Inst(LD, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12));
 
-  emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
+  emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out, true);
 }
 
 void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc,
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
index 45169becca37b7..d2ea062dc09a74 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -19,6 +19,7 @@
 #include "llvm/MC/MCInstBuilder.h"
 #include "llvm/MC/MCInstrInfo.h"
 #include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/EndianStream.h"
 
@@ -120,12 +121,15 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
   assert(MO.isExpr() && "getExprOpValue expects only expressions");
+  bool RelaxCandidate = false;
+  bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
   const MCExpr *Expr = MO.getExpr();
   MCExpr::ExprKind Kind = Expr->getKind();
   LoongArch::Fixups FixupKind = LoongArch::fixup_loongarch_invalid;
   if (Kind == MCExpr::Target) {
     const LoongArchMCExpr *LAExpr = cast<LoongArchMCExpr>(Expr);
 
+    RelaxCandidate = LAExpr->getRelaxHint();
     switch (LAExpr->getKind()) {
     case LoongArchMCExpr::VK_LoongArch_None:
     case LoongArchMCExpr::VK_LoongArch_Invalid:
@@ -270,6 +274,15 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
 
   Fixups.push_back(
       MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
+
+  // Emit an R_LARCH_RELAX if linker relaxation is enabled and LAExpr has relax
+  // hint.
+  if (EnableRelax && RelaxCandidate) {
+    const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
+    Fixups.push_back(MCFixup::create(
+        0, Dummy, MCFixupKind(LoongArch::fixup_loongarch_relax), MI.getLoc()));
+  }
+
   return 0;
 }
 
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
index 993111552a3143..82c992b1cc8c4e 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
@@ -25,9 +25,10 @@ using namespace llvm;
 
 #define DEBUG_TYPE "loongarch-mcexpr"
 
-const LoongArchMCExpr *
-LoongArchMCExpr::create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx) {
-  return new (Ctx) LoongArchMCExpr(Expr, Kind);
+const LoongArchMCExpr *LoongArchMCExpr::create(const MCExpr *Expr,
+                                               VariantKind Kind, MCContext &Ctx,
+                                               bool Hint) {
+  return new (Ctx) LoongArchMCExpr(Expr, Kind, Hint);
 }
 
 void LoongArchMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
index 0945cf82db865c..93251f8241033b 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
@@ -67,16 +67,18 @@ class LoongArchMCExpr : public MCTargetExpr {
 private:
   const MCExpr *Expr;
   const VariantKind Kind;
+  const bool RelaxHint;
 
-  explicit LoongArchMCExpr(const MCExpr *Expr, VariantKind Kind)
-      : Expr(Expr), Kind(Kind) {}
+  explicit LoongArchMCExpr(const MCExpr *Expr, VariantKind Kind, bool Hint)
+      : Expr(Expr), Kind(Kind), RelaxHint(Hint) {}
 
 public:
   static const LoongArchMCExpr *create(const MCExpr *Expr, VariantKind Kind,
-                                       MCContext &Ctx);
+                                       MCContext &Ctx, bool Hint = false);
 
   VariantKind getKind() const { return Kind; }
   const MCExpr *getSubExpr() const { return Expr; }
+  bool getRelaxHint() const { return RelaxHint; }
 
   void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
   bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
diff --git a/llvm/test/MC/LoongArch/Relocations/relax-la.s b/llvm/test/MC/LoongArch/Relocations/relax-la.s
new file mode 100644
index 00000000000000..a17605b42f851d
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/relax-la.s
@@ -0,0 +1,19 @@
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# CHECK:       Relocations [
+# CHECK-NEXT:    Section ({{.*}}) .rela.text {
+# CHECK-NEXT:      0x0 R_LARCH_PCALA_HI20 .L1 0x0
+# CHECK-NEXT:      0x0 R_LARCH_RELAX - 0x0
+# CHECK-NEXT:      0x4 R_LARCH_PCALA_LO12 .L1 0x0
+# CHECK-NEXT:      0x4 R_LARCH_RELAX - 0x0
+# CHECK-NEXT:      0x8 R_LARCH_GOT_PC_HI20 .L1 0x0
+# CHECK-NEXT:      0x8 R_LARCH_RELAX - 0x0
+# CHECK-NEXT:      0xC R_LARCH_GOT_PC_LO12 .L1 0x0
+# CHECK-NEXT:      0xC R_LARCH_RELAX - 0x0
+# CHECK-NEXT:    }
+
+.text
+.L1:
+  la.pcrel $a0, .L1
+  la.got   $a0, .L1

>From 607c7e7a1cda243c1bf33bacd1a24195d807a156 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang at loongson.cn>
Date: Wed, 6 Dec 2023 14:12:22 +0800
Subject: [PATCH 2/3] Delete relax-la test and test it in macros-la

---
 llvm/test/MC/LoongArch/Macros/macros-la.s     | 44 +++++++++++++++++++
 llvm/test/MC/LoongArch/Relocations/relax-la.s | 19 --------
 2 files changed, 44 insertions(+), 19 deletions(-)
 delete mode 100644 llvm/test/MC/LoongArch/Relocations/relax-la.s

diff --git a/llvm/test/MC/LoongArch/Macros/macros-la.s b/llvm/test/MC/LoongArch/Macros/macros-la.s
index 924e4326b8e5d6..358fb70ccb6572 100644
--- a/llvm/test/MC/LoongArch/Macros/macros-la.s
+++ b/llvm/test/MC/LoongArch/Macros/macros-la.s
@@ -1,14 +1,26 @@
 # RUN: llvm-mc --triple=loongarch64 %s | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.relax
+# RUN: llvm-readobj -r %t.relax | FileCheck %s --check-prefixes=RELOC,RELAX
 
 la.abs $a0, sym_abs
 # CHECK:      lu12i.w $a0, %abs_hi20(sym_abs)
 # CHECK-NEXT: ori $a0, $a0, %abs_lo12(sym_abs)
 # CHECK-NEXT: lu32i.d $a0, %abs64_lo20(sym_abs)
 # CHECK-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_abs)
+# RELOC:      R_LARCH_ABS_HI20 sym_abs 0x0
+# RELOC-NEXT: R_LARCH_ABS_LO12 sym_abs 0x0
+# RELOC-NEXT: R_LARCH_ABS64_LO20 sym_abs 0x0
+# RELOC-NEXT: R_LARCH_ABS64_HI12 sym_abs 0x0
 
 la.pcrel $a0, sym_pcrel
 # CHECK:      pcalau12i $a0, %pc_hi20(sym_pcrel)
 # CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(sym_pcrel)
+# RELOC:      R_LARCH_PCALA_HI20 sym_pcrel 0x0
+# RELAX-NEXT: R_LARCH_RELAX - 0x0
+# RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel 0x0
+# RELAX-NEXT: R_LARCH_RELAX - 0x0
 
 la.pcrel $a0, $a1, sym_pcrel_large
 # CHECK:      pcalau12i $a0, %pc_hi20(sym_pcrel_large)
@@ -16,10 +28,18 @@ la.pcrel $a0, $a1, sym_pcrel_large
 # CHECK-NEXT: lu32i.d $a1, %pc64_lo20(sym_pcrel_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %pc64_hi12(sym_pcrel_large)
 # CHECK-NEXT: add.d $a0, $a0, $a1
+# RELOC:      R_LARCH_PCALA_HI20 sym_pcrel_large 0x0
+# RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel_large 0x0
+# RELOC-NEXT: R_LARCH_PCALA64_LO20 sym_pcrel_large 0x0
+# RELOC-NEXT: R_LARCH_PCALA64_HI12 sym_pcrel_large 0x0
 
 la.got $a0, sym_got
 # CHECK:      pcalau12i $a0, %got_pc_hi20(sym_got)
 # CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(sym_got)
+# RELOC:      R_LARCH_GOT_PC_HI20 sym_got 0x0
+# RELAX-NEXT: R_LARCH_RELAX - 0x0
+# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got 0x0
+# RELAX-NEXT: R_LARCH_RELAX - 0x0
 
 la.got $a0, $a1, sym_got_large
 # CHECK:      pcalau12i $a0, %got_pc_hi20(sym_got_large)
@@ -27,14 +47,22 @@ la.got $a0, $a1, sym_got_large
 # CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_got_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_got_large)
 # CHECK-NEXT: ldx.d $a0, $a0, $a1
+# RELOC:      R_LARCH_GOT_PC_HI20 sym_got_large 0x0
+# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got_large 0x0
+# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_got_large 0x0
+# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_got_large 0x0
 
 la.tls.le $a0, sym_le
 # CHECK:      lu12i.w $a0, %le_hi20(sym_le)
 # CHECK-NEXT: ori $a0, $a0, %le_lo12(sym_le)
+# RELOC:      R_LARCH_TLS_LE_HI20 sym_le 0x0
+# RELOC-NEXT: R_LARCH_TLS_LE_LO12 sym_le 0x0
 
 la.tls.ie $a0, sym_ie
 # CHECK:      pcalau12i $a0, %ie_pc_hi20(sym_ie)
 # CHECK-NEXT: ld.d $a0, $a0, %ie_pc_lo12(sym_ie)
+# RELOC:      R_LARCH_TLS_IE_PC_HI20 sym_ie 0x0
+# RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie 0x0
 
 la.tls.ie $a0, $a1, sym_ie_large
 # CHECK:      pcalau12i $a0, %ie_pc_hi20(sym_ie_large)
@@ -42,10 +70,16 @@ la.tls.ie $a0, $a1, sym_ie_large
 # CHECK-NEXT: lu32i.d $a1, %ie64_pc_lo20(sym_ie_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %ie64_pc_hi12(sym_ie_large)
 # CHECK-NEXT: ldx.d $a0, $a0, $a1
+# RELOC:      R_LARCH_TLS_IE_PC_HI20 sym_ie_large 0x0
+# RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie_large 0x0
+# RELOC-NEXT: R_LARCH_TLS_IE64_PC_LO20 sym_ie_large 0x0
+# RELOC-NEXT: R_LARCH_TLS_IE64_PC_HI12 sym_ie_large 0x0
 
 la.tls.ld $a0, sym_ld
 # CHECK:      pcalau12i $a0, %ld_pc_hi20(sym_ld)
 # CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_ld)
+# RELOC:      R_LARCH_TLS_LD_PC_HI20 sym_ld 0x0
+# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld 0x0
 
 la.tls.ld $a0, $a1, sym_ld_large
 # CHECK:      pcalau12i $a0, %ld_pc_hi20(sym_ld_large)
@@ -53,10 +87,16 @@ la.tls.ld $a0, $a1, sym_ld_large
 # CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_ld_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_ld_large)
 # CHECK-NEXT: add.d $a0, $a0, $a1
+# RELOC:      R_LARCH_TLS_LD_PC_HI20 sym_ld_large 0x0
+# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld_large 0x0
+# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_ld_large 0x0
+# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_ld_large 0x0
 
 la.tls.gd $a0, sym_gd
 # CHECK:      pcalau12i $a0, %gd_pc_hi20(sym_gd)
 # CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_gd)
+# RELOC:      R_LARCH_TLS_GD_PC_HI20 sym_gd 0x0
+# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd 0x0
 
 la.tls.gd $a0, $a1, sym_gd_large
 # CHECK:      pcalau12i $a0, %gd_pc_hi20(sym_gd_large)
@@ -64,3 +104,7 @@ la.tls.gd $a0, $a1, sym_gd_large
 # CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_gd_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_gd_large)
 # CHECK-NEXT: add.d $a0, $a0, $a1
+# RELOC:      R_LARCH_TLS_GD_PC_HI20 sym_gd_large 0x0
+# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd_large 0x0
+# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_gd_large 0x0
+# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_gd_large 0x0
diff --git a/llvm/test/MC/LoongArch/Relocations/relax-la.s b/llvm/test/MC/LoongArch/Relocations/relax-la.s
deleted file mode 100644
index a17605b42f851d..00000000000000
--- a/llvm/test/MC/LoongArch/Relocations/relax-la.s
+++ /dev/null
@@ -1,19 +0,0 @@
-# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t
-# RUN: llvm-readobj -r %t | FileCheck %s
-
-# CHECK:       Relocations [
-# CHECK-NEXT:    Section ({{.*}}) .rela.text {
-# CHECK-NEXT:      0x0 R_LARCH_PCALA_HI20 .L1 0x0
-# CHECK-NEXT:      0x0 R_LARCH_RELAX - 0x0
-# CHECK-NEXT:      0x4 R_LARCH_PCALA_LO12 .L1 0x0
-# CHECK-NEXT:      0x4 R_LARCH_RELAX - 0x0
-# CHECK-NEXT:      0x8 R_LARCH_GOT_PC_HI20 .L1 0x0
-# CHECK-NEXT:      0x8 R_LARCH_RELAX - 0x0
-# CHECK-NEXT:      0xC R_LARCH_GOT_PC_LO12 .L1 0x0
-# CHECK-NEXT:      0xC R_LARCH_RELAX - 0x0
-# CHECK-NEXT:    }
-
-.text
-.L1:
-  la.pcrel $a0, .L1
-  la.got   $a0, .L1

>From 32808a324501839f4de3ed32ccfdcd16265785e6 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang at loongson.cn>
Date: Thu, 21 Dec 2023 17:40:59 +0800
Subject: [PATCH 3/3] Update tests due to #72960 merged and address
 @SixWeining's comments.

1, update relax-addsub test to check `la.pcrel` RELAX.
2, update subsection test to check RELAX.
3, add check reloc start/end flags.
4, change non-first CHECK to CHECK-NEXT and add CHECK-EMPTY.
---
 llvm/test/MC/LoongArch/Macros/macros-la.s     | 64 ++++++++++++-------
 llvm/test/MC/LoongArch/Misc/subsection.s      |  2 +-
 .../MC/LoongArch/Relocations/relax-addsub.s   | 16 +++--
 3 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/llvm/test/MC/LoongArch/Macros/macros-la.s b/llvm/test/MC/LoongArch/Macros/macros-la.s
index 358fb70ccb6572..1a1d12d7d7dfd1 100644
--- a/llvm/test/MC/LoongArch/Macros/macros-la.s
+++ b/llvm/test/MC/LoongArch/Macros/macros-la.s
@@ -4,107 +4,125 @@
 # RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.relax
 # RUN: llvm-readobj -r %t.relax | FileCheck %s --check-prefixes=RELOC,RELAX
 
+# RELOC:      Relocations [
+# RELOC-NEXT:   Section ({{.*}}) .rela.text {
+
 la.abs $a0, sym_abs
 # CHECK:      lu12i.w $a0, %abs_hi20(sym_abs)
 # CHECK-NEXT: ori $a0, $a0, %abs_lo12(sym_abs)
 # CHECK-NEXT: lu32i.d $a0, %abs64_lo20(sym_abs)
 # CHECK-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_abs)
-# RELOC:      R_LARCH_ABS_HI20 sym_abs 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_ABS_HI20 sym_abs 0x0
 # RELOC-NEXT: R_LARCH_ABS_LO12 sym_abs 0x0
 # RELOC-NEXT: R_LARCH_ABS64_LO20 sym_abs 0x0
 # RELOC-NEXT: R_LARCH_ABS64_HI12 sym_abs 0x0
 
 la.pcrel $a0, sym_pcrel
-# CHECK:      pcalau12i $a0, %pc_hi20(sym_pcrel)
+# CHECK-NEXT: pcalau12i $a0, %pc_hi20(sym_pcrel)
 # CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(sym_pcrel)
-# RELOC:      R_LARCH_PCALA_HI20 sym_pcrel 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_PCALA_HI20 sym_pcrel 0x0
 # RELAX-NEXT: R_LARCH_RELAX - 0x0
 # RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel 0x0
 # RELAX-NEXT: R_LARCH_RELAX - 0x0
 
 la.pcrel $a0, $a1, sym_pcrel_large
-# CHECK:      pcalau12i $a0, %pc_hi20(sym_pcrel_large)
+# CHECK-NEXT: pcalau12i $a0, %pc_hi20(sym_pcrel_large)
 # CHECK-NEXT: addi.d $a1, $zero, %pc_lo12(sym_pcrel_large)
 # CHECK-NEXT: lu32i.d $a1, %pc64_lo20(sym_pcrel_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %pc64_hi12(sym_pcrel_large)
 # CHECK-NEXT: add.d $a0, $a0, $a1
-# RELOC:      R_LARCH_PCALA_HI20 sym_pcrel_large 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_PCALA_HI20 sym_pcrel_large 0x0
 # RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel_large 0x0
 # RELOC-NEXT: R_LARCH_PCALA64_LO20 sym_pcrel_large 0x0
 # RELOC-NEXT: R_LARCH_PCALA64_HI12 sym_pcrel_large 0x0
 
 la.got $a0, sym_got
-# CHECK:      pcalau12i $a0, %got_pc_hi20(sym_got)
+# CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(sym_got)
 # CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(sym_got)
-# RELOC:      R_LARCH_GOT_PC_HI20 sym_got 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_GOT_PC_HI20 sym_got 0x0
 # RELAX-NEXT: R_LARCH_RELAX - 0x0
 # RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got 0x0
 # RELAX-NEXT: R_LARCH_RELAX - 0x0
 
 la.got $a0, $a1, sym_got_large
-# CHECK:      pcalau12i $a0, %got_pc_hi20(sym_got_large)
+# CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(sym_got_large)
 # CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_got_large)
 # CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_got_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_got_large)
 # CHECK-NEXT: ldx.d $a0, $a0, $a1
-# RELOC:      R_LARCH_GOT_PC_HI20 sym_got_large 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_GOT_PC_HI20 sym_got_large 0x0
 # RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got_large 0x0
 # RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_got_large 0x0
 # RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_got_large 0x0
 
 la.tls.le $a0, sym_le
-# CHECK:      lu12i.w $a0, %le_hi20(sym_le)
+# CHECK-NEXT: lu12i.w $a0, %le_hi20(sym_le)
 # CHECK-NEXT: ori $a0, $a0, %le_lo12(sym_le)
-# RELOC:      R_LARCH_TLS_LE_HI20 sym_le 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_TLS_LE_HI20 sym_le 0x0
 # RELOC-NEXT: R_LARCH_TLS_LE_LO12 sym_le 0x0
 
 la.tls.ie $a0, sym_ie
-# CHECK:      pcalau12i $a0, %ie_pc_hi20(sym_ie)
+# CHECK-NEXT: pcalau12i $a0, %ie_pc_hi20(sym_ie)
 # CHECK-NEXT: ld.d $a0, $a0, %ie_pc_lo12(sym_ie)
-# RELOC:      R_LARCH_TLS_IE_PC_HI20 sym_ie 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_TLS_IE_PC_HI20 sym_ie 0x0
 # RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie 0x0
 
 la.tls.ie $a0, $a1, sym_ie_large
-# CHECK:      pcalau12i $a0, %ie_pc_hi20(sym_ie_large)
+# CHECK-NEXT: pcalau12i $a0, %ie_pc_hi20(sym_ie_large)
 # CHECK-NEXT: addi.d $a1, $zero, %ie_pc_lo12(sym_ie_large)
 # CHECK-NEXT: lu32i.d $a1, %ie64_pc_lo20(sym_ie_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %ie64_pc_hi12(sym_ie_large)
 # CHECK-NEXT: ldx.d $a0, $a0, $a1
-# RELOC:      R_LARCH_TLS_IE_PC_HI20 sym_ie_large 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_TLS_IE_PC_HI20 sym_ie_large 0x0
 # RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie_large 0x0
 # RELOC-NEXT: R_LARCH_TLS_IE64_PC_LO20 sym_ie_large 0x0
 # RELOC-NEXT: R_LARCH_TLS_IE64_PC_HI12 sym_ie_large 0x0
 
 la.tls.ld $a0, sym_ld
-# CHECK:      pcalau12i $a0, %ld_pc_hi20(sym_ld)
+# CHECK-NEXT: pcalau12i $a0, %ld_pc_hi20(sym_ld)
 # CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_ld)
-# RELOC:      R_LARCH_TLS_LD_PC_HI20 sym_ld 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_TLS_LD_PC_HI20 sym_ld 0x0
 # RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld 0x0
 
 la.tls.ld $a0, $a1, sym_ld_large
-# CHECK:      pcalau12i $a0, %ld_pc_hi20(sym_ld_large)
+# CHECK-NEXT: pcalau12i $a0, %ld_pc_hi20(sym_ld_large)
 # CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_ld_large)
 # CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_ld_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_ld_large)
 # CHECK-NEXT: add.d $a0, $a0, $a1
-# RELOC:      R_LARCH_TLS_LD_PC_HI20 sym_ld_large 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_TLS_LD_PC_HI20 sym_ld_large 0x0
 # RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld_large 0x0
 # RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_ld_large 0x0
 # RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_ld_large 0x0
 
 la.tls.gd $a0, sym_gd
-# CHECK:      pcalau12i $a0, %gd_pc_hi20(sym_gd)
+# CHECK-NEXT: pcalau12i $a0, %gd_pc_hi20(sym_gd)
 # CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_gd)
-# RELOC:      R_LARCH_TLS_GD_PC_HI20 sym_gd 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_TLS_GD_PC_HI20 sym_gd 0x0
 # RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd 0x0
 
 la.tls.gd $a0, $a1, sym_gd_large
-# CHECK:      pcalau12i $a0, %gd_pc_hi20(sym_gd_large)
+# CHECK-NEXT: pcalau12i $a0, %gd_pc_hi20(sym_gd_large)
 # CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_gd_large)
 # CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_gd_large)
 # CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_gd_large)
 # CHECK-NEXT: add.d $a0, $a0, $a1
-# RELOC:      R_LARCH_TLS_GD_PC_HI20 sym_gd_large 0x0
+# CHECK-EMPTY:
+# RELOC-NEXT: R_LARCH_TLS_GD_PC_HI20 sym_gd_large 0x0
 # RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd_large 0x0
 # RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_gd_large 0x0
 # RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_gd_large 0x0
+
+# RELOC-NEXT:   }
+# RELOC-NEXT: ]
diff --git a/llvm/test/MC/LoongArch/Misc/subsection.s b/llvm/test/MC/LoongArch/Misc/subsection.s
index 0bd22b474536c0..566a2408d6913d 100644
--- a/llvm/test/MC/LoongArch/Misc/subsection.s
+++ b/llvm/test/MC/LoongArch/Misc/subsection.s
@@ -1,5 +1,5 @@
 # RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,NORELAX --implicit-check-not=error:
-## TODO: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,RELAX --implicit-check-not=error:
+# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,RELAX --implicit-check-not=error:
 
 a:
   nop
diff --git a/llvm/test/MC/LoongArch/Relocations/relax-addsub.s b/llvm/test/MC/LoongArch/Relocations/relax-addsub.s
index 532eb4e0561ac7..c4454f5bb98d11 100644
--- a/llvm/test/MC/LoongArch/Relocations/relax-addsub.s
+++ b/llvm/test/MC/LoongArch/Relocations/relax-addsub.s
@@ -18,7 +18,9 @@
 # RELAX:       Relocations [
 # RELAX-NEXT:    Section ({{.*}}) .rela.text {
 # RELAX-NEXT:      0x10 R_LARCH_PCALA_HI20 .L1 0x0
+# RELAX-NEXT:      0x10 R_LARCH_RELAX - 0x0
 # RELAX-NEXT:      0x14 R_LARCH_PCALA_LO12 .L1 0x0
+# RELAX-NEXT:      0x14 R_LARCH_RELAX - 0x0
 # RELAX-NEXT:    }
 # RELAX-NEXT:    Section ({{.*}}) .rela.data {
 # RELAX-NEXT:      0xF R_LARCH_ADD8 .L3 0x0
@@ -29,13 +31,21 @@
 # RELAX-NEXT:      0x12 R_LARCH_SUB32 .L2 0x0
 # RELAX-NEXT:      0x16 R_LARCH_ADD64 .L3 0x0
 # RELAX-NEXT:      0x16 R_LARCH_SUB64 .L2 0x0
+# RELAX-NEXT:      0x1E R_LARCH_ADD8 .L4 0x0
+# RELAX-NEXT:      0x1E R_LARCH_SUB8 .L3 0x0
+# RELAX-NEXT:      0x1F R_LARCH_ADD16 .L4 0x0
+# RELAX-NEXT:      0x1F R_LARCH_SUB16 .L3 0x0
+# RELAX-NEXT:      0x21 R_LARCH_ADD32 .L4 0x0
+# RELAX-NEXT:      0x21 R_LARCH_SUB32 .L3 0x0
+# RELAX-NEXT:      0x25 R_LARCH_ADD64 .L4 0x0
+# RELAX-NEXT:      0x25 R_LARCH_SUB64 .L3 0x0
 # RELAX-NEXT:    }
 # RELAX-NEXT:  ]
 
 # RELAX:      Hex dump of section '.data':
 # RELAX-NEXT: 0x00000000 04040004 00000004 00000000 00000000
-# RELAX-NEXT: 0x00000010 00000000 00000000 00000000 00000808
-# RELAX-NEXT: 0x00000020 00080000 00080000 00000000 00
+# RELAX-NEXT: 0x00000010 00000000 00000000 00000000 00000000
+# RELAX-NEXT: 0x00000020 00000000 00000000 00000000 00
 
 .text
 .L1:
@@ -60,8 +70,6 @@
 .short .L3 - .L2
 .word  .L3 - .L2
 .dword .L3 - .L2
-## TODO
-## With relaxation, emit relocs because la.pcrel is a linker-relaxable inst.
 .byte  .L4 - .L3
 .short .L4 - .L3
 .word  .L4 - .L3



More information about the llvm-commits mailing list