-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[X86][APX] Suppress EGPR/NDD instructions for relocations #136660
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
Conversation
Introduce an option (-mapx-relax-relocations) to control the emission of the new APX relocations. It's off by default to keep backward compatibility with older version of ld and other linkers without APX support. And EGPR and NDD are also suppressed to avoid the instructions updated incorrectly by older version of linker.
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-x86 Author: Feng Zou (fzou1) ChangesIntroduce an option (-mapx-relax-relocations) to control the emission of the new APX relocations. It's off by default to keep backward compatibility with old version of ld and other linkers without APX support. And EGPR and NDD are also suppressed to avoid the instructions updated incorrectly by old version of linkers. Patch is 57.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136660.diff 37 Files Affected:
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
index c3f30e2a8e9c0..fa3063d6be9a7 100644
--- a/clang/CMakeLists.txt
+++ b/clang/CMakeLists.txt
@@ -219,6 +219,9 @@ set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld")
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL
"enable x86 relax relocations by default")
+set(ENABLE_X86_APX_RELAX_RELOCATIONS OFF CACHE BOOL
+ "Enable x86 APX relax relocations by default")
+
set(PPC_LINUX_DEFAULT_IEEELONGDOUBLE OFF CACHE BOOL
"Enable IEEE binary128 as default long double format on PowerPC Linux.")
diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake
index 99890b8246ad7..22eef24b611a8 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -49,6 +49,7 @@ set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
+set(ENABLE_X86_APX_RELAX_RELOCATIONS OFF CACHE BOOL "")
# TODO(#67176): relative-vtables doesn't play well with different default
# visibilities. Making everything hidden visibility causes other complications
diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake
index 83336589da305..550d94d1ec6a5 100644
--- a/clang/cmake/caches/Fuchsia.cmake
+++ b/clang/cmake/caches/Fuchsia.cmake
@@ -89,6 +89,7 @@ set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
+set(ENABLE_X86_APX_RELAX_RELOCATIONS OFF CACHE BOOL "")
set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "")
set(LLVM_ENABLE_BACKTRACES ON CACHE BOOL "")
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index c5990fb248689..875facd6cfc63 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -201,6 +201,7 @@ CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get u
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
CODEGENOPT(PPCUseFullRegisterNames, 1, 0) ///< Print full register names in assembly
CODEGENOPT(X86RelaxRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
+CODEGENOPT(X86APXRelaxRelocations, 1, 0) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(X86Sse2Avx , 1, 0) ///< -Wa,-msse2avx
/// When false, this attempts to generate code as if the result of an
diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake
index 00c352b458c34..db7fc2ba45eaf 100644
--- a/clang/include/clang/Config/config.h.cmake
+++ b/clang/include/clang/Config/config.h.cmake
@@ -72,6 +72,9 @@
/* enable x86 relax relocations by default */
#cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS
+/* enable x86 APX relax relocations by default */
+#cmakedefine01 ENABLE_X86_APX_RELAX_RELOCATIONS
+
/* Enable IEEE binary128 as default long double format on PowerPC Linux. */
#cmakedefine01 PPC_LINUX_DEFAULT_IEEELONGDOUBLE
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 919c1c643d080..a3becf76a7671 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7442,6 +7442,9 @@ def mmapsyms_implicit : Flag<["-"], "mmapsyms=implicit">,
def mrelax_relocations_no : Flag<["-"], "mrelax-relocations=no">,
HelpText<"Disable x86 relax relocations">,
MarshallingInfoNegativeFlag<CodeGenOpts<"X86RelaxRelocations">>;
+def mapx_relax_relocations_yes : Flag<["-"], "mapx-relax-relocations=yes">,
+ HelpText<"Enable x86 APX relax relocations">,
+ MarshallingInfoNegativeFlag<CodeGenOpts<"X86APXRelaxRelocations">>;
def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
HelpText<"Save temporary labels in the symbol table. "
"Note this may change .s semantics and shouldn't generally be used "
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index d0059673d6a67..ef90956e25de0 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -473,6 +473,9 @@ class ToolChain {
/// Check whether to enable x86 relax relocations by default.
virtual bool useRelaxRelocations() const;
+ /// Check whether to enable x86 APX relax relocations by default.
+ virtual bool useAPXRelaxRelocations() const;
+
/// Check whether use IEEE binary128 as long double format by default.
bool defaultToIEEELongDouble() const;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index f7eb853beb23c..72643631f39fc 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -513,6 +513,7 @@ static bool initTargetOptions(const CompilerInstance &CI,
Options.MCOptions.Crel = CodeGenOpts.Crel;
Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;
Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;
+ Options.MCOptions.X86APXRelaxRelocations = CodeGenOpts.X86APXRelaxRelocations;
Options.MCOptions.CompressDebugSections =
CodeGenOpts.getCompressDebugSections();
if (CodeGenOpts.OutputAsmVariant != 3) // 3 (default): not specified
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 5cd5755e01587..c7bf259a678bd 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -192,6 +192,10 @@ bool ToolChain::useRelaxRelocations() const {
return ENABLE_X86_RELAX_RELOCATIONS;
}
+bool ToolChain::useAPXRelaxRelocations() const {
+ return ENABLE_X86_APX_RELAX_RELOCATIONS;
+}
+
bool ToolChain::defaultToIEEELongDouble() const {
return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index f2f5231933c88..b1630dcca7306 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2602,6 +2602,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
bool Crel = false, ExperimentalCrel = false;
bool ImplicitMapSyms = false;
bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations();
+ bool UseAPXRelaxRelocations =
+ C.getDefaultToolChain().useAPXRelaxRelocations();
bool UseNoExecStack = false;
bool Msa = false;
const char *MipsTargetFeature = nullptr;
@@ -2663,6 +2665,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
checkArg(IsELF, {"yes", "no"});
continue;
}
+ if (Equal.first == "-mapx-relax-relocations" ||
+ Equal.first == "--mapx-relax-relocations") {
+ UseAPXRelaxRelocations = Equal.second == "yes";
+ checkArg(IsELF, {"yes", "no"});
+ continue;
+ }
if (Value == "-msse2avx") {
CmdArgs.push_back("-msse2avx");
continue;
@@ -2874,6 +2882,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back("-mmsa");
if (!UseRelaxRelocations)
CmdArgs.push_back("-mrelax-relocations=no");
+ if (UseAPXRelaxRelocations)
+ CmdArgs.push_back("-mapx-relax-relocations=yes");
if (UseNoExecStack)
CmdArgs.push_back("-mnoexecstack");
if (MipsTargetFeature != nullptr) {
diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s
index 7b084de7e6be2..d3b58509f57bb 100644
--- a/clang/test/Driver/relax.s
+++ b/clang/test/Driver/relax.s
@@ -4,11 +4,20 @@
// CHECK: "-cc1as"
// CHECK: "-mrelax-relocations=no"
+// RUN: %clang -### -c --target=x86_64-pc-linux -integrated-as -Wa,--mapx-relax-relocations=yes %s 2>&1 | FileCheck %s --check-prefix=APXREL_OPTION
+
+// APXREL_OPTION: "-cc1as"
+// APXREL_OPTION: "-mapx-relax-relocations=yes"
+
+// RUN: %clang -cc1as -triple x86_64-pc-linux %s -o %t -filetype obj -mapx-relax-relocations=yes
+// RUN: llvm-readobj -r %t | FileCheck --check-prefix=APXREL %s
// RUN: %clang -cc1as -triple x86_64-pc-linux %s -o %t -filetype obj
-// RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s
+// RUN: llvm-readobj -r %t | FileCheck --check-prefix=NOAPXREL %s
-// REL: R_X86_64_REX_GOTPCRELX foo
-// REL: R_X86_64_CODE_4_GOTPCRELX foo
+// APXREL: R_X86_64_REX_GOTPCRELX foo
+// APXREL: R_X86_64_CODE_4_GOTPCRELX foo
+// NOAPXREL: R_X86_64_REX_GOTPCRELX foo
+// NOAPXREL: R_X86_64_GOTPCREL foo
movq foo@GOTPCREL(%rip), %rax
movq foo@GOTPCREL(%rip), %r16
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index b98fc5ead100f..5654ea91f1349 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -171,6 +171,8 @@ struct AssemblerInvocation {
LLVM_PREFERRED_TYPE(bool)
unsigned X86RelaxRelocations : 1;
LLVM_PREFERRED_TYPE(bool)
+ unsigned X86APXRelaxRelocations : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned X86Sse2Avx : 1;
/// The name of the relocation model to use.
@@ -216,6 +218,7 @@ struct AssemblerInvocation {
Crel = false;
ImplicitMapsyms = 0;
X86RelaxRelocations = 0;
+ X86APXRelaxRelocations = 0;
X86Sse2Avx = 0;
}
@@ -388,6 +391,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Opts.Crel = Args.hasArg(OPT_crel);
Opts.ImplicitMapsyms = Args.hasArg(OPT_mmapsyms_implicit);
Opts.X86RelaxRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
+ Opts.X86APXRelaxRelocations = Args.hasArg(OPT_mapx_relax_relocations_yes);
Opts.X86Sse2Avx = Args.hasArg(OPT_msse2avx);
Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);
@@ -449,6 +453,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
MCOptions.Crel = Opts.Crel;
MCOptions.ImplicitMapSyms = Opts.ImplicitMapsyms;
MCOptions.X86RelaxRelocations = Opts.X86RelaxRelocations;
+ MCOptions.X86APXRelaxRelocations = Opts.X86APXRelaxRelocations;
MCOptions.X86Sse2Avx = Opts.X86Sse2Avx;
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 0c4fd00cab65c..28fdf4f0c8d80 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -912,9 +912,9 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_X86_64_CODE_4_GOTPC32_TLSDESC:
case R_X86_64_TLSDESC_CALL:
case R_X86_64_TLSGD:
- if (rel.expr == R_RELAX_TLS_GD_TO_LE) {
+ if (rel.expr == R_RELAX_TLS_GD_TO_LE && ctx.arg.relax) {
relaxTlsGdToLe(loc, rel, val);
- } else if (rel.expr == R_RELAX_TLS_GD_TO_IE) {
+ } else if (rel.expr == R_RELAX_TLS_GD_TO_IE && ctx.arg.relax) {
relaxTlsGdToIe(loc, rel, val);
} else {
checkInt(ctx, loc, val, 32, rel);
@@ -932,7 +932,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_X86_64_GOTTPOFF:
case R_X86_64_CODE_4_GOTTPOFF:
case R_X86_64_CODE_6_GOTTPOFF:
- if (rel.expr == R_RELAX_TLS_IE_TO_LE) {
+ if (rel.expr == R_RELAX_TLS_IE_TO_LE && ctx.arg.relax) {
relaxTlsIeToLe(loc, rel, val);
} else {
checkInt(ctx, loc, val, 32, rel);
diff --git a/lld/test/ELF/tls-opt.s b/lld/test/ELF/tls-opt.s
index 466dda0ef2e7b..cf8b46e088ddd 100644
--- a/lld/test/ELF/tls-opt.s
+++ b/lld/test/ELF/tls-opt.s
@@ -1,44 +1,84 @@
// REQUIRES: x86
-// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -x86-apx-relax-relocations=true
// RUN: ld.lld %t.o -o %t1
// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
-// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefix=DISASM %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefixes=DISASM,APXRELAX %s
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t1 --no-relax
+// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefixes=DISASM,NOAPXRELAX %s
// NORELOC: Relocations [
// NORELOC-NEXT: ]
// DISASM: <_start>:
-// DISASM-NEXT: movq $-8, %rax
-// DISASM-NEXT: movq $-8, %r15
-// DISASM-NEXT: leaq -8(%rax), %rax
-// DISASM-NEXT: leaq -8(%r15), %r15
-// DISASM-NEXT: addq $-8, %rsp
-// DISASM-NEXT: addq $-8, %r12
-// DISASM-NEXT: movq $-4, %rax
-// DISASM-NEXT: movq $-4, %r15
-// DISASM-NEXT: leaq -4(%rax), %rax
-// DISASM-NEXT: leaq -4(%r15), %r15
-// DISASM-NEXT: addq $-4, %rsp
-// DISASM-NEXT: addq $-4, %r12
+// APXRELAX-NEXT: movq $-8, %rax
+// APXRELAX-NEXT: movq $-8, %r15
+// APXRELAX-NEXT: leaq -8(%rax), %rax
+// APXRELAX-NEXT: leaq -8(%r15), %r15
+// APXRELAX-NEXT: addq $-8, %rsp
+// APXRELAX-NEXT: addq $-8, %r12
+// APXRELAX-NEXT: movq $-4, %rax
+// APXRELAX-NEXT: movq $-4, %r15
+// APXRELAX-NEXT: leaq -4(%rax), %rax
+// APXRELAX-NEXT: leaq -4(%r15), %r15
+// APXRELAX-NEXT: addq $-4, %rsp
+// APXRELAX-NEXT: addq $-4, %r12
+
+// NOAPXRELAX-NEXT: movq -12(%rip), %rax
+// NOAPXRELAX-NEXT: movq -12(%rip), %r15
+// NOAPXRELAX-NEXT: addq -12(%rip), %rax
+// NOAPXRELAX-NEXT: addq -12(%rip), %r15
+// NOAPXRELAX-NEXT: addq -12(%rip), %rsp
+// NOAPXRELAX-NEXT: addq -12(%rip), %r12
+// NOAPXRELAX-NEXT: movq -8(%rip), %rax
+// NOAPXRELAX-NEXT: movq -8(%rip), %r15
+// NOAPXRELAX-NEXT: addq -8(%rip), %rax
+// NOAPXRELAX-NEXT: addq -8(%rip), %r15
+// NOAPXRELAX-NEXT: addq -8(%rip), %rsp
+// NOAPXRELAX-NEXT: addq -8(%rip), %r12
+
# EGPR
-// DISASM-NEXT: movq $-8, %r16
-// DISASM-NEXT: movq $-8, %r20
-// DISASM-NEXT: movq $-4, %r16
-// DISASM-NEXT: addq $-8, %r16
-// DISASM-NEXT: addq $-8, %r28
-// DISASM-NEXT: addq $-4, %r16
+// APXRELAX-NEXT: movq $-8, %r16
+// APXRELAX-NEXT: movq $-8, %r20
+// APXRELAX-NEXT: movq $-4, %r16
+// APXRELAX-NEXT: addq $-8, %r16
+// APXRELAX-NEXT: addq $-8, %r28
+// APXRELAX-NEXT: addq $-4, %r16
+
+// NOAPXRELAX-NEXT: movq -12(%rip), %r16
+// NOAPXRELAX-NEXT: movq -12(%rip), %r20
+// NOAPXRELAX-NEXT: movq -8(%rip), %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %r28
+// NOAPXRELAX-NEXT: addq -8(%rip), %r16
+
# NDD
-// DISASM-NEXT: addq $-8, %r16, %r16
-// DISASM-NEXT: addq $-8, %r16, %r20
-// DISASM-NEXT: addq $-8, %r16, %rax
-// DISASM-NEXT: addq $-8, %rax, %r16
-// DISASM-NEXT: addq $-8, %r8, %r16
-// DISASM-NEXT: addq $-8, %rax, %r12
+// APXRELAX-NEXT: addq $-8, %r16, %r16
+// APXRELAX-NEXT: addq $-8, %r16, %r20
+// APXRELAX-NEXT: addq $-8, %r16, %rax
+// APXRELAX-NEXT: addq $-8, %rax, %r16
+// APXRELAX-NEXT: addq $-8, %r8, %r16
+// APXRELAX-NEXT: addq $-8, %rax, %r12
+
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16, %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16, %r20
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16, %rax
+// NOAPXRELAX-NEXT: addq -12(%rip), %rax, %r16
+// NOAPXRELAX-NEXT: addq %r8, -12(%rip), %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %rax, %r12
+
# NDD + NF
-// DISASM-NEXT: {nf} addq $-8, %r8, %r16
-// DISASM-NEXT: {nf} addq $-8, %rax, %r12
+// APXRELAX-NEXT: {nf} addq $-8, %r8, %r16
+// APXRELAX-NEXT: {nf} addq $-8, %rax, %r12
+
+// NOAPXRELAX-NEXT: {nf} addq %r8, -12(%rip), %r16
+// NOAPXRELAX-NEXT: {nf} addq -12(%rip), %rax, %r12
+
# NF
-// DISASM-NEXT: {nf} addq $-8, %r12
+// APXRELAX-NEXT: {nf} addq $-8, %r12
+// NOAPXRELAX-NEXT: {nf} addq -12(%rip), %r12
// LD to LE:
// DISASM-NEXT: movq %fs:0, %rax
@@ -47,10 +87,15 @@
// DISASM-NEXT: leaq -4(%rax), %rcx
// GD to LE:
-// DISASM-NEXT: movq %fs:0, %rax
-// DISASM-NEXT: leaq -8(%rax), %rax
-// DISASM-NEXT: movq %fs:0, %rax
-// DISASM-NEXT: leaq -4(%rax), %rax
+// APXRELAX-NEXT: movq %fs:0, %rax
+// APXRELAX-NEXT: leaq -8(%rax), %rax
+// APXRELAX-NEXT: movq %fs:0, %rax
+// APXRELAX-NEXT: leaq -4(%rax), %rax
+
+// NOAPXRELAX-NEXT: leaq -12(%rip), %rdi
+// NOAPXRELAX-NEXT: callq 0x20126c
+// NOAPXRELAX-NEXT: leaq -8(%rip), %rdi
+// NOAPXRELAX-NEXT: callq 0x20127c
// LD to LE:
// DISASM: <_DTPOFF64_1>:
diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
index 8452090e2c35a..c2628404a5516 100644
--- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s
+++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
@@ -1,7 +1,10 @@
# REQUIRES: x86
# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o -x86-apx-relax-relocations=true
+# RUN: not ld.lld --no-relax -T %t/lds %t/a.o -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: --check-prefixes=CHECK,APXRELAX
+
# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o
-# RUN: not ld.lld --no-relax -T %t/lds %t/a.o -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
+# RUN: not ld.lld --no-relax -T %t/lds %t/a.o -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: --check-prefixes=CHECK,NOAPXRELAX
## Test diagnostics for unrelaxed GOTPCRELX overflows. In addition, test that there is no
## `>>> defined in` for linker synthesized __stop_* symbols (there is no
@@ -13,9 +16,11 @@
# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: >>> defined in <internal>
# CHECK-EMPTY:
-# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_CODE_4_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
+# APXRELAX-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_CODE_4_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
+# NOAPXRELAX-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_GOTPCREL out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: >>> defined in <internal>
+
#--- a.s
movl __stop_data@GOTPCREL(%rip), %eax # out of range
movq __stop_data@GOTPCREL(%rip), %rax # out of range
diff --git a/lld/test/ELF/x86-64-gotpc-relax-nopic.s b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
index be55c7d7006fe..67a155bfe0d76 100644
--- a/lld/test/ELF/x86-64-gotpc-relax-nopic.s
+++ b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
@@ -1,8 +1,13 @@
# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -x86-apx-relax-relocations=true
+# RUN: ld.lld %t.o -o %t1
+# RUN: llvm-readobj --symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
+# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t1 | FileCheck --check-prefixes=DISASM,APXRELAX %s
+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
# RUN: ld.lld %t.o -o %t1
# RUN: llvm-readobj --symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
-# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t1 | FileCheck --check-prefix=DISASM %s
+# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t1 | FileCheck --check-prefixes=DISASM,NOAPXRELAX %s
## There is no relocations.
# SYMRELOC: Relocations [
@@ -34,15 +39,25 @@
# DISASM-NEXT: subq $0x203290, %rbp
# DISASM-NEXT: xorq $0x203290, %r8
# DISASM-NEXT: testq $0x203290, %r15
-# DISASM-NEXT: 20123f: adcq $0x203290, %r16
-# DISASM-NEXT: addq $0x203290, %r17
-# DISASM-NEXT: andq $0x203290, %r18
-# DISASM-NEXT: cmpq $0x203290, %r19
-# DISASM-NEXT: orq $0x203290, %r20
-# DISASM-NEXT: sbbq $0x203290, %r21
-# DISASM-NEXT: subq $0x203290, %r22
-# DISASM-NEXT: xorq $0x203290, %r23
-# DISASM-NEXT: testq $0x203290, %r24
+# APXRELAX-NEXT: 20123f: adcq $0x203290, %r16
+# APXRELAX-NEXT: addq $0x203290, %r17
+# APXRELAX-NEXT: andq $0x203290, %r18
+# APXRELAX-NEXT: cmpq $0x203290, %r19
+# APXRELAX-NEXT: orq $0x203290, %r20
+# APXRELAX-NEXT: sbbq $0x203290, %r21
+# APXRELAX-NEXT: subq $0x203290, %r22
+# APXRELAX-NEXT: xorq $0x203290, %r23
+# APXRELAX-NEXT: testq $0x203290, %r24
+
+# NOAPXRELAX-NEXT: 20123f: adcq 0x1041(%rip), %r16
+# N...
[truncated]
|
@llvm/pr-subscribers-lld Author: Feng Zou (fzou1) ChangesIntroduce an option (-mapx-relax-relocations) to control the emission of the new APX relocations. It's off by default to keep backward compatibility with old version of ld and other linkers without APX support. And EGPR and NDD are also suppressed to avoid the instructions updated incorrectly by old version of linkers. Patch is 57.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136660.diff 37 Files Affected:
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
index c3f30e2a8e9c0..fa3063d6be9a7 100644
--- a/clang/CMakeLists.txt
+++ b/clang/CMakeLists.txt
@@ -219,6 +219,9 @@ set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld")
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL
"enable x86 relax relocations by default")
+set(ENABLE_X86_APX_RELAX_RELOCATIONS OFF CACHE BOOL
+ "Enable x86 APX relax relocations by default")
+
set(PPC_LINUX_DEFAULT_IEEELONGDOUBLE OFF CACHE BOOL
"Enable IEEE binary128 as default long double format on PowerPC Linux.")
diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake
index 99890b8246ad7..22eef24b611a8 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -49,6 +49,7 @@ set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
+set(ENABLE_X86_APX_RELAX_RELOCATIONS OFF CACHE BOOL "")
# TODO(#67176): relative-vtables doesn't play well with different default
# visibilities. Making everything hidden visibility causes other complications
diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake
index 83336589da305..550d94d1ec6a5 100644
--- a/clang/cmake/caches/Fuchsia.cmake
+++ b/clang/cmake/caches/Fuchsia.cmake
@@ -89,6 +89,7 @@ set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
+set(ENABLE_X86_APX_RELAX_RELOCATIONS OFF CACHE BOOL "")
set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "")
set(LLVM_ENABLE_BACKTRACES ON CACHE BOOL "")
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index c5990fb248689..875facd6cfc63 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -201,6 +201,7 @@ CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get u
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
CODEGENOPT(PPCUseFullRegisterNames, 1, 0) ///< Print full register names in assembly
CODEGENOPT(X86RelaxRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
+CODEGENOPT(X86APXRelaxRelocations, 1, 0) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(X86Sse2Avx , 1, 0) ///< -Wa,-msse2avx
/// When false, this attempts to generate code as if the result of an
diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake
index 00c352b458c34..db7fc2ba45eaf 100644
--- a/clang/include/clang/Config/config.h.cmake
+++ b/clang/include/clang/Config/config.h.cmake
@@ -72,6 +72,9 @@
/* enable x86 relax relocations by default */
#cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS
+/* enable x86 APX relax relocations by default */
+#cmakedefine01 ENABLE_X86_APX_RELAX_RELOCATIONS
+
/* Enable IEEE binary128 as default long double format on PowerPC Linux. */
#cmakedefine01 PPC_LINUX_DEFAULT_IEEELONGDOUBLE
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 919c1c643d080..a3becf76a7671 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7442,6 +7442,9 @@ def mmapsyms_implicit : Flag<["-"], "mmapsyms=implicit">,
def mrelax_relocations_no : Flag<["-"], "mrelax-relocations=no">,
HelpText<"Disable x86 relax relocations">,
MarshallingInfoNegativeFlag<CodeGenOpts<"X86RelaxRelocations">>;
+def mapx_relax_relocations_yes : Flag<["-"], "mapx-relax-relocations=yes">,
+ HelpText<"Enable x86 APX relax relocations">,
+ MarshallingInfoNegativeFlag<CodeGenOpts<"X86APXRelaxRelocations">>;
def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
HelpText<"Save temporary labels in the symbol table. "
"Note this may change .s semantics and shouldn't generally be used "
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index d0059673d6a67..ef90956e25de0 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -473,6 +473,9 @@ class ToolChain {
/// Check whether to enable x86 relax relocations by default.
virtual bool useRelaxRelocations() const;
+ /// Check whether to enable x86 APX relax relocations by default.
+ virtual bool useAPXRelaxRelocations() const;
+
/// Check whether use IEEE binary128 as long double format by default.
bool defaultToIEEELongDouble() const;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index f7eb853beb23c..72643631f39fc 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -513,6 +513,7 @@ static bool initTargetOptions(const CompilerInstance &CI,
Options.MCOptions.Crel = CodeGenOpts.Crel;
Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;
Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;
+ Options.MCOptions.X86APXRelaxRelocations = CodeGenOpts.X86APXRelaxRelocations;
Options.MCOptions.CompressDebugSections =
CodeGenOpts.getCompressDebugSections();
if (CodeGenOpts.OutputAsmVariant != 3) // 3 (default): not specified
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 5cd5755e01587..c7bf259a678bd 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -192,6 +192,10 @@ bool ToolChain::useRelaxRelocations() const {
return ENABLE_X86_RELAX_RELOCATIONS;
}
+bool ToolChain::useAPXRelaxRelocations() const {
+ return ENABLE_X86_APX_RELAX_RELOCATIONS;
+}
+
bool ToolChain::defaultToIEEELongDouble() const {
return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index f2f5231933c88..b1630dcca7306 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2602,6 +2602,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
bool Crel = false, ExperimentalCrel = false;
bool ImplicitMapSyms = false;
bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations();
+ bool UseAPXRelaxRelocations =
+ C.getDefaultToolChain().useAPXRelaxRelocations();
bool UseNoExecStack = false;
bool Msa = false;
const char *MipsTargetFeature = nullptr;
@@ -2663,6 +2665,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
checkArg(IsELF, {"yes", "no"});
continue;
}
+ if (Equal.first == "-mapx-relax-relocations" ||
+ Equal.first == "--mapx-relax-relocations") {
+ UseAPXRelaxRelocations = Equal.second == "yes";
+ checkArg(IsELF, {"yes", "no"});
+ continue;
+ }
if (Value == "-msse2avx") {
CmdArgs.push_back("-msse2avx");
continue;
@@ -2874,6 +2882,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back("-mmsa");
if (!UseRelaxRelocations)
CmdArgs.push_back("-mrelax-relocations=no");
+ if (UseAPXRelaxRelocations)
+ CmdArgs.push_back("-mapx-relax-relocations=yes");
if (UseNoExecStack)
CmdArgs.push_back("-mnoexecstack");
if (MipsTargetFeature != nullptr) {
diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s
index 7b084de7e6be2..d3b58509f57bb 100644
--- a/clang/test/Driver/relax.s
+++ b/clang/test/Driver/relax.s
@@ -4,11 +4,20 @@
// CHECK: "-cc1as"
// CHECK: "-mrelax-relocations=no"
+// RUN: %clang -### -c --target=x86_64-pc-linux -integrated-as -Wa,--mapx-relax-relocations=yes %s 2>&1 | FileCheck %s --check-prefix=APXREL_OPTION
+
+// APXREL_OPTION: "-cc1as"
+// APXREL_OPTION: "-mapx-relax-relocations=yes"
+
+// RUN: %clang -cc1as -triple x86_64-pc-linux %s -o %t -filetype obj -mapx-relax-relocations=yes
+// RUN: llvm-readobj -r %t | FileCheck --check-prefix=APXREL %s
// RUN: %clang -cc1as -triple x86_64-pc-linux %s -o %t -filetype obj
-// RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s
+// RUN: llvm-readobj -r %t | FileCheck --check-prefix=NOAPXREL %s
-// REL: R_X86_64_REX_GOTPCRELX foo
-// REL: R_X86_64_CODE_4_GOTPCRELX foo
+// APXREL: R_X86_64_REX_GOTPCRELX foo
+// APXREL: R_X86_64_CODE_4_GOTPCRELX foo
+// NOAPXREL: R_X86_64_REX_GOTPCRELX foo
+// NOAPXREL: R_X86_64_GOTPCREL foo
movq foo@GOTPCREL(%rip), %rax
movq foo@GOTPCREL(%rip), %r16
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index b98fc5ead100f..5654ea91f1349 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -171,6 +171,8 @@ struct AssemblerInvocation {
LLVM_PREFERRED_TYPE(bool)
unsigned X86RelaxRelocations : 1;
LLVM_PREFERRED_TYPE(bool)
+ unsigned X86APXRelaxRelocations : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned X86Sse2Avx : 1;
/// The name of the relocation model to use.
@@ -216,6 +218,7 @@ struct AssemblerInvocation {
Crel = false;
ImplicitMapsyms = 0;
X86RelaxRelocations = 0;
+ X86APXRelaxRelocations = 0;
X86Sse2Avx = 0;
}
@@ -388,6 +391,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Opts.Crel = Args.hasArg(OPT_crel);
Opts.ImplicitMapsyms = Args.hasArg(OPT_mmapsyms_implicit);
Opts.X86RelaxRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
+ Opts.X86APXRelaxRelocations = Args.hasArg(OPT_mapx_relax_relocations_yes);
Opts.X86Sse2Avx = Args.hasArg(OPT_msse2avx);
Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);
@@ -449,6 +453,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
MCOptions.Crel = Opts.Crel;
MCOptions.ImplicitMapSyms = Opts.ImplicitMapsyms;
MCOptions.X86RelaxRelocations = Opts.X86RelaxRelocations;
+ MCOptions.X86APXRelaxRelocations = Opts.X86APXRelaxRelocations;
MCOptions.X86Sse2Avx = Opts.X86Sse2Avx;
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 0c4fd00cab65c..28fdf4f0c8d80 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -912,9 +912,9 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_X86_64_CODE_4_GOTPC32_TLSDESC:
case R_X86_64_TLSDESC_CALL:
case R_X86_64_TLSGD:
- if (rel.expr == R_RELAX_TLS_GD_TO_LE) {
+ if (rel.expr == R_RELAX_TLS_GD_TO_LE && ctx.arg.relax) {
relaxTlsGdToLe(loc, rel, val);
- } else if (rel.expr == R_RELAX_TLS_GD_TO_IE) {
+ } else if (rel.expr == R_RELAX_TLS_GD_TO_IE && ctx.arg.relax) {
relaxTlsGdToIe(loc, rel, val);
} else {
checkInt(ctx, loc, val, 32, rel);
@@ -932,7 +932,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_X86_64_GOTTPOFF:
case R_X86_64_CODE_4_GOTTPOFF:
case R_X86_64_CODE_6_GOTTPOFF:
- if (rel.expr == R_RELAX_TLS_IE_TO_LE) {
+ if (rel.expr == R_RELAX_TLS_IE_TO_LE && ctx.arg.relax) {
relaxTlsIeToLe(loc, rel, val);
} else {
checkInt(ctx, loc, val, 32, rel);
diff --git a/lld/test/ELF/tls-opt.s b/lld/test/ELF/tls-opt.s
index 466dda0ef2e7b..cf8b46e088ddd 100644
--- a/lld/test/ELF/tls-opt.s
+++ b/lld/test/ELF/tls-opt.s
@@ -1,44 +1,84 @@
// REQUIRES: x86
-// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -x86-apx-relax-relocations=true
// RUN: ld.lld %t.o -o %t1
// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
-// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefix=DISASM %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefixes=DISASM,APXRELAX %s
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t1 --no-relax
+// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefixes=DISASM,NOAPXRELAX %s
// NORELOC: Relocations [
// NORELOC-NEXT: ]
// DISASM: <_start>:
-// DISASM-NEXT: movq $-8, %rax
-// DISASM-NEXT: movq $-8, %r15
-// DISASM-NEXT: leaq -8(%rax), %rax
-// DISASM-NEXT: leaq -8(%r15), %r15
-// DISASM-NEXT: addq $-8, %rsp
-// DISASM-NEXT: addq $-8, %r12
-// DISASM-NEXT: movq $-4, %rax
-// DISASM-NEXT: movq $-4, %r15
-// DISASM-NEXT: leaq -4(%rax), %rax
-// DISASM-NEXT: leaq -4(%r15), %r15
-// DISASM-NEXT: addq $-4, %rsp
-// DISASM-NEXT: addq $-4, %r12
+// APXRELAX-NEXT: movq $-8, %rax
+// APXRELAX-NEXT: movq $-8, %r15
+// APXRELAX-NEXT: leaq -8(%rax), %rax
+// APXRELAX-NEXT: leaq -8(%r15), %r15
+// APXRELAX-NEXT: addq $-8, %rsp
+// APXRELAX-NEXT: addq $-8, %r12
+// APXRELAX-NEXT: movq $-4, %rax
+// APXRELAX-NEXT: movq $-4, %r15
+// APXRELAX-NEXT: leaq -4(%rax), %rax
+// APXRELAX-NEXT: leaq -4(%r15), %r15
+// APXRELAX-NEXT: addq $-4, %rsp
+// APXRELAX-NEXT: addq $-4, %r12
+
+// NOAPXRELAX-NEXT: movq -12(%rip), %rax
+// NOAPXRELAX-NEXT: movq -12(%rip), %r15
+// NOAPXRELAX-NEXT: addq -12(%rip), %rax
+// NOAPXRELAX-NEXT: addq -12(%rip), %r15
+// NOAPXRELAX-NEXT: addq -12(%rip), %rsp
+// NOAPXRELAX-NEXT: addq -12(%rip), %r12
+// NOAPXRELAX-NEXT: movq -8(%rip), %rax
+// NOAPXRELAX-NEXT: movq -8(%rip), %r15
+// NOAPXRELAX-NEXT: addq -8(%rip), %rax
+// NOAPXRELAX-NEXT: addq -8(%rip), %r15
+// NOAPXRELAX-NEXT: addq -8(%rip), %rsp
+// NOAPXRELAX-NEXT: addq -8(%rip), %r12
+
# EGPR
-// DISASM-NEXT: movq $-8, %r16
-// DISASM-NEXT: movq $-8, %r20
-// DISASM-NEXT: movq $-4, %r16
-// DISASM-NEXT: addq $-8, %r16
-// DISASM-NEXT: addq $-8, %r28
-// DISASM-NEXT: addq $-4, %r16
+// APXRELAX-NEXT: movq $-8, %r16
+// APXRELAX-NEXT: movq $-8, %r20
+// APXRELAX-NEXT: movq $-4, %r16
+// APXRELAX-NEXT: addq $-8, %r16
+// APXRELAX-NEXT: addq $-8, %r28
+// APXRELAX-NEXT: addq $-4, %r16
+
+// NOAPXRELAX-NEXT: movq -12(%rip), %r16
+// NOAPXRELAX-NEXT: movq -12(%rip), %r20
+// NOAPXRELAX-NEXT: movq -8(%rip), %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %r28
+// NOAPXRELAX-NEXT: addq -8(%rip), %r16
+
# NDD
-// DISASM-NEXT: addq $-8, %r16, %r16
-// DISASM-NEXT: addq $-8, %r16, %r20
-// DISASM-NEXT: addq $-8, %r16, %rax
-// DISASM-NEXT: addq $-8, %rax, %r16
-// DISASM-NEXT: addq $-8, %r8, %r16
-// DISASM-NEXT: addq $-8, %rax, %r12
+// APXRELAX-NEXT: addq $-8, %r16, %r16
+// APXRELAX-NEXT: addq $-8, %r16, %r20
+// APXRELAX-NEXT: addq $-8, %r16, %rax
+// APXRELAX-NEXT: addq $-8, %rax, %r16
+// APXRELAX-NEXT: addq $-8, %r8, %r16
+// APXRELAX-NEXT: addq $-8, %rax, %r12
+
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16, %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16, %r20
+// NOAPXRELAX-NEXT: addq -12(%rip), %r16, %rax
+// NOAPXRELAX-NEXT: addq -12(%rip), %rax, %r16
+// NOAPXRELAX-NEXT: addq %r8, -12(%rip), %r16
+// NOAPXRELAX-NEXT: addq -12(%rip), %rax, %r12
+
# NDD + NF
-// DISASM-NEXT: {nf} addq $-8, %r8, %r16
-// DISASM-NEXT: {nf} addq $-8, %rax, %r12
+// APXRELAX-NEXT: {nf} addq $-8, %r8, %r16
+// APXRELAX-NEXT: {nf} addq $-8, %rax, %r12
+
+// NOAPXRELAX-NEXT: {nf} addq %r8, -12(%rip), %r16
+// NOAPXRELAX-NEXT: {nf} addq -12(%rip), %rax, %r12
+
# NF
-// DISASM-NEXT: {nf} addq $-8, %r12
+// APXRELAX-NEXT: {nf} addq $-8, %r12
+// NOAPXRELAX-NEXT: {nf} addq -12(%rip), %r12
// LD to LE:
// DISASM-NEXT: movq %fs:0, %rax
@@ -47,10 +87,15 @@
// DISASM-NEXT: leaq -4(%rax), %rcx
// GD to LE:
-// DISASM-NEXT: movq %fs:0, %rax
-// DISASM-NEXT: leaq -8(%rax), %rax
-// DISASM-NEXT: movq %fs:0, %rax
-// DISASM-NEXT: leaq -4(%rax), %rax
+// APXRELAX-NEXT: movq %fs:0, %rax
+// APXRELAX-NEXT: leaq -8(%rax), %rax
+// APXRELAX-NEXT: movq %fs:0, %rax
+// APXRELAX-NEXT: leaq -4(%rax), %rax
+
+// NOAPXRELAX-NEXT: leaq -12(%rip), %rdi
+// NOAPXRELAX-NEXT: callq 0x20126c
+// NOAPXRELAX-NEXT: leaq -8(%rip), %rdi
+// NOAPXRELAX-NEXT: callq 0x20127c
// LD to LE:
// DISASM: <_DTPOFF64_1>:
diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
index 8452090e2c35a..c2628404a5516 100644
--- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s
+++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
@@ -1,7 +1,10 @@
# REQUIRES: x86
# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o -x86-apx-relax-relocations=true
+# RUN: not ld.lld --no-relax -T %t/lds %t/a.o -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: --check-prefixes=CHECK,APXRELAX
+
# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o
-# RUN: not ld.lld --no-relax -T %t/lds %t/a.o -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
+# RUN: not ld.lld --no-relax -T %t/lds %t/a.o -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: --check-prefixes=CHECK,NOAPXRELAX
## Test diagnostics for unrelaxed GOTPCRELX overflows. In addition, test that there is no
## `>>> defined in` for linker synthesized __stop_* symbols (there is no
@@ -13,9 +16,11 @@
# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: >>> defined in <internal>
# CHECK-EMPTY:
-# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_CODE_4_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
+# APXRELAX-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_CODE_4_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
+# NOAPXRELAX-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_GOTPCREL out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: >>> defined in <internal>
+
#--- a.s
movl __stop_data@GOTPCREL(%rip), %eax # out of range
movq __stop_data@GOTPCREL(%rip), %rax # out of range
diff --git a/lld/test/ELF/x86-64-gotpc-relax-nopic.s b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
index be55c7d7006fe..67a155bfe0d76 100644
--- a/lld/test/ELF/x86-64-gotpc-relax-nopic.s
+++ b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
@@ -1,8 +1,13 @@
# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -x86-apx-relax-relocations=true
+# RUN: ld.lld %t.o -o %t1
+# RUN: llvm-readobj --symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
+# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t1 | FileCheck --check-prefixes=DISASM,APXRELAX %s
+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
# RUN: ld.lld %t.o -o %t1
# RUN: llvm-readobj --symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
-# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t1 | FileCheck --check-prefix=DISASM %s
+# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t1 | FileCheck --check-prefixes=DISASM,NOAPXRELAX %s
## There is no relocations.
# SYMRELOC: Relocations [
@@ -34,15 +39,25 @@
# DISASM-NEXT: subq $0x203290, %rbp
# DISASM-NEXT: xorq $0x203290, %r8
# DISASM-NEXT: testq $0x203290, %r15
-# DISASM-NEXT: 20123f: adcq $0x203290, %r16
-# DISASM-NEXT: addq $0x203290, %r17
-# DISASM-NEXT: andq $0x203290, %r18
-# DISASM-NEXT: cmpq $0x203290, %r19
-# DISASM-NEXT: orq $0x203290, %r20
-# DISASM-NEXT: sbbq $0x203290, %r21
-# DISASM-NEXT: subq $0x203290, %r22
-# DISASM-NEXT: xorq $0x203290, %r23
-# DISASM-NEXT: testq $0x203290, %r24
+# APXRELAX-NEXT: 20123f: adcq $0x203290, %r16
+# APXRELAX-NEXT: addq $0x203290, %r17
+# APXRELAX-NEXT: andq $0x203290, %r18
+# APXRELAX-NEXT: cmpq $0x203290, %r19
+# APXRELAX-NEXT: orq $0x203290, %r20
+# APXRELAX-NEXT: sbbq $0x203290, %r21
+# APXRELAX-NEXT: subq $0x203290, %r22
+# APXRELAX-NEXT: xorq $0x203290, %r23
+# APXRELAX-NEXT: testq $0x203290, %r24
+
+# NOAPXRELAX-NEXT: 20123f: adcq 0x1041(%rip), %r16
+# N...
[truncated]
|
Not understand this. IIUC, either we should not emit APX instructions at all, which is controlled by |
If the APX relocation types are emitted in MC, they cannot be recognized by old version of linkers. It leads to APX features unavailable on existing Linux OSes with old version of linkers. |
Rename the pass of suppressing APX features for relocation.
But if you just old relocations for APX instructions and |
No, the old linker will do wrong thing. Here we added a pass to suppress EGPR and NDD/NF instructions for that. |
Any comments? |
lld/test/ELF/tls-opt.s
Outdated
// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefixes=DISASM,APXRELAX %s | ||
|
||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
// RUN: ld.lld %t.o -o %t1 --no-relax |
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.
Why do we need to check no-relax?
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.
There are instructions with APX EGPR or NDD/NF instructions in the test, and the R_X86_64_GOTTPOFF relocation is emitted. so we add this to suppress link relaxation for TLS relocation in LLD linker. I wonder if we need to emit warning or error in MC for this case (if users write such assembly code).
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.
But we didn't suppress link relaxation for non APX instruciton before, right?
lld/ELF/Arch/X86_64.cpp
Outdated
@@ -912,9 +912,9 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { | |||
case R_X86_64_CODE_4_GOTPC32_TLSDESC: | |||
case R_X86_64_TLSDESC_CALL: | |||
case R_X86_64_TLSGD: | |||
if (rel.expr == R_RELAX_TLS_GD_TO_LE) { | |||
if (rel.expr == R_RELAX_TLS_GD_TO_LE && ctx.arg.relax) { |
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.
I'm not sure we need to change it. I assume the problem happens only when using old lld with new compiler. There's nothing to do with the new lld here.
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.
This makes the tests or user programs having APX EGPR/NDD/NF pass with "-no-relax" option.
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.
Do we need to handle this case? The new lld has the ability to hanlde APX relocations. lld still does the ralax with "-no-relax" for the reset 3 relocations before the APX changes, isn't it?
llvm/lib/Target/X86/CMakeLists.txt
Outdated
@@ -89,6 +89,7 @@ set(sources | |||
GISel/X86InstructionSelector.cpp | |||
GISel/X86LegalizerInfo.cpp | |||
GISel/X86RegisterBankInfo.cpp | |||
X86SuppressAPXForReloc.cpp |
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.
Put it in alphabetic order?
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.
Will do
X86EnableAPXForRelocation) | ||
return false; | ||
const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>(); | ||
if (!ST.hasEGPR() && !ST.hasNDD() && !ST.hasNF()) |
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.
Why checking hasNF
?
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.
There are NF instructions for GOT_6_GOTTPOFF.
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.
I think only ADD64rm_NF_ND use GOT_6_GOTTPOFF. ADD64rm_NF uses REX2 encoding and should no problem if not using EGPR?
lld/ELF/Arch/X86_64.cpp
Outdated
@@ -912,9 +912,9 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { | |||
case R_X86_64_CODE_4_GOTPC32_TLSDESC: | |||
case R_X86_64_TLSDESC_CALL: | |||
case R_X86_64_TLSGD: | |||
if (rel.expr == R_RELAX_TLS_GD_TO_LE) { | |||
if (rel.expr == R_RELAX_TLS_GD_TO_LE && ctx.arg.relax) { |
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.
Use --no-relax to suppress TLS relaxation as well as GOTPCREL optimization.
lld/ELF/Arch/X86_64.cpp
Outdated
@@ -912,9 +912,9 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { | |||
case R_X86_64_CODE_4_GOTPC32_TLSDESC: | |||
case R_X86_64_TLSDESC_CALL: | |||
case R_X86_64_TLSGD: | |||
if (rel.expr == R_RELAX_TLS_GD_TO_LE) { | |||
if (rel.expr == R_RELAX_TLS_GD_TO_LE && ctx.arg.relax) { |
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.
This makes the tests or user programs having APX EGPR/NDD/NF pass with "-no-relax" option.
lld/test/ELF/tls-opt.s
Outdated
// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefixes=DISASM,APXRELAX %s | ||
|
||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
// RUN: ld.lld %t.o -o %t1 --no-relax |
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.
There are instructions with APX EGPR or NDD/NF instructions in the test, and the R_X86_64_GOTTPOFF relocation is emitted. so we add this to suppress link relaxation for TLS relocation in LLD linker. I wonder if we need to emit warning or error in MC for this case (if users write such assembly code).
case X86::SBB64rm: | ||
case X86::SUB64rm: | ||
case X86::XOR64rm: { | ||
for (auto &MO : MI.operands()) { |
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.
We can find the operand with X86::AddrDisp
directly.
case X86::ADD64rm_ND: | ||
case X86::ADD64rm_NF_ND: { |
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.
I think it's better to split the EGPR and NDD handling. We don't need to go through a lot of code if EGPR is not enabled.
Still not understand the requirement... |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/16860 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/155/builds/8781 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/95/builds/12600 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/56/builds/24594 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/108/builds/12234 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/9322 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/76/builds/9147 Here is the relevant piece of the build log for the reference
|
The test introduced in #136660, may be failed as ld.lld command not found.
Sorry. The test failure had been fixed in #137794. |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/125/builds/7219 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/64/builds/3275 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/39/builds/5888 Here is the relevant piece of the build log for the reference
|
We should avoid introducing a new cmake config for changes like this. You could utilize clang config file to specify the option. lld change should have been separated |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/146/builds/2810 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/42/builds/4349 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/98/builds/1349 Here is the relevant piece of the build log for the reference
|
Suppress EGPR/NDD instructions for relocations to avoid APX relocation types emitted. This is to keep backward compatibility with old version of linkers without APX support. The use case is to try APX features with LLVM + old built-in linker on RHEL9 OS which is expected to be EOL in 2032. If there are APX relocation types, the old version of linkers would raise "unsupported relocation type" error. Example: ``` $ llvm-mc -filetype=obj -o got.o -triple=x86_64-unknown-linux got.s $ ld got.o -o got.exe ld: got.o: unsupported relocation type 0x2b ... $ cat got.s ... movq foo@GOTPCREL(%rip), %r16 $ llvm-objdump -dr got.o ... 1: d5 48 8b 05 00 00 00 00 movq (%rip), %r16 0000000000000005: R_X86_64_CODE_4_GOTPCRELX foo-0x4 ```
The test introduced in llvm#136660, may be failed as ld.lld command not found.
Suppress EGPR/NDD instructions for relocations to avoid APX relocation types emitted. This is to keep backward compatibility with old version of linkers without APX support. The use case is to try APX features with LLVM + old built-in linker on RHEL9 OS which is expected to be EOL in 2032. If there are APX relocation types, the old version of linkers would raise "unsupported relocation type" error. Example: ``` $ llvm-mc -filetype=obj -o got.o -triple=x86_64-unknown-linux got.s $ ld got.o -o got.exe ld: got.o: unsupported relocation type 0x2b ... $ cat got.s ... movq foo@GOTPCREL(%rip), %r16 $ llvm-objdump -dr got.o ... 1: d5 48 8b 05 00 00 00 00 movq (%rip), %r16 0000000000000005: R_X86_64_CODE_4_GOTPCRELX foo-0x4 ```
The test introduced in llvm#136660, may be failed as ld.lld command not found.
Suppress EGPR/NDD instructions for relocations to avoid APX relocation types emitted. This is to keep backward compatibility with old version of linkers without APX support. The use case is to try APX features with LLVM + old built-in linker on RHEL9 OS which is expected to be EOL in 2032. If there are APX relocation types, the old version of linkers would raise "unsupported relocation type" error. Example: ``` $ llvm-mc -filetype=obj -o got.o -triple=x86_64-unknown-linux got.s $ ld got.o -o got.exe ld: got.o: unsupported relocation type 0x2b ... $ cat got.s ... movq foo@GOTPCREL(%rip), %r16 $ llvm-objdump -dr got.o ... 1: d5 48 8b 05 00 00 00 00 movq (%rip), %r16 0000000000000005: R_X86_64_CODE_4_GOTPCRELX foo-0x4 ```
The test introduced in llvm#136660, may be failed as ld.lld command not found.
Suppress EGPR/NDD instructions for relocations to avoid APX relocation types emitted. This is to keep backward compatibility with old version of linkers without APX support. The use case is to try APX features with LLVM + old built-in linker on RHEL9 OS which is expected to be EOL in 2032. If there are APX relocation types, the old version of linkers would raise "unsupported relocation type" error. Example: ``` $ llvm-mc -filetype=obj -o got.o -triple=x86_64-unknown-linux got.s $ ld got.o -o got.exe ld: got.o: unsupported relocation type 0x2b ... $ cat got.s ... movq foo@GOTPCREL(%rip), %r16 $ llvm-objdump -dr got.o ... 1: d5 48 8b 05 00 00 00 00 movq (%rip), %r16 0000000000000005: R_X86_64_CODE_4_GOTPCRELX foo-0x4 ```
The test introduced in llvm#136660, may be failed as ld.lld command not found.
Suppress EGPR/NDD instructions for relocations to avoid APX relocation types emitted. This is to keep backward compatibility with old version of linkers without APX support. The use case is to try APX features with LLVM + old built-in linker on RHEL9 OS which is expected to be EOL in 2032. If there are APX relocation types, the old version of linkers would raise "unsupported relocation type" error. Example: ``` $ llvm-mc -filetype=obj -o got.o -triple=x86_64-unknown-linux got.s $ ld got.o -o got.exe ld: got.o: unsupported relocation type 0x2b ... $ cat got.s ... movq foo@GOTPCREL(%rip), %r16 $ llvm-objdump -dr got.o ... 1: d5 48 8b 05 00 00 00 00 movq (%rip), %r16 0000000000000005: R_X86_64_CODE_4_GOTPCRELX foo-0x4 ```
The test introduced in llvm#136660, may be failed as ld.lld command not found.
Sorry for late reply. The related cmake and LLD changes were reverted. Only a backend pass and option were added to suppress APX features for relocation. Thanks. |
Previous PRs for disabling APX for relocation: llvm#136660 llvm#137794 llvm#138500 llvm#139285
Suppress EGPR/NDD instructions for relocations to avoid APX relocation types emitted. This is to keep backward compatibility with old version of linkers without APX support. The use case is to try APX features with LLVM + old built-in linker on RHEL9 OS which is expected to be EOL in 2032.
If there are APX relocation types, the old version of linkers would raise "unsupported relocation type" error. Example: