mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-18 21:24:32 -04:00
[AArch64] Fold adds with tprel_lo12_nc and secrel_lo12 into a following ldr/str
Differential Revision: https://reviews.llvm.org/D44355 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327316 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -911,6 +911,16 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
case AArch64::ADDlowTLS:
|
||||
// Produce a plain ADD
|
||||
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADDXri))
|
||||
.add(MI.getOperand(0))
|
||||
.add(MI.getOperand(1))
|
||||
.add(MI.getOperand(2))
|
||||
.addImm(0);
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
|
||||
case AArch64::MOVbaseTLS: {
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
auto SysReg = AArch64SysReg::TPIDR_EL0;
|
||||
|
||||
@@ -3918,10 +3918,7 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SDValue Op,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32)),
|
||||
0);
|
||||
SDValue TPWithOff =
|
||||
SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPWithOff_lo,
|
||||
LoVar,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32)),
|
||||
0);
|
||||
DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, TPWithOff_lo, LoVar);
|
||||
return TPWithOff;
|
||||
} else if (Model == TLSModel::InitialExec) {
|
||||
TPOff = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, AArch64II::MO_TLS);
|
||||
@@ -3958,9 +3955,7 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SDValue Op,
|
||||
TPOff = SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPOff, HiVar,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32)),
|
||||
0);
|
||||
TPOff = SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPOff, LoVar,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32)),
|
||||
0);
|
||||
TPOff = DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, TPOff, LoVar);
|
||||
} else if (Model == TLSModel::GeneralDynamic) {
|
||||
// The call needs a relocation too for linker relaxation. It doesn't make
|
||||
// sense to call it MO_PAGE or MO_PAGEOFF though so we need another copy of
|
||||
@@ -4031,9 +4026,7 @@ AArch64TargetLowering::LowerWindowsGlobalTLSAddress(SDValue Op,
|
||||
SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TLS, TGAHi,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32)),
|
||||
0);
|
||||
Addr = SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, Addr, TGALo,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32)),
|
||||
0);
|
||||
Addr = DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, Addr, TGALo);
|
||||
return Addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -396,6 +396,15 @@ def MOVaddrEXT
|
||||
[(set GPR64:$dst, (AArch64addlow (AArch64adrp texternalsym:$hi),
|
||||
texternalsym:$low))]>,
|
||||
Sched<[WriteAdrAdr]>;
|
||||
// Normally AArch64addlow either gets folded into a following ldr/str,
|
||||
// or together with an adrp into MOVaddr above. For cases with TLS, it
|
||||
// might appear without either of them, so allow lowering it into a plain
|
||||
// add.
|
||||
def ADDlowTLS
|
||||
: Pseudo<(outs GPR64:$dst), (ins GPR64:$src, i64imm:$low),
|
||||
[(set GPR64:$dst, (AArch64addlow GPR64:$src,
|
||||
tglobaltlsaddr:$low))]>,
|
||||
Sched<[WriteAdr]>;
|
||||
|
||||
} // isReMaterializable, isCodeGenOnly
|
||||
|
||||
|
||||
@@ -40,11 +40,10 @@ define i32 @test_local_exec() {
|
||||
|
||||
; CHECK: mrs x[[R1:[0-9]+]], TPIDR_EL0
|
||||
; CHECK: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var
|
||||
; CHECK: add x[[R3:[0-9]+]], x[[R2]], :tprel_lo12_nc:local_exec_var
|
||||
; CHECK: ldr w0, [x[[R3]]]
|
||||
; CHECK: ldr w0, [x[[R2]], :tprel_lo12_nc:local_exec_var]
|
||||
|
||||
; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
|
||||
; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
|
||||
; CHECK-RELOC: R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,7 @@ define i64 @getVar64() {
|
||||
|
||||
; CHECK: ldr [[TLS:x[0-9]+]], {{\[}}[[TLS_POINTER]], x[[TLS_INDEX]], lsl #3]
|
||||
; CHECK: add [[TLS]], [[TLS]], :secrel_hi12:tlsVar
|
||||
; This add+ldr could also be folded into a single ldr with a :secrel_lo12:
|
||||
; offset.
|
||||
; CHECK: add [[TLS]], [[TLS]], :secrel_lo12:tlsVar
|
||||
; CHECK: ldr w0, {{\[}}[[TLS]]{{\]}}
|
||||
; CHECK: ldr w0, {{\[}}[[TLS]], :secrel_lo12:tlsVar{{\]}}
|
||||
|
||||
; CHECK-LABEL: getPtr
|
||||
; CHECK: adrp [[TLS_INDEX_ADDR:x[0-9]+]], _tls_index
|
||||
@@ -56,17 +53,12 @@ define i64 @getVar64() {
|
||||
|
||||
; CHECK: ldr [[TLS:x[0-9]+]], {{\[}}[[TLS_POINTER]], x[[TLS_INDEX]], lsl #3]
|
||||
; CHECK: add [[TLS]], [[TLS]], :secrel_hi12:tlsVar
|
||||
; This add+ldr could also be folded into a single ldr with a :secrel_lo12:
|
||||
; offset.
|
||||
; CHECK: add [[TLS]], [[TLS]], :secrel_lo12:tlsVar
|
||||
; CHECK: str w0, {{\[}}[[TLS]]{{\]}}
|
||||
; CHECK: str w0, {{\[}}[[TLS]], :secrel_lo12:tlsVar{{\]}}
|
||||
|
||||
; CHECK-LABEL: getVar8
|
||||
; CHECK: add [[TLS:x[0-9]+]], [[TLS]], :secrel_hi12:tlsVar8
|
||||
; CHECK: add [[TLS]], [[TLS]], :secrel_lo12:tlsVar8
|
||||
; CHECK: ldrb w0, {{\[}}[[TLS]]{{\]}}
|
||||
; CHECK: ldrb w0, {{\[}}[[TLS]], :secrel_lo12:tlsVar8{{\]}}
|
||||
|
||||
; CHECK-LABEL: getVar64
|
||||
; CHECK: add [[TLS:x[0-9]+]], [[TLS]], :secrel_hi12:tlsVar64
|
||||
; CHECK: add [[TLS]], [[TLS]], :secrel_lo12:tlsVar64
|
||||
; CHECK: ldr x0, {{\[}}[[TLS]]{{\]}}
|
||||
; CHECK: ldr x0, {{\[}}[[TLS]], :secrel_lo12:tlsVar64{{\]}}
|
||||
|
||||
Reference in New Issue
Block a user