Index: llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp @@ -911,6 +911,16 @@ 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; Index: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3918,10 +3918,7 @@ 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 @@ 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 @@ 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; } Index: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td @@ -396,6 +396,15 @@ [(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 Index: llvm/trunk/test/CodeGen/AArch64/arm64-tls-execs.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/arm64-tls-execs.ll +++ llvm/trunk/test/CodeGen/AArch64/arm64-tls-execs.ll @@ -40,11 +40,10 @@ ; 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 } Index: llvm/trunk/test/CodeGen/AArch64/win-tls.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/win-tls.ll +++ llvm/trunk/test/CodeGen/AArch64/win-tls.ll @@ -35,10 +35,7 @@ ; 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 @@ ; 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{{\]}}