[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`.
This commit is contained in:
parent
1673501fe5
commit
bd6ed29f34
@ -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)),
|
||||
|
||||
34
llvm/test/CodeGen/X86/absolute-symbol-kernel-code-model.ll
Normal file
34
llvm/test/CodeGen/X86/absolute-symbol-kernel-code-model.ll
Normal file
@ -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
|
||||
}
|
||||
|
||||
@no_abs_sym = external hidden global [0 x i8]
|
||||
@abs_sym = external hidden global [0 x i8], !absolute_symbol !0
|
||||
@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
|
||||
Loading…
x
Reference in New Issue
Block a user