[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:
Martin Storsjo
2018-03-12 18:47:43 +00:00
parent c4689888d6
commit e9c83048fb
5 changed files with 28 additions and 25 deletions
@@ -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;
+3 -10
View File
@@ -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;
}
+9
View File
@@ -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
+2 -3
View File
@@ -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
}
+4 -12
View File
@@ -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{{\]}}