mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Pull in r354756 from upstream llvm trunk (by Craig Topper):
[X86] Fix tls variable lowering issue with large code model
Summary:
The problem here is the lowering for tls variable. Below is the DAG
for the code. SelectionDAG has 11 nodes:
t0: ch = EntryToken
t8: i64,ch = load<(load 8 from `i8 addrspace(257)* null`,
addrspace 257)> t0, Constant:i64<0>, undef:i64
t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32*
@x> 0 [TF=10]
t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64
t12: i64 = add t8, t11
t4: i32,ch = load<(dereferenceable load 4 from @x)> t0, t12,
undef:i64
t6: ch = CopyToReg t0, Register:i32 %0, t4
And when mcmodel is large, below instruction can NOT be folded.
t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @x> 0
[TF=10]
t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64
So "t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64" is
lowered to " Morphed node: t11: i64,ch = MOV64rm<Mem:(load 8 from
got)> t10, TargetConstant:i8<1>, Register:i64 $noreg,
TargetConstant:i32<0>, Register:i32 $noreg, t0"
When llvm start to lower "t10: i64 = X86ISD::WrapperRIP
TargetGlobalTLSAddress:i64<i32* @x> 0 [TF=10]", it fails.
The patch is to fold the load and X86ISD::WrapperRIP.
Fixes PR26906
Patch by LuoYuanke
Reviewers: craig.topper, rnk, annita.zhang, wxiao3
Reviewed By: rnk
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58336
This should fix "fatal error: error in backend: Cannot select" messages
when compiling <ctype.h> functions using -mcmodel=large.
Reported by: phk
PR: 233143
MFC after: 3 days
This commit is contained in:
parent
484160a9cf
commit
4f560b016f
1 changed files with 13 additions and 5 deletions
|
|
@ -989,15 +989,23 @@ bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM) {
|
|||
if (AM.hasSymbolicDisplacement())
|
||||
return true;
|
||||
|
||||
bool IsRIPRelTLS = false;
|
||||
bool IsRIPRel = N.getOpcode() == X86ISD::WrapperRIP;
|
||||
if (IsRIPRel) {
|
||||
SDValue Val = N.getOperand(0);
|
||||
if (Val.getOpcode() == ISD::TargetGlobalTLSAddress)
|
||||
IsRIPRelTLS = true;
|
||||
}
|
||||
|
||||
// We can't use an addressing mode in the 64-bit large code model. In the
|
||||
// medium code model, we use can use an mode when RIP wrappers are present.
|
||||
// That signifies access to globals that are known to be "near", such as the
|
||||
// GOT itself.
|
||||
// We can't use an addressing mode in the 64-bit large code model.
|
||||
// Global TLS addressing is an exception. In the medium code model,
|
||||
// we use can use a mode when RIP wrappers are present.
|
||||
// That signifies access to globals that are known to be "near",
|
||||
// such as the GOT itself.
|
||||
CodeModel::Model M = TM.getCodeModel();
|
||||
if (Subtarget->is64Bit() &&
|
||||
(M == CodeModel::Large || (M == CodeModel::Medium && !IsRIPRel)))
|
||||
((M == CodeModel::Large && !IsRIPRelTLS) ||
|
||||
(M == CodeModel::Medium && !IsRIPRel)))
|
||||
return true;
|
||||
|
||||
// Base and index reg must be 0 in order to use %rip as base.
|
||||
|
|
|
|||
Loading…
Reference in a new issue