Index: lib/Target/X86/X86ISelLowering.h =================================================================== --- lib/Target/X86/X86ISelLowering.h +++ lib/Target/X86/X86ISelLowering.h @@ -770,6 +770,11 @@ return !X86ScalarSSEf64 || VT == MVT::f80; } + /// Return true if we believe it is correct and profitable to reduce the + /// load node to a smaller type. + bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, + EVT NewVT) const override; + const X86Subtarget* getSubtarget() const { return Subtarget; } Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -3862,6 +3862,32 @@ return false; } +bool X86TargetLowering::shouldReduceLoadWidth(SDNode *Load, + ISD::LoadExtType ExtTy, + EVT NewVT) const { + // The linker may attempt to transition a relocation from the initial-exec to + // the local-exec model as an optimization; this optimization is possible when + // the DSO contains both the relocation and the symbol. + // + // Notionally, this is equivalent to taking: + // 'movq symbol@gottpoff(%rip), %register' + // and transforming it into: + // 'movq $symbol, %register' + // + // Similarly, the following: + // 'addq symbol@gottpoff(%rip), %register' + // is also equivalent to: + // 'leaq symbol(%register), %register' + // + // However, bfd ld will error fatally if we shrink the load from a 'movq' to a + // 'movl'. Work around this quirk by refusing to shrink such loads. + SDValue BasePtr = cast(Load)->getBasePtr(); + if (BasePtr.getOpcode() == X86ISD::WrapperRIP) + if (const auto *GA = dyn_cast(BasePtr.getOperand(0))) + return GA->getTargetFlags() != X86II::MO_GOTTPOFF; + return true; +} + /// \brief Returns true if it is beneficial to convert a load of a constant /// to just the constant itself. bool X86TargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm, Index: test/CodeGen/X86/tls-models.ll =================================================================== --- test/CodeGen/X86/tls-models.ll +++ test/CodeGen/X86/tls-models.ll @@ -128,6 +128,14 @@ ; DARWIN: _internal_ie@TLVP } +define i32 @PR22083() { +entry: + ret i32 ptrtoint (i32* @external_ie to i32) + ; X64-LABEL: PR22083: + ; X64: movq external_ie@GOTTPOFF(%rip), %rax + ; X64_PIC-LABEL: PR22083: + ; X64_PIC: movq external_ie@GOTTPOFF(%rip), %rax +} ; ----- localexec specified -----