[llvm] bd6ed29 - [X86] Do not use movq in -mcmodel=kernel on an out of range abs global (#163323)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 15 11:23:38 PDT 2025
Author: PiJoules
Date: 2025-10-15T18:23:33Z
New Revision: bd6ed29f342ef273ead8f4d57a0cd4e95e0a6354
URL: https://github.com/llvm/llvm-project/commit/bd6ed29f342ef273ead8f4d57a0cd4e95e0a6354
DIFF: https://github.com/llvm/llvm-project/commit/bd6ed29f342ef273ead8f4d57a0cd4e95e0a6354.diff
LOG: [X86] Do not use movq in -mcmodel=kernel on an out of range abs global (#163323)
CFI can lead to some `relocation R_X86_64_32S out of range` errors when
using thinlto. We have an instance of an `inline_bits` alias with a
value of 0x8000008000000001 which cannot fit into a signed 32-bit reloc
hence the error. This reloc is used because the instruction for reading
the alias is `movq` which uses a signed 32-bit immediate. The proper
instruction to use in this instance is `movabs` for the full 64-bit
reloc.
Under the kernel model, a signed 32-bit immediate was always used but if
the target is a global with `absolue_symbol` we should reject the
MOV64ri32. The pattern matching logic will eventually lead to a match for
MOV64ri which emits the `movabs`.
Added:
llvm/test/CodeGen/X86/absolute-symbol-kernel-code-model.ll
Modified:
llvm/lib/Target/X86/X86InstrCompiler.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 0fd44b74fd449..ec31675731b79 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1256,8 +1256,17 @@ def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
(MOV64ri32 tconstpool :$dst)>, Requires<[KernelCode]>;
def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
(MOV64ri32 tjumptable :$dst)>, Requires<[KernelCode]>;
-def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
- (MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>;
+
+// If the globaladdr is an absolute_symbol, don't bother using the sign extending
+// instruction since there's no benefit to using it with absolute symbols.
+def globalAddrNoAbsSym : PatLeaf<(tglobaladdr:$dst), [{
+ auto *GA = cast<GlobalAddressSDNode>(N);
+ return !GA->getGlobal()->getAbsoluteSymbolRange();
+}]>;
+def : Pat<(i64 (X86Wrapper globalAddrNoAbsSym:$dst)),
+ (MOV64ri32 tglobaladdr:$dst)>,
+ Requires<[KernelCode]>;
+
def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
(MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>;
def : Pat<(i64 (X86Wrapper mcsym:$dst)),
diff --git a/llvm/test/CodeGen/X86/absolute-symbol-kernel-code-model.ll b/llvm/test/CodeGen/X86/absolute-symbol-kernel-code-model.ll
new file mode 100644
index 0000000000000..ce7024dcc438b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/absolute-symbol-kernel-code-model.ll
@@ -0,0 +1,34 @@
+; RUN: llc --code-model=kernel < %s -asm-verbose=0 | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK-LABEL: func_no_abs_sym
+define i64 @func_no_abs_sym() nounwind {
+ ; CHECK: movq $no_abs_sym, %rax
+ %1 = ptrtoint ptr @no_abs_sym to i64
+ ret i64 %1
+}
+
+; CHECK-LABEL: func_abs_sym
+define i64 @func_abs_sym() nounwind {
+ ; CHECK: movabsq $abs_sym, %rax
+ %1 = ptrtoint ptr @abs_sym to i64
+ ret i64 %1
+}
+
+; CHECK-LABEL: func_abs_sym_in_range
+define i64 @func_abs_sym_in_range() nounwind {
+ ;; The absolute_symbol range fits in 32 bits but we still use movabs
+ ;; since there's no benefit to using the sign extending instruction
+ ;; with absolute symbols.
+ ; CHECK: movabsq $abs_sym_in_range, %rax
+ %1 = ptrtoint ptr @abs_sym_in_range to i64
+ ret i64 %1
+}
+
+ at no_abs_sym = external hidden global [0 x i8]
+ at abs_sym = external hidden global [0 x i8], !absolute_symbol !0
+ at abs_sym_in_range = external hidden global [0 x i8], !absolute_symbol !1
+
+!0 = !{i64 -1, i64 -1} ;; Full range
+!1 = !{i64 -2147483648, i64 2147483648} ;; In range
More information about the llvm-commits
mailing list