-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[JITLink][LoongArch] Add label addition and subtraction relocations #122262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Member
|
@llvm/pr-subscribers-backend-loongarch Author: ZhaoQi (zhaoqi5) ChangesFull diff: https://github.com/llvm/llvm-project/pull/122262.diff 4 Files Affected:
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
index d6025edf7d110d..1d763e1255fc21 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
@@ -14,8 +14,10 @@
#define LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H
#include "TableManager.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
+#include "llvm/Support/LEB128.h"
namespace llvm {
namespace jitlink {
@@ -226,6 +228,90 @@ enum EdgeKind_loongarch : Edge::Kind {
///
Call36PCRel,
+ /// low 6 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (*{1}Fixup + (Target + Addend) & 0x3f) : int8
+ ///
+ Add6,
+
+ /// 8 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (Target + *{1}Fixup + Addend) : int8
+ ///
+ Add8,
+
+ /// 16 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (Target + *{2}Fixup + Addend) : int16
+ ///
+ Add16,
+
+ /// 32 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (Target + *{4}Fixup + Addend) : int32
+ ///
+ Add32,
+
+ /// 64 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (Target + *{8}Fixup + Addend) : int64
+ ///
+ Add64,
+
+ /// ULEB128 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (Target + *{16}Fixup + Addend) : uleb128
+ ///
+ AddUleb128,
+
+ /// low 6 bits label subtraction
+ ///
+ /// Fixup expression:
+ /// Fixup <- (*{1}Fixup - (Target + Addend) & 0x3f) : int8
+ ///
+ Sub6,
+
+ /// 8 bits label subtraction
+ ///
+ /// Fixup expression:
+ /// Fixup <- (*{1}Fixup - Target - Addend) : int8
+ ///
+ Sub8,
+
+ /// 16 bits label subtraction
+ ///
+ /// Fixup expression:
+ /// Fixup <- (*{2}Fixup - Target - Addend) : int16
+ ///
+ Sub16,
+
+ /// 32 bits label subtraction
+ ///
+ /// Fixup expression:
+ /// Fixup <- (*{4}Fixup - Target - Addend) : int32
+ ///
+ Sub32,
+
+ /// 64 bits label subtraction
+ ///
+ /// Fixup expression:
+ /// Fixup <- (*{8}Fixup - Target - Addend) : int64
+ ///
+ Sub64,
+
+ /// ULEB128 bits label subtraction
+ ///
+ /// Fixup expression:
+ /// Fixup <- (*{16}Fixup - Target - Addend) : uleb128
+ ///
+ SubUleb128,
+
/// Alignment requirement used by linker relaxation.
///
/// Linker relaxation will use this to ensure all code sequences are properly
@@ -369,6 +455,100 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) {
*(little32_t *)(FixupPtr + 4) = Jirl | Lo16;
break;
}
+ case Add6: {
+ int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
+ Value += ((TargetAddress + Addend) & 0x3f);
+ *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
+ break;
+ }
+ case Add8: {
+ int64_t Value =
+ TargetAddress + *(reinterpret_cast<const int8_t *>(FixupPtr)) + Addend;
+ *FixupPtr = static_cast<int8_t>(Value);
+ break;
+ }
+ case Add16: {
+ int64_t Value =
+ TargetAddress + support::endian::read16le(FixupPtr) + Addend;
+ *(little16_t *)FixupPtr = static_cast<int16_t>(Value);
+ break;
+ }
+ case Add32: {
+ int64_t Value =
+ TargetAddress + support::endian::read32le(FixupPtr) + Addend;
+ *(little32_t *)FixupPtr = static_cast<int32_t>(Value);
+ break;
+ }
+ case Add64: {
+ int64_t Value =
+ TargetAddress + support::endian::read64le(FixupPtr) + Addend;
+ *(little64_t *)FixupPtr = static_cast<int64_t>(Value);
+ break;
+ }
+ case AddUleb128: {
+ const uint32_t Maxcount = 1 + 64 / 7;
+ uint32_t Count;
+ const char *Error = nullptr;
+ uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)),
+ &Count, nullptr, &Error);
+
+ if (Count > Maxcount || (Count == Maxcount && Error))
+ return make_error<JITLinkError>(
+ "0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) +
+ ": extra space for uleb128");
+
+ uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL;
+ encodeULEB128((Orig + TargetAddress + Addend) & Mask,
+ (reinterpret_cast<uint8_t *>(FixupPtr)), Count);
+ break;
+ }
+ case Sub6: {
+ int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
+ Value -= ((TargetAddress + Addend) & 0x3f);
+ *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
+ break;
+ }
+ case Sub8: {
+ int64_t Value =
+ *(reinterpret_cast<const int8_t *>(FixupPtr)) - TargetAddress - Addend;
+ *FixupPtr = static_cast<int8_t>(Value);
+ break;
+ }
+ case Sub16: {
+ int64_t Value =
+ support::endian::read16le(FixupPtr) - TargetAddress - Addend;
+ *(little16_t *)FixupPtr = static_cast<int16_t>(Value);
+ break;
+ }
+ case Sub32: {
+ int64_t Value =
+ support::endian::read32le(FixupPtr) - TargetAddress - Addend;
+ *(little32_t *)FixupPtr = static_cast<int32_t>(Value);
+ break;
+ }
+ case Sub64: {
+ int64_t Value =
+ support::endian::read64le(FixupPtr) - TargetAddress - Addend;
+ *(little64_t *)FixupPtr = static_cast<int64_t>(Value);
+ break;
+ }
+ case SubUleb128: {
+ const uint32_t Maxcount = 1 + 64 / 7;
+ uint32_t Count;
+ const char *Error = nullptr;
+ uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)),
+ &Count, nullptr, &Error);
+
+ if (Count > Maxcount || (Count == Maxcount && Error))
+ return make_error<JITLinkError>(
+ "0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) +
+ ": extra space for uleb128");
+
+ uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL;
+ encodeULEB128((Orig - TargetAddress - Addend) & Mask,
+ (reinterpret_cast<uint8_t *>(FixupPtr)), Count);
+ break;
+ }
case AlignRelaxable:
// Ignore when the relaxation pass did not run
break;
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
index 3f0a7b645e83fc..f23fb346c55f90 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
@@ -306,6 +306,30 @@ class ELFLinkGraphBuilder_loongarch : public ELFLinkGraphBuilder<ELFT> {
return RequestGOTAndTransformToPageOffset12;
case ELF::R_LARCH_CALL36:
return Call36PCRel;
+ case ELF::R_LARCH_ADD6:
+ return Add6;
+ case ELF::R_LARCH_ADD8:
+ return Add8;
+ case ELF::R_LARCH_ADD16:
+ return Add16;
+ case ELF::R_LARCH_ADD32:
+ return Add32;
+ case ELF::R_LARCH_ADD64:
+ return Add64;
+ case ELF::R_LARCH_ADD_ULEB128:
+ return AddUleb128;
+ case ELF::R_LARCH_SUB6:
+ return Sub6;
+ case ELF::R_LARCH_SUB8:
+ return Sub8;
+ case ELF::R_LARCH_SUB16:
+ return Sub16;
+ case ELF::R_LARCH_SUB32:
+ return Sub32;
+ case ELF::R_LARCH_SUB64:
+ return Sub64;
+ case ELF::R_LARCH_SUB_ULEB128:
+ return SubUleb128;
case ELF::R_LARCH_ALIGN:
return AlignRelaxable;
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
index a5579b074de7cf..55389adb31b60e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
@@ -52,6 +52,18 @@ const char *getEdgeKindName(Edge::Kind K) {
KIND_NAME_CASE(RequestGOTAndTransformToPage20)
KIND_NAME_CASE(RequestGOTAndTransformToPageOffset12)
KIND_NAME_CASE(Call36PCRel)
+ KIND_NAME_CASE(Add6)
+ KIND_NAME_CASE(Add8)
+ KIND_NAME_CASE(Add16)
+ KIND_NAME_CASE(Add32)
+ KIND_NAME_CASE(Add64)
+ KIND_NAME_CASE(AddUleb128)
+ KIND_NAME_CASE(Sub6)
+ KIND_NAME_CASE(Sub8)
+ KIND_NAME_CASE(Sub16)
+ KIND_NAME_CASE(Sub32)
+ KIND_NAME_CASE(Sub64)
+ KIND_NAME_CASE(SubUleb128)
KIND_NAME_CASE(AlignRelaxable)
default:
return getGenericEdgeKindName(K);
diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s
new file mode 100644
index 00000000000000..86e3008ef40943
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s
@@ -0,0 +1,53 @@
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc --triple=loongarch32 -mattr=+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
+# RUN: llvm-mc --triple=loongarch64 -mattr=+relax --filetype=obj \
+# RUN: -o %t/la64_reloc_addsub.o %s
+# RUN: llvm-jitlink --noexec --check %s %t/la64_reloc_addsub.o \
+# RUN: --slab-allocate=1Mb --slab-address=0x1000 --slab-page-size=0x4000
+
+# jitlink-check: *{8}(named_data) = 0x8
+# jitlink-check: *{4}(named_data+8) = 0x8
+# jitlink-check: *{2}(named_data+12) = 0x8
+# jitlink-check: *{1}(named_data+14) = 0x8
+# jitlink-check: *{1}(named_data+15) = 0x10
+
+# jitlink-check: *{1}(leb_data) = 0x8
+# jitlink-check: *{2}(leb_data+1) = 0x180
+# jitlink-check: *{8}(leb_data+3) = 0xfffffffffffffff8
+# jitlink-check: *{2}(leb_data+11) = 0x1ff
+# jitlink-check: *{1}(leb_data+13) = 0x7f
+# jitlink-check: *{2}(leb_data+14) = 0x181
+
+.section .alloc_data,"ax",@progbits
+.global main
+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).
+ la.global $t0, named_data
+.L1:
+
+named_data:
+.reloc named_data+15, R_LARCH_ADD6, .L1
+.reloc named_data+15, R_LARCH_SUB6, .L0
+.dword .L1 - .L0
+.word .L1 - .L0
+.half .L1 - .L0
+.byte .L1 - .L0
+.byte 0x8
+
+.size named_data, 16
+
+leb_data:
+.uleb128 .L1 - .L0
+.uleb128 .L1 - .L0 + 120
+.uleb128 -(.L1 - .L0)
+.uleb128 leb_end - leb_data + 111
+.uleb128 leb_end - leb_data + 113
+leb_end:
+
+.size leb_data, 16
|
Linker relaxation is not implemented for jitlink now (maybe implement in the future). But if relaxation is enabled by clang, R_LARCH_RELAX and R_LARCH_ALIGN relocations will be emitted. So we just ignore linker relaxation and check the alignment now. If not, interpreting C++ code using clang-repl when relaxation is enabled will occur error: `JIT session error: Unsupported loongarch relocation:102: R_LARCH_ALIGN`. Similar to: f5b5398.
Linker relaxation is not implemented for jitlink now. But if relaxation is enabled by clang, R_LARCH_RELAX and R_LARCH_ALIGN relocations will be emitted. This commit adapts lld's algorithm to jitlink. Currently, only relaxing R_LARCH_ALIGN is implemented. Other relaxable relocs can be implemented in the future. Without this, interpreting C++ code using clang-repl or running ir using lli when relaxation is enabled will occur error: `JIT session error: Unsupported loongarch relocation:102: R_LARCH_ALIGN`. Similar to 310473c but only implement align.
41de630 to
91aea9b
Compare
92a79be to
4398bd9
Compare
wangleiat
approved these changes
Jan 24, 2025
Contributor
wangleiat
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.