[llvm] [LoongArch] Add relax feature and keep relocations (PR #72191)

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 13 18:06:25 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-loongarch

Author: Jinyang He (MQ-mengqing)

<details>
<summary>Changes</summary>

Add relax feature. To support linker relocation, we should make relocation with a symbol rather than section plus offset, and keep all relocations with non-abs symbol.

---
Full diff: https://github.com/llvm/llvm-project/pull/72191.diff


6 Files Affected:

- (modified) llvm/lib/Target/LoongArch/LoongArch.td (+4) 
- (modified) llvm/lib/Target/LoongArch/LoongArchSubtarget.h (+2) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp (+3-2) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp (+13-5) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h (+1-1) 
- (added) llvm/test/MC/LoongArch/Relocations/relax-attr.s (+32) 


``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td
index 0675caa3b60145d..75b65fe69f26291 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.td
+++ b/llvm/lib/Target/LoongArch/LoongArch.td
@@ -102,6 +102,10 @@ def FeatureUAL
     : SubtargetFeature<"ual", "HasUAL", "true",
                        "Allow memory accesses to be unaligned">;
 
+def FeatureRelax
+    : SubtargetFeature<"relax", "HasLinkerRelax", "true",
+                       "Enable Linker relaxation">;
+
 //===----------------------------------------------------------------------===//
 // Registers, instruction descriptions ...
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
index 0fbe23f2f62d9d4..5c173675cca4ccb 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
@@ -43,6 +43,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   bool HasLaGlobalWithAbs = false;
   bool HasLaLocalWithAbs = false;
   bool HasUAL = false;
+  bool HasLinkerRelax = false;
   unsigned GRLen = 32;
   MVT GRLenVT = MVT::i32;
   LoongArchABI::ABI TargetABI = LoongArchABI::ABI_Unknown;
@@ -100,6 +101,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   bool hasLaGlobalWithAbs() const { return HasLaGlobalWithAbs; }
   bool hasLaLocalWithAbs() const { return HasLaLocalWithAbs; }
   bool hasUAL() const { return HasUAL; }
+  bool hasLinkerRelax() const { return HasLinkerRelax; }
   MVT getGRLenVT() const { return GRLenVT; }
   unsigned getGRLen() const { return GRLen; }
   LoongArchABI::ABI getTargetABI() const { return TargetABI; }
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 8744bcb45f75f30..a35916d2ad2197d 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -167,7 +167,7 @@ bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
     return true;
   switch (Fixup.getTargetKind()) {
   default:
-    return false;
+    return STI.hasFeature(LoongArch::FeatureRelax);
   case FK_Data_1:
   case FK_Data_2:
   case FK_Data_4:
@@ -192,7 +192,8 @@ bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
 
 std::unique_ptr<MCObjectTargetWriter>
 LoongArchAsmBackend::createObjectTargetWriter() const {
-  return createLoongArchELFObjectWriter(OSABI, Is64Bit);
+  return createLoongArchELFObjectWriter(
+      OSABI, Is64Bit, STI.hasFeature(LoongArch::FeatureRelax));
 }
 
 MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T,
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
index a6b9c0652639fbc..8a464b894265146 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp
@@ -20,19 +20,27 @@ using namespace llvm;
 namespace {
 class LoongArchELFObjectWriter : public MCELFObjectTargetWriter {
 public:
-  LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+  LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool EnableRelax);
 
   ~LoongArchELFObjectWriter() override;
 
+  bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
+                               unsigned Type) const override {
+    return EnableRelax;
+  }
+
 protected:
   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
                         const MCFixup &Fixup, bool IsPCRel) const override;
+  bool EnableRelax;
 };
 } // end namespace
 
-LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit)
+LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit,
+                                                   bool EnableRelax)
     : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH,
-                              /*HasRelocationAddend*/ true) {}
+                              /*HasRelocationAddend*/ true),
+      EnableRelax(EnableRelax) {}
 
 LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {}
 
@@ -87,6 +95,6 @@ unsigned LoongArchELFObjectWriter::getRelocType(MCContext &Ctx,
 }
 
 std::unique_ptr<MCObjectTargetWriter>
-llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
-  return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit);
+llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) {
+  return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit, Relax);
 }
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
index ab35a0096c8a2a2..bb05baa9b717c2c 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
@@ -36,7 +36,7 @@ MCAsmBackend *createLoongArchAsmBackend(const Target &T,
                                         const MCTargetOptions &Options);
 
 std::unique_ptr<MCObjectTargetWriter>
-createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax);
 
 } // end namespace llvm
 
diff --git a/llvm/test/MC/LoongArch/Relocations/relax-attr.s b/llvm/test/MC/LoongArch/Relocations/relax-attr.s
new file mode 100644
index 000000000000000..b1e648d850bb908
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/relax-attr.s
@@ -0,0 +1,32 @@
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=CHECKR
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section ({{.*}}) .rela.data {
+# CHECK-NEXT:     0x0 R_LARCH_64 .text 0x4
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# CHECKR:      Relocations [
+# CHECKR-NEXT:   Section ({{.*}}) .rela.text {
+# CHECKR-NEXT:     0x8 R_LARCH_B21 .L1 0x0
+# CHECKR-NEXT:     0xC R_LARCH_B16 .L1 0x0
+# CHECKR-NEXT:     0x10 R_LARCH_B26 .L1 0x0
+# CHECKR-NEXT:   }
+# CHECKR-NEXT:   Section ({{.*}}) .rela.data {
+# CHECKR-NEXT:     0x0 R_LARCH_64 .L1 0x0
+# CHECKR-NEXT:   }
+# CHECKR-NEXT: ]
+
+.text
+  nop
+.L1:
+  nop
+  beqz $a0, .L1
+  blt  $a0, $a1, .L1
+  b    .L1
+
+.data
+.dword .L1

``````````

</details>


https://github.com/llvm/llvm-project/pull/72191


More information about the llvm-commits mailing list